From patchwork Wed Sep 18 13:24:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 2906911 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D4EC89F1E3 for ; Wed, 18 Sep 2013 13:28:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4FF8220399 for ; Wed, 18 Sep 2013 13:28:57 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4784F20347 for ; Wed, 18 Sep 2013 13:28:55 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHnF-0005jF-No; Wed, 18 Sep 2013 13:27:47 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHmy-0002W2-8r; Wed, 18 Sep 2013 13:27:28 +0000 Received: from mail-bk0-f50.google.com ([209.85.214.50]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHmV-0002OH-3I for linux-arm-kernel@lists.infradead.org; Wed, 18 Sep 2013 13:27:02 +0000 Received: by mail-bk0-f50.google.com with SMTP id mz11so2793221bkb.37 for ; Wed, 18 Sep 2013 06:26:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R4f67gCYOvfC6lcEEPkm6wn1zDg31RWFqrnSf/EPnzU=; b=bD0Whl9YlAO2nt8xAkYKCooMADHwAuAiOZpa05HkV/i1a75DxXQ7/K0al0Q3L4d8I/ fbTsZSKs3hZ7pNjy88IsQlKQkJ4CZ7Bd/gj5tun/UcHU3QEwtL3XiNDCSQuXJEUTDVfS NlcZoAwdimf5+8uD4DRFMT6Fxbt2B45OU2Y7f9j5lhjhu4buVPQWeNsoi0iV/FSZvszb kGC0VCaCOe5pRRxWKBTMRLnjVxev6ubDJiMGZUorGjrA+8bMPsYguou1lGtpf9I8GoS5 eV+7yQnOFj2Jw6y99Lst01hVl/i+9yQiy8BvPxAuApxDEae1ZwVJoGNpsryCg/I56b5I mlow== X-Received: by 10.204.229.76 with SMTP id jh12mr119790bkb.44.1379510782466; Wed, 18 Sep 2013 06:26:22 -0700 (PDT) Received: from localhost (port-55509.pppoe.wtnet.de. [46.59.217.135]) by mx.google.com with ESMTPSA id qe6sm902211bkb.5.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 18 Sep 2013 06:26:21 -0700 (PDT) From: Thierry Reding To: Rob Herring , Grant Likely , Greg Kroah-Hartman , Thomas Gleixner Subject: [PATCH v2 04/10] irqdomain: Return errors from irq_create_of_mapping() Date: Wed, 18 Sep 2013 15:24:46 +0200 Message-Id: <1379510692-32435-5-git-send-email-treding@nvidia.com> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379510692-32435-1-git-send-email-treding@nvidia.com> References: <1379510692-32435-1-git-send-email-treding@nvidia.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130918_092659_456428_1B79057A X-CRM114-Status: GOOD ( 20.95 ) X-Spam-Score: 0.9 (/) Cc: linux-mips@linux-mips.org, Russell King , devicetree@vger.kernel.org, Benjamin Herrenschmidt , linux-kernel@vger.kernel.org, Ralf Baechle , sparclinux@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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=-1.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, KHOP_BIG_TO_CC, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=no 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 Instead of returning 0 for all errors, allow the precise error code to be propagated. This will be used in subsequent patches to allow further propagation of error codes. The interrupt number corresponding to the new mapping is returned in an output parameter so that the return value is reserved to signal success (== 0) or failure (< 0). Signed-off-by: Thierry Reding Acked-by: Ralf Baechle Acked-by: Rob Herring --- Changes in v2: - convert existing callers instead of using compatible wrapper arch/arm/mach-integrator/pci_v3.c | 8 ++++++-- arch/microblaze/pci/pci-common.c | 6 ++++-- arch/mips/pci/fixup-lantiq.c | 12 +++++++---- arch/mips/pci/pci-rt3883.c | 9 +++++---- arch/powerpc/kernel/pci-common.c | 7 +++++-- arch/powerpc/platforms/cell/celleb_scc_sio.c | 8 +++++--- arch/powerpc/platforms/cell/spu_manage.c | 6 +++--- arch/powerpc/platforms/fsl_uli1575.c | 7 +++---- arch/powerpc/platforms/pseries/event_sources.c | 12 ++++++----- arch/x86/kernel/devicetree.c | 11 +++++----- drivers/pci/host/pci-mvebu.c | 9 +++++++-- include/linux/of_irq.h | 6 +++--- kernel/irq/irqdomain.c | 28 ++++++++++++++++---------- 13 files changed, 78 insertions(+), 51 deletions(-) diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index bef1005..aa0f867 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -847,8 +847,12 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin) return 0; } - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size, &virq); + if (ret) + return 0; + + return virq; } static int __init pci_v3_dtprobe(struct platform_device *pdev, diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 1b93bf0..80b6e0f 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -246,8 +246,10 @@ int pci_read_irq_line(struct pci_dev *pci_dev) oirq.size, oirq.specifier[0], oirq.specifier[1], of_node_full_name(oirq.controller)); - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size, &virq); + if (ret) + virq = 0; } if (!virq) { pr_debug(" Failed to map !\n"); diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c index 6c829df..dfe7bf1 100644 --- a/arch/mips/pci/fixup-lantiq.c +++ b/arch/mips/pci/fixup-lantiq.c @@ -26,15 +26,19 @@ int pcibios_plat_dev_init(struct pci_dev *dev) int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_irq dev_irq; - int irq; + unsigned int irq; + int err; if (of_irq_map_pci(dev, &dev_irq)) { dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n", slot, pin); return 0; } - irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier, - dev_irq.size); - dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq); + err = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier, + dev_irq.size, &irq); + if (err) + return 0; + + dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%u\n", slot, pin, irq); return irq; } diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 95c9d41..79b49b5 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -584,8 +584,8 @@ err_put_intc_node: int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_irq dev_irq; + unsigned int irq = 0; int err; - int irq; err = of_irq_map_pci(dev, &dev_irq); if (err) { @@ -594,11 +594,12 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return 0; } - irq = irq_create_of_mapping(dev_irq.controller, + err = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier, - dev_irq.size); + dev_irq.size, + &irq); - if (irq == 0) + if (err) pr_crit("pci %s: no irq found for pin %u\n", pci_name((struct pci_dev *) dev), pin); else diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 905a24b..ae71b14 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -230,6 +230,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) { struct of_irq oirq; unsigned int virq; + int ret; pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); @@ -266,8 +267,10 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) oirq.size, oirq.specifier[0], oirq.specifier[1], of_node_full_name(oirq.controller)); - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size, &virq); + if (ret) + virq = NO_IRQ; } if(virq == NO_IRQ) { pr_debug(" Failed to map !\n"); diff --git a/arch/powerpc/platforms/cell/celleb_scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c index 9c339ec..94b771e 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_sio.c +++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c @@ -43,7 +43,7 @@ static int __init txx9_serial_init(void) { extern int early_serial_txx9_setup(struct uart_port *port); struct device_node *node; - int i; + int i, err; struct uart_port req; struct of_irq irq; struct resource res; @@ -66,8 +66,10 @@ static int __init txx9_serial_init(void) #ifdef CONFIG_SERIAL_TXX9_CONSOLE req.membase = ioremap(req.mapbase, 0x24); #endif - req.irq = irq_create_of_mapping(irq.controller, - irq.specifier, irq.size); + err = irq_create_of_mapping(irq.controller, + irq.specifier, irq.size, &req.irq); + if (err) + req.irq = 0; req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/; req.uartclk = 83300000; diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 2bb6977..b78c7a4 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -190,9 +190,9 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) ret = -EINVAL; pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], oirq.controller->full_name); - spu->irqs[i] = irq_create_of_mapping(oirq.controller, - oirq.specifier, oirq.size); - if (spu->irqs[i] == NO_IRQ) { + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size, &spu->irqs[i]); + if (ret) { pr_debug("spu_new: failed to map it !\n"); goto err; } diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index 92ac9b5..575b215 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -322,7 +322,7 @@ static void hpcd_final_uli5288(struct pci_dev *dev) struct pci_controller *hose = pci_bus_to_host(dev->bus); struct device_node *hosenode = hose ? hose->dn : NULL; struct of_irq oirq; - int virq, pin = 2; + int pin = 2; u32 laddr[3]; if (!machine_is(mpc86xx_hpcd)) @@ -334,9 +334,8 @@ static void hpcd_final_uli5288(struct pci_dev *dev) laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8); laddr[1] = laddr[2] = 0; of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - dev->irq = virq; + irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size, + &dev->irq); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575); diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index 2605c31..4367fdd 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -24,7 +24,7 @@ void request_event_sources_irqs(struct device_node *np, irq_handler_t handler, const char *name) { - int i, index, count = 0; + int i, index, err, count = 0; struct of_irq oirq; const u32 *opicprop; unsigned int opicplen; @@ -59,10 +59,12 @@ void request_event_sources_irqs(struct device_node *np, index++) { if (count > 15) break; - virqs[count] = irq_create_of_mapping(oirq.controller, - oirq.specifier, - oirq.size); - if (virqs[count] == NO_IRQ) { + + err = irq_create_of_mapping(oirq.controller, + oirq.specifier, + oirq.size, + &virqs[count]); + if (err) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 376dc78..7adede6 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -106,7 +106,6 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) static int x86_of_pci_irq_enable(struct pci_dev *dev) { struct of_irq oirq; - u32 virq; int ret; u8 pin; @@ -120,11 +119,11 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev) if (ret) return ret; - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - if (virq == 0) - return -EINVAL; - dev->irq = virq; + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size, + &dev->irq); + if (ret) + return ret; + return 0; } diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 77f8a7c..7773a17 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -656,14 +656,19 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_irq oirq; + unsigned int virq; int ret; ret = of_irq_map_pci(dev, &oirq); if (ret) return ret; - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + ret = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size, + &virq); + if (ret) + return 0; + + return virq; } static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys) diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 535cecf..138266d 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -63,9 +63,9 @@ extern int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, struct of_irq *out_irq); extern int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq); -extern unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, - unsigned int intsize); +extern int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned int *virqp); extern int of_irq_to_resource(struct device_node *dev, int index, struct resource *r); extern int of_irq_count(struct device_node *dev); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index d2a3b01..5f8401c 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -484,40 +484,46 @@ int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base, } EXPORT_SYMBOL_GPL(irq_create_strict_mappings); -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) +int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, + unsigned int intsize, unsigned int *virqp) { + unsigned int type = IRQ_TYPE_NONE; struct irq_domain *domain; irq_hw_number_t hwirq; - unsigned int type = IRQ_TYPE_NONE; unsigned int virq; + int ret; domain = controller ? irq_find_host(controller) : irq_default_domain; if (!domain) { pr_warn("no irq domain found for %s !\n", of_node_full_name(controller)); - return 0; + return -EPROBE_DEFER; } /* If domain has no translation, then we assume interrupt line */ if (domain->ops->xlate == NULL) hwirq = intspec[0]; else { - if (domain->ops->xlate(domain, controller, intspec, intsize, - &hwirq, &type)) - return 0; + ret = domain->ops->xlate(domain, controller, intspec, intsize, + &hwirq, &type); + if (ret) + return ret; } /* Create mapping */ - virq = irq_create_mapping(domain, hwirq); - if (!virq) - return virq; + ret = __irq_create_mapping(domain, hwirq, &virq); + if (ret) + return ret; /* Set type if specified and different than the current one */ if (type != IRQ_TYPE_NONE && type != irq_get_trigger_type(virq)) irq_set_irq_type(virq, type); - return virq; + + if (virqp) + *virqp = virq; + + return 0; } EXPORT_SYMBOL_GPL(irq_create_of_mapping);