From patchwork Mon Nov 21 19:48:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 5242 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 0DD7523E0E for ; Mon, 21 Nov 2011 19:49:03 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id 02A81A18478 for ; Mon, 21 Nov 2011 19:49:02 +0000 (UTC) Received: by mail-fx0-f52.google.com with SMTP id a26so11407044faa.11 for ; Mon, 21 Nov 2011 11:49:02 -0800 (PST) Received: by 10.152.105.226 with SMTP id gp2mr9816863lab.28.1321904942756; Mon, 21 Nov 2011 11:49:02 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.41.198 with SMTP id h6cs139920lal; Mon, 21 Nov 2011 11:49:02 -0800 (PST) Received: by 10.14.10.86 with SMTP id 62mr1052209eeu.244.1321904938290; Mon, 21 Nov 2011 11:48:58 -0800 (PST) Received: from eu1sys200aog115.obsmtp.com (eu1sys200aog115.obsmtp.com. [207.126.144.139]) by mx.google.com with SMTP id v18si2616527eej.140.2011.11.21.11.48.51 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 21 Nov 2011 11:48:58 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.139 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.139; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.139 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob115.postini.com ([207.126.147.11]) with SMTP ID DSNKTsqrIizuSxUnf+/jSq3Wd5gTDmcdH0A5@postini.com; Mon, 21 Nov 2011 19:48:58 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id D5BD555; Mon, 21 Nov 2011 19:48:47 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id BDD5268; Mon, 21 Nov 2011 19:38:27 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id E3F3F24C075; Mon, 21 Nov 2011 20:48:38 +0100 (CET) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Mon, 21 Nov 2011 20:48:48 +0100 From: Linus Walleij To: Cc: Stephen Warren , Grant Likely , Barry Song <21cnbao@gmail.com>, Shawn Guo , Thomas Abraham , Dong Aisheng , Rajendra Nayak , Linus Walleij Subject: [PATCH 6/8] pinctrl: COH901XXX: probe the driver from pinmux Date: Mon, 21 Nov 2011 20:48:46 +0100 Message-ID: <1321904926-32443-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.3.2 MIME-Version: 1.0 From: Linus Walleij The U300 pinmux and GPIO drivers are siblings and cannot really live without each other. Unlike most other platforms they are not one combined pin control and GPIO block, but two separate yet interdependent units. Thus we need to tie them close together so that the pin controller can cross-call to the GPIO driver when it needs to e.g. bias pins and such things that only the GPIO driver can do. Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 8 ++++++++ drivers/pinctrl/pinctrl-coh901xxx.c | 28 +++++----------------------- drivers/pinctrl/pinctrl-coh901xxx.h | 3 +++ drivers/pinctrl/pinmux-u300.c | 18 +++++++++++++++++- 4 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 drivers/pinctrl/pinctrl-coh901xxx.h diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index ac0791e..f399862 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1602,6 +1602,14 @@ static struct platform_device pinmux_device = { .id = -1, .num_resources = ARRAY_SIZE(pinmux_resources), .resource = pinmux_resources, + .dev = { + /* + * Pass in the GPIO platform device as platform data so that + * the pinmux device can probe the GPIO device, a bit tricky + * but works nicely! + */ + .platform_data = &gpio_device, + }, }; /* Pinmux settings */ diff --git a/drivers/pinctrl/pinctrl-coh901xxx.c b/drivers/pinctrl/pinctrl-coh901xxx.c index 69fb707..7f51fb8 100644 --- a/drivers/pinctrl/pinctrl-coh901xxx.c +++ b/drivers/pinctrl/pinctrl-coh901xxx.c @@ -24,6 +24,7 @@ #include #include #include +#include "pinctrl-coh901xxx.h" /* * Bias modes for U300 GPIOs @@ -710,7 +711,8 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) } } -static int __init u300_gpio_probe(struct platform_device *pdev) +int __init u300_gpio_probe(struct platform_device *pdev, + struct gpio_chip **chip) { struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); struct u300_gpio *gpio; @@ -862,6 +864,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, gpio); + *chip = &gpio->chip; return 0; @@ -883,7 +886,7 @@ err_no_clk: return err; } -static int __exit u300_gpio_remove(struct platform_device *pdev) +int __exit u300_gpio_remove(struct platform_device *pdev) { struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); struct u300_gpio *gpio = platform_get_drvdata(pdev); @@ -912,27 +915,6 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) return 0; } -static struct platform_driver u300_gpio_driver = { - .driver = { - .name = "u300-gpio", - }, - .remove = __exit_p(u300_gpio_remove), -}; - - -static int __init u300_gpio_init(void) -{ - return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); -} - -static void __exit u300_gpio_exit(void) -{ - platform_driver_unregister(&u300_gpio_driver); -} - -arch_initcall(u300_gpio_init); -module_exit(u300_gpio_exit); - MODULE_AUTHOR("Linus Walleij "); MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-coh901xxx.h b/drivers/pinctrl/pinctrl-coh901xxx.h new file mode 100644 index 0000000..20390ec --- /dev/null +++ b/drivers/pinctrl/pinctrl-coh901xxx.h @@ -0,0 +1,3 @@ +int u300_gpio_probe(struct platform_device *pdev, + struct gpio_chip **chip); +int u300_gpio_remove(struct platform_device *pdev); diff --git a/drivers/pinctrl/pinmux-u300.c b/drivers/pinctrl/pinmux-u300.c index 7e89b36..1232857 100644 --- a/drivers/pinctrl/pinmux-u300.c +++ b/drivers/pinctrl/pinmux-u300.c @@ -19,6 +19,7 @@ #include #include #include +#include "pinctrl-coh901xxx.h" /* * Register definitions for the U300 Padmux control registers in the @@ -663,6 +664,7 @@ struct u300_pmx { u32 phybase; u32 physize; void __iomem *virtbase; + struct platform_device *gpio_pdev; }; /** @@ -1056,6 +1058,7 @@ static struct pinctrl_desc u300_pmx_desc = { static int __init u300_pmx_probe(struct platform_device *pdev) { + struct gpio_chip *chip; struct u300_pmx *upmx; struct resource *res; int ret; @@ -1066,6 +1069,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev) if (!upmx) return -ENOMEM; + upmx->gpio_pdev = dev_get_platdata(&pdev->dev); upmx->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1095,9 +1099,18 @@ static int __init u300_pmx_probe(struct platform_device *pdev) goto out_no_pmx; } + /* Now probe the sibling GPIO driver */ + ret = u300_gpio_probe(upmx->gpio_pdev, &chip); + if (ret) { + dev_err(&pdev->dev, "could not probe sibling GPIO device\n"); + goto out_no_gpio; + } + /* We will handle a range of GPIO pins */ - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { + u300_gpio_ranges[i].gc = chip; pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + } platform_set_drvdata(pdev, upmx); @@ -1105,6 +1118,8 @@ static int __init u300_pmx_probe(struct platform_device *pdev) return 0; +out_no_gpio: + pinctrl_unregister(upmx->pctl); out_no_pmx: iounmap(upmx->virtbase); out_no_remap: @@ -1123,6 +1138,7 @@ static int __exit u300_pmx_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + u300_gpio_remove(upmx->gpio_pdev); pinctrl_unregister(upmx->pctl); iounmap(upmx->virtbase); release_mem_region(upmx->phybase, upmx->physize);