From patchwork Mon Dec 15 09:57:50 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 5491851 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 69F94BEEA8 for ; Mon, 15 Dec 2014 10:00:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5EEDA20A01 for ; Mon, 15 Dec 2014 10:00:31 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2C722209FD for ; Mon, 15 Dec 2014 10:00:30 +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 1Y0SQ1-0000GE-BL; Mon, 15 Dec 2014 09:58:21 +0000 Received: from eusmtp01.atmel.com ([212.144.249.243]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y0SPx-0000B8-Qh for linux-arm-kernel@lists.infradead.org; Mon, 15 Dec 2014 09:58:18 +0000 Received: from ibiza.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.31) with Microsoft SMTP Server id 14.2.347.0; Mon, 15 Dec 2014 10:57:52 +0100 From: Ludovic Desroches To: , , Subject: [PATCH RFC] pinctrl: at91 Date: Mon, 15 Dec 2014 10:57:50 +0100 Message-ID: <1418637470-5839-1-git-send-email-ludovic.desroches@atmel.com> X-Mailer: git-send-email 2.0.3 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141215_015818_258905_68AFF104 X-CRM114-Status: GOOD ( 17.60 ) X-Spam-Score: -0.0 (/) Cc: plagnioj@jcrosoft.com, Ludovic Desroches , nicolas.ferre@atmel.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 Signed-off-by: Ludovic Desroches Acked-by: Nicolas Ferre --- Hi Linus, I have reworked my patch (of course it will be split for submission) trying to follow your advices. I have replaced pinctrl_add_gpio_range() with of_gpiochip_add(). I'll do more tests but it seems to work. Maybe I've missed something but I still need to fix the case when there is a gpio controller not used. A lot of things rely on the gpio controller id (taken from the alias): index for gpio_chips array, pin muxing, naming, etc. I am not sure I can't get rid of this constraint. Regards Ludovic arch/arm/boot/dts/sama5d4.dtsi | 19 ++++++++++++++++++- drivers/pinctrl/pinctrl-at91.c | 42 +++++++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 1b0f30c..c1c01a3 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -62,6 +62,7 @@ gpio0 = &pioA; gpio1 = &pioB; gpio2 = &pioC; + gpio3 = &pioD; gpio4 = &pioE; tcb0 = &tcb0; tcb1 = &tcb1; @@ -1063,7 +1064,7 @@ }; - pinctrl@fc06a000 { + pinctrl: pinctrl@fc06a000 { #address-cells = <1>; #size-cells = <1>; compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; @@ -1084,6 +1085,7 @@ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 1>; #gpio-cells = <2>; gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioA_clk>; @@ -1095,6 +1097,7 @@ interrupts = <24 IRQ_TYPE_LEVEL_HIGH 1>; #gpio-cells = <2>; gpio-controller; + gpio-ranges = <&pinctrl 0 32 32>; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioB_clk>; @@ -1106,17 +1109,31 @@ interrupts = <25 IRQ_TYPE_LEVEL_HIGH 1>; #gpio-cells = <2>; gpio-controller; + gpio-ranges = <&pinctrl 0 64 32>; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioC_clk>; }; + pioD: gpio@fc068000 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfc068000 0x100>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&pioD_clk>; + status = "disabled"; + }; + pioE: gpio@fc06d000 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfc06d000 0x100>; interrupts = <26 IRQ_TYPE_LEVEL_HIGH 1>; #gpio-cells = <2>; gpio-controller; + gpio-ranges = <&pinctrl 0 128 32>; interrupt-controller; #interrupt-cells = <2>; clocks = <&pioE_clk>; diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index dfd021e..f5d4aea 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,6 @@ struct at91_pinctrl_mux_ops; struct at91_gpio_chip { struct gpio_chip chip; - struct pinctrl_gpio_range range; struct at91_gpio_chip *next; /* Bank sharing same clock */ int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ int pioc_virq; /* PIO bank Linux virtual interrupt */ @@ -178,6 +178,7 @@ struct at91_pinctrl { struct pinctrl_dev *pctl; int nbanks; + int nactive_banks; uint32_t *mux_mask; int nmux; @@ -982,6 +983,8 @@ static void at91_pinctrl_child_count(struct at91_pinctrl *info, for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) { info->nbanks++; + if (of_device_is_available(child)) + info->nactive_banks; } else { info->nfunctions++; info->ngroups += of_get_child_count(child); @@ -1145,8 +1148,12 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, dev_dbg(&pdev->dev, "mux-mask\n"); tmp = info->mux_mask; for (i = 0; i < info->nbanks; i++) { + if (!gpio_chips[i]) { + tmp += info->nmux; + continue; + } for (j = 0; j < info->nmux; j++, tmp++) { - dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); + dev_dbg(&pdev->dev, "pio%c:periphal %c\t0x%x\n", 'A' + i, 'A' + j, tmp[0]); } } @@ -1185,7 +1192,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) { struct at91_pinctrl *info; struct pinctrl_pin_desc *pdesc; - int ret, i, j, k; + int ret, i, j, k, ngpio_chips_enabled = 0; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) @@ -1201,11 +1208,15 @@ static int at91_pinctrl_probe(struct platform_device *pdev) * need this to proceed. */ for (i = 0; i < info->nbanks; i++) { - if (!gpio_chips[i]) { - dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); - devm_kfree(&pdev->dev, info); - return -EPROBE_DEFER; - } + if (gpio_chips[i]) + ngpio_chips_enabled++; + } + if (ngpio_chips_enabled < info->nactive_banks) { + dev_warn(&pdev->dev, + "All GPIO chips are not registered yet (%d/%d)\n", + ngpio_chips_enabled, info->nactive_banks); + devm_kfree(&pdev->dev, info); + return -EPROBE_DEFER; } at91_pinctrl_desc.name = dev_name(&pdev->dev); @@ -1233,9 +1244,9 @@ static int at91_pinctrl_probe(struct platform_device *pdev) goto err; } - /* We will handle a range of GPIO pins */ for (i = 0; i < info->nbanks; i++) - pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); + if (gpio_chips[i]) + of_gpiochip_add(&gpio_chips[i]->chip); dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); @@ -1682,6 +1693,8 @@ static void at91_gpio_probe_fixup(void) for (i = 0; i < gpio_banks; i++) { at91_gpio = gpio_chips[i]; + if (!at91_gpio) + continue; /* * GPIO controller are grouped on some SoC: @@ -1705,7 +1718,6 @@ static int at91_gpio_probe(struct platform_device *pdev) struct resource *res; struct at91_gpio_chip *at91_chip = NULL; struct gpio_chip *chip; - struct pinctrl_gpio_range *range; int ret = 0; int irq, i; int alias_idx = of_alias_get_id(np, "gpio"); @@ -1790,14 +1802,6 @@ static int at91_gpio_probe(struct platform_device *pdev) chip->names = (const char *const *)names; - range = &at91_chip->range; - range->name = chip->label; - range->id = alias_idx; - range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK; - - range->npins = chip->ngpio; - range->gc = chip; - ret = gpiochip_add(chip); if (ret) goto gpiochip_add_err;