From patchwork Tue Feb 21 13:34:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 6864 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 0B34D23E48 for ; Tue, 21 Feb 2012 13:35:08 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id A433FA183A2 for ; Tue, 21 Feb 2012 13:35:07 +0000 (UTC) Received: by iabz7 with SMTP id z7so12432832iab.11 for ; Tue, 21 Feb 2012 05:35:07 -0800 (PST) Received: from mr.google.com ([10.50.34.202]) by 10.50.34.202 with SMTP id b10mr19353653igj.30.1329831307189 (num_hops = 1); Tue, 21 Feb 2012 05:35:07 -0800 (PST) Received: by 10.50.34.202 with SMTP id b10mr15572753igj.30.1329831307064; Tue, 21 Feb 2012 05:35:07 -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.231.11.10 with SMTP id r10csp94772ibr; Tue, 21 Feb 2012 05:35:06 -0800 (PST) Received: by 10.14.126.10 with SMTP id a10mr10304754eei.42.1329831305437; Tue, 21 Feb 2012 05:35:05 -0800 (PST) Received: from eu1sys200aog117.obsmtp.com (eu1sys200aog117.obsmtp.com. [207.126.144.143]) by mx.google.com with SMTP id d47si15863244eec.26.2012.02.21.05.34.53 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 21 Feb 2012 05:35:05 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.143 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.143; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.143 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-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob117.postini.com ([207.126.147.11]) with SMTP ID DSNKT0OdfADl4M7EkRjQf17EAH4L9e0x3XLv@postini.com; Tue, 21 Feb 2012 13:35:04 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E7E90112; Tue, 21 Feb 2012 13:34:39 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 47D572252; Tue, 21 Feb 2012 13:34:39 +0000 (GMT) Received: from exdcvycastm004.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm004", Issuer "exdcvycastm004" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id C8F00A8088; Tue, 21 Feb 2012 14:34:33 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.2) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 21 Feb 2012 14:34:38 +0100 From: Linus Walleij To: , Cc: Stephen Warren , Grant Likely , Barry Song <21cnbao@gmail.com>, Shawn Guo , Thomas Abraham , Dong Aisheng , Rajendra Nayak , Haojian Zhuang , Linus Walleij Subject: [PATCH] pinctrl: spawn U300 pinctrl from the COH901 GPIO Date: Tue, 21 Feb 2012 14:34:35 +0100 Message-ID: <1329831275-21769-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.8 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnT+sLVv3vZzSX4u8zYhrfLYaf/3Xsln7LhMo9M42L05NMR5Dz6Uf2LK9GfuH/GfxLdUofr From: Linus Walleij This solves the riddle on how the U300 pin controller shall be able to reference the struct gpio_chip even though these are two separate drivers: spawn the pinctrl child from the GPIO driver and pass in the struct gpio_chip as platform data. In the process we rename the U300 "pinmux-u300" to "pinctrl-u300" so as not to confuse. Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 30 +++++++++++++------------- arch/arm/mach-u300/include/mach/gpio-u300.h | 2 + drivers/pinctrl/pinctrl-coh901.c | 10 +++++++- drivers/pinctrl/pinctrl-u300.c | 20 +++++++++++------ 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index bb1034f..030b2c0 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = { .max_channels = U300_DMA_CHANNELS, }; -static struct resource pinmux_resources[] = { +static struct resource pinctrl_resources[] = { { .start = U300_SYSCON_BASE, .end = U300_SYSCON_BASE + SZ_4K - 1, @@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = { .resource = i2c1_resources, }; +static struct platform_device pinctrl_device = { + .name = "pinctrl-u300", + .id = -1, + .num_resources = ARRAY_SIZE(pinctrl_resources), + .resource = pinctrl_resources, +}; + /* * The different variants have a few different versions of the * GPIO block, with different number of ports. @@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = { #endif .gpio_base = 0, .gpio_irq_base = IRQ_U300_GPIO_BASE, + .pinctrl_device = &pinctrl_device, }; static struct platform_device gpio_device = { @@ -1597,23 +1605,16 @@ static struct platform_device dma_device = { }, }; -static struct platform_device pinmux_device = { - .name = "pinmux-u300", - .id = -1, - .num_resources = ARRAY_SIZE(pinmux_resources), - .resource = pinmux_resources, -}; - /* Pinmux settings */ static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), - PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), - PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), + PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"), + PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"), + PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"), /* per-device maps for MMC/SD, SPI and UART */ - PIN_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), - PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"), - PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"), + PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"), + PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"), + PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"), }; struct u300_mux_hog { @@ -1676,7 +1677,6 @@ static struct platform_device *platform_devs[] __initdata = { &gpio_device, &nand_device, &wdog_device, - &pinmux_device, }; /* diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h index bf4c793..e81400c 100644 --- a/arch/arm/mach-u300/include/mach/gpio-u300.h +++ b/arch/arm/mach-u300/include/mach/gpio-u300.h @@ -24,12 +24,14 @@ enum u300_gpio_variant { * @ports: number of GPIO block ports * @gpio_base: first GPIO number for this block (use a free range) * @gpio_irq_base: first GPIO IRQ number for this block (use a free range) + * @pinctrl_device: pin control device to spawn as child */ struct u300_gpio_platform { enum u300_gpio_variant variant; u8 ports; int gpio_base; int gpio_irq_base; + struct platform_device *pinctrl_device; }; #endif /* __MACH_U300_GPIO_U300_H */ diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index eba232a..b90c011 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) list_for_each_safe(p, n, &gpio->port_list) { port = list_entry(p, struct u300_gpio_port, node); list_del(&port->node); - free_irq(port->irq, port); kfree(port); } } @@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev) goto err_no_chip; } + /* Spawn pin controller device as child of the GPIO, pass gpio chip */ + plat->pinctrl_device->dev.platform_data = &gpio->chip; + err = platform_device_register(plat->pinctrl_device); + if (err) + goto err_no_pinctrl; + platform_set_drvdata(pdev, gpio); return 0; +err_no_pinctrl: + err = gpiochip_remove(&gpio->chip); err_no_chip: err_no_port: u300_gpio_free_ports(gpio); @@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = { .remove = __exit_p(u300_gpio_remove), }; - static int __init u300_gpio_init(void) { return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index c8d02f1..fc4a281 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -162,7 +162,7 @@ #define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100 #define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200 -#define DRIVER_NAME "pinmux-u300" +#define DRIVER_NAME "pinctrl-u300" /* * The DB3350 has 467 pads, I have enumerated the pads clockwise around the @@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = { .owner = THIS_MODULE, }; -static int __init u300_pmx_probe(struct platform_device *pdev) +static int __devinit u300_pmx_probe(struct platform_device *pdev) { struct u300_pmx *upmx; struct resource *res; + struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); int ret; int i; + pr_err("U300 PMX PROBE\n"); + /* Create state holders etc for this driver */ upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); if (!upmx) @@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev) } /* 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 = gpio_chip; pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + } platform_set_drvdata(pdev, upmx); - dev_info(&pdev->dev, "initialized U300 pinmux driver\n"); + dev_info(&pdev->dev, "initialized U300 pin control driver\n"); return 0; @@ -1115,7 +1120,7 @@ out_no_resource: return ret; } -static int __exit u300_pmx_remove(struct platform_device *pdev) +static int __devexit u300_pmx_remove(struct platform_device *pdev) { struct u300_pmx *upmx = platform_get_drvdata(pdev); int i; @@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, - .remove = __exit_p(u300_pmx_remove), + .probe = u300_pmx_probe, + .remove = __devexit_p(u300_pmx_remove), }; static int __init u300_pmx_init(void) { - return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe); + return platform_driver_register(&u300_pmx_driver); } arch_initcall(u300_pmx_init);