From patchwork Thu Jun 25 09:39:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 6673021 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E723DC05AC for ; Thu, 25 Jun 2015 09:40:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E4DFB20692 for ; Thu, 25 Jun 2015 09:40:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 83FCD20680 for ; Thu, 25 Jun 2015 09:40:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751213AbbFYJkS (ORCPT ); Thu, 25 Jun 2015 05:40:18 -0400 Received: from michel.telenet-ops.be ([195.130.137.88]:57265 "EHLO michel.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751414AbbFYJkP (ORCPT ); Thu, 25 Jun 2015 05:40:15 -0400 Received: from ayla.of.borg ([84.193.93.87]) by michel.telenet-ops.be with bizsmtp id kZgC1q01F1t5w8s06ZgD5V; Thu, 25 Jun 2015 11:40:13 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1Z83dk-0002TT-La; Thu, 25 Jun 2015 11:40:12 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1Z83dn-0002d9-7j; Thu, 25 Jun 2015 11:40:15 +0200 From: Geert Uytterhoeven To: Laurent Pinchart , Linus Walleij Cc: Pantelis Antoniou , Grant Likely , Rob Herring , linux-sh@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH] pinctrl: sh-pfc: Convert to platform_get_*() Date: Thu, 25 Jun 2015 11:39:53 +0200 Message-Id: <1435225193-10078-1-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, 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 If the pin function controller (which can be a GPIO controller) is instantiated before the interrupt controllers, due to the ordering in the DTS, the irq domains for the interrupt controllers referenced by its "interrupts-extended" property cannot be found yet: irq: no irq domain found for /interrupt-controller@e61c0000 ! As the sh-pfc driver accesses the platform device's resources directly, it cannot find the (optional) IRQ resources, and thinks no interrupts are available. This may lead to failures later, when GPIOs are used as interupts: gpio-keys keyboard: Unable to claim irq 0; error -22 gpio-keys: probe of keyboard failed with error -22 To fix this, add support for deferred probing to sh-pfc, by converting the driver from direct platform device resource access to using the platform_get_resource() and platform_get_irq() helpers. Note that while this fixes the root cause worked around by commit e4ba0a9bddff3ba5 ("ARM: shmobile: r8a73a4: Move pfc node to work around probe ordering bug"), I strongly recommend against reverting the workaround now, as this would lead to lots of probe deferrals in drivers relying on pinctrl. This may be reconsidered once the DT code starts taking into account phandle dependencies during device instantation. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart --- This patch is against next-20150625 "[PATCH] [RFC] OF: probe order dependency aware of_platform_populate" (https://www.marc.info/?l=devicetree&m=141873189825553&w=1) is a first step, but it doesn't postpone the instantiation of the pfc. Tested: - r8a73a4/ape6evm (with pfc before/after irqc in DT), - sh73a0/kzm9g (with pfc before/after intc-irqpin in DT). Regression-tested: - r8a7791/koelsch (pfc doesn't have interrupts), - r8a7740/armadillo (pfc after intc-irqpin in DT), - r8a7740/armadillo-legacy (gpio-keys wired to pfc), - sh73a0/kzm9g-legacy (gpio-keys not wired to pfc). Compile-tested: - sh/se7724_defconfig. --- drivers/pinctrl/sh-pfc/core.c | 46 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 865d235612c5200a..9796238959047508 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -29,24 +29,25 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, struct platform_device *pdev) { - unsigned int num_windows = 0; - unsigned int num_irqs = 0; + unsigned int num_windows, num_irqs; struct sh_pfc_window *windows; unsigned int *irqs = NULL; struct resource *res; unsigned int i; + int irq; /* Count the MEM and IRQ resources. */ - for (i = 0; i < pdev->num_resources; ++i) { - switch (resource_type(&pdev->resource[i])) { - case IORESOURCE_MEM: - num_windows++; + for (num_windows = 0;; num_windows++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, num_windows); + if (!res) break; - - case IORESOURCE_IRQ: - num_irqs++; + } + for (num_irqs = 0;; num_irqs++) { + irq = platform_get_irq(pdev, num_irqs); + if (irq == -EPROBE_DEFER) + return irq; + if (irq < 0) break; - } } if (num_windows == 0) @@ -72,22 +73,17 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, } /* Fill them. */ - for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) { - switch (resource_type(res)) { - case IORESOURCE_MEM: - windows->phys = res->start; - windows->size = resource_size(res); - windows->virt = devm_ioremap_resource(pfc->dev, res); - if (IS_ERR(windows->virt)) - return -ENOMEM; - windows++; - break; - - case IORESOURCE_IRQ: - *irqs++ = res->start; - break; - } + for (i = 0; i < num_windows; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + windows->phys = res->start; + windows->size = resource_size(res); + windows->virt = devm_ioremap_resource(pfc->dev, res); + if (IS_ERR(windows->virt)) + return -ENOMEM; + windows++; } + for (i = 0; i < num_irqs; i++) + *irqs++ = platform_get_irq(pdev, i); return 0; }