From patchwork Tue Jan 19 13:11:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8061861 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2C7F89F818 for ; Tue, 19 Jan 2016 13:19:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0FE9020138 for ; Tue, 19 Jan 2016 13:19:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F0A4A20397 for ; Tue, 19 Jan 2016 13:19:01 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aLWAE-000123-TL; Tue, 19 Jan 2016 13:17:38 +0000 Received: from mail-wm0-x22b.google.com ([2a00:1450:400c:c09::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aLW4c-000388-57 for linux-arm-kernel@lists.infradead.org; Tue, 19 Jan 2016 13:11:53 +0000 Received: by mail-wm0-x22b.google.com with SMTP id n5so111234773wmn.0 for ; Tue, 19 Jan 2016 05:11:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SXmOznCp9Q+RNvgY8TfhHf4Um6OTeEzy7z084NFsmTw=; b=mhfqqhLXHE7YhAkd8BOqtoE1l73NhohQjHA0sQpgexYxT+aBDJkFWILat9nZ/MCKge rK7qrDcQBH81gdBB5p1tNa/fB9daBxkBFpqS9B2Fm8heQ8njYQKmvZThBIrJBin3uw3o b+Xc4/q4coIgVETzVyPaiyAhilLYt0XQW3RIzKNnJJ43dpkpALDekIXisWNtTwSwU2V8 hxJAHnRlabFd23sN12WsVg9c1ju4SgyG8u/suU+Q/dY9T6dKrVCdSOoDZVX7Kxu5eWxA R39MyY+O7DkCu3I+psUiaATTRLRm+rNbsXo0ZV9PizNiTzLSaUJgAe3UcNSeZl0nvUbI 87mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SXmOznCp9Q+RNvgY8TfhHf4Um6OTeEzy7z084NFsmTw=; b=R4n/Bu77eE6JpUudHryEPKjjSvB2JDnVd5NC9Q3m05lDvCvr8ktOUn3oDCazKHrb8O IZFNptja8ED5QLCwKLYVARa5zWy7zjpVu4FKx8arYrnw8Yn3HWvNIsFzAVfiv4bu8bQ9 +SACbWc1t81iYcoBpQcOvRyPkvy/FIEQ09Vxy4/xGb+npjkWjbFCv9zyBCl47jTygyTu CLnsfjMeUaDDv5iOohq9VdGlDPxJyh2h1jj3KmXhuSuco2w0EC1y/ONAtPkUEGN4Zcm9 +YMsQIYo8ASH6SUYHMNpcJCNY3bycmr8efLtFTnDOz5kiQcmSv8cXyvkRz2068OXfp/e DP9w== X-Gm-Message-State: AG10YOQ6FMK9+hovJjxQhJN8BopqqrcR8u+Gl/rRBckmK+zqYrdNaxrEe+3IIt6UU0pUuA== X-Received: by 10.28.30.210 with SMTP id e201mr20393751wme.42.1453209088475; Tue, 19 Jan 2016 05:11:28 -0800 (PST) Received: from tn-HP-4.semihalf.local ([80.82.22.190]) by smtp.gmail.com with ESMTPSA id w194sm17762623wmd.0.2016.01.19.05.11.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Jan 2016 05:11:27 -0800 (PST) From: Tomasz Nowicki To: marc.zyngier@arm.com, tglx@linutronix.de, jason@lakedaemon.net, rjw@rjwysocki.net, lorenzo.pieralisi@arm.com, robert.richter@caviumnetworks.com, shijie.huang@arm.com, guohanjun@huawei.com, Suravee.Suthikulpanit@amd.com Subject: [PATCH V3 02/10] irqchip / GICv3: Add ACPI support for GICv3+ initialization Date: Tue, 19 Jan 2016 14:11:15 +0100 Message-Id: <1453209083-3358-3-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453209083-3358-1-git-send-email-tn@semihalf.com> References: <1453209083-3358-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160119_051150_529472_A0F368EC X-CRM114-Status: GOOD ( 16.54 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: graeme.gregory@linaro.org, Catalin.Marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, hanjun.guo@linaro.org, ddaney.cavm@gmail.com, Tomasz Nowicki , mw@semihalf.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP With the refator of gic_of_init(), GICv3/4 can be initialized by gic_init_bases() with gic distributor base address and gic redistributor region(s). So get the redistributor region base addresses from MADT GIC redistributor subtable, and the distributor base address from GICD subtable to init GICv3 irqchip in ACPI way. Note: GIC redistributor base address may also be provided in GICC structures on systems supporting GICv3 and above if the GIC Redistributors are not in the always-on power domain, this patch didn't implement such feature yet. Also, ACPI ITS initialization will be added in the following patches. Signed-off-by: Tomasz Nowicki Signed-off-by: Hanjun Guo Acked-by: Marc Zyngier --- drivers/irqchip/irq-gic-v3.c | 137 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 31205c7..2cada42 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -15,10 +15,12 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include #include #include #include @@ -764,6 +766,15 @@ static int gic_irq_domain_translate(struct irq_domain *d, return 0; } + if (is_fwnode_irqchip(fwspec->fwnode)) { + if(fwspec->param_count != 2) + return -EINVAL; + + *hwirq = fwspec->param[0]; + *type = fwspec->param[1]; + return 0; + } + return -EINVAL; } @@ -951,3 +962,129 @@ out_unmap_dist: } IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init); + +#ifdef CONFIG_ACPI +static struct redist_region *redist_regs __initdata; +static u32 nr_redist_regions __initdata; + +static int __init +gic_acpi_parse_madt_redist(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_redistributor *redist = + (struct acpi_madt_generic_redistributor *)header; + void __iomem *redist_base; + static int count = 0; + + redist_base = ioremap(redist->base_address, redist->length); + if (!redist_base) { + pr_err("Couldn't map GICR region @%llx\n", redist->base_address); + return -ENOMEM; + } + + redist_regs[count].phys_base = redist->base_address; + redist_regs[count].redist_base = redist_base; + count++; + return 0; +} + +static int __init gic_acpi_match_gicr(struct acpi_subtable_header *header, + const unsigned long end) +{ + /* Subtable presence means that redist exists, that's it */ + return 0; +} + +static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header, + struct acpi_probe_entry *ape) +{ + struct acpi_madt_generic_distributor *dist; + int count; + + dist = (struct acpi_madt_generic_distributor *)header; + if (dist->version != ape->driver_data) + return false; + + /* We need to do that exercise anyway, the sooner the better */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, + gic_acpi_match_gicr, 0); + if (count <= 0) + return false; + + nr_redist_regions = count; + return true; +} + +#define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K) + +static int __init +gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end) +{ + struct acpi_madt_generic_distributor *dist; + struct fwnode_handle *domain_handle; + void __iomem *dist_base; + int i, err, count; + + /* Get distributor base address */ + dist = (struct acpi_madt_generic_distributor *)header; + dist_base = ioremap(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE); + if (!dist_base) { + pr_err("Unable to map GICD registers\n"); + return -ENOMEM; + } + + err = gic_validate_dist_version(dist_base); + if (err) { + pr_err("No distributor detected at @%p, giving up", dist_base); + goto out_dist_unmap; + } + + redist_regs = kzalloc(sizeof(*redist_regs) * nr_redist_regions, + GFP_KERNEL); + if (!redist_regs) { + err = -ENOMEM; + goto out_dist_unmap; + } + + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, + gic_acpi_parse_madt_redist, 0); + if (count <= 0) { + err = -ENODEV; + goto out_redist_unmap; + } + + domain_handle = irq_domain_alloc_fwnode(dist_base); + if (!domain_handle) { + err = -ENOMEM; + goto out_redist_unmap; + } + + err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0, + domain_handle); + if (err) + goto out_fwhandle_free; + + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle); + return 0; + +out_fwhandle_free: + irq_domain_free_fwnode(domain_handle); +out_redist_unmap: + for (i = 0; i < nr_redist_regions; i++) + if (redist_regs[i].redist_base) + iounmap(redist_regs[i].redist_base); + kfree(redist_regs); +out_dist_unmap: + iounmap(dist_base); + return err; +} +IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_V3, + gic_acpi_init); +IRQCHIP_ACPI_DECLARE(gic_v4, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_V4, + gic_acpi_init); +IRQCHIP_ACPI_DECLARE(gic_v3_or_v4, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_NONE, + gic_acpi_init); +#endif