Commit 128a06d4 authored by Linus Walleij's avatar Linus Walleij

pinctrl: spawn U300 pinctrl from the COH901 GPIO

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: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 4ecce45d
...@@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = { ...@@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS, .max_channels = U300_DMA_CHANNELS,
}; };
static struct resource pinmux_resources[] = { static struct resource pinctrl_resources[] = {
{ {
.start = U300_SYSCON_BASE, .start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1, .end = U300_SYSCON_BASE + SZ_4K - 1,
...@@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = { ...@@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources, .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 * The different variants have a few different versions of the
* GPIO block, with different number of ports. * GPIO block, with different number of ports.
...@@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = { ...@@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif #endif
.gpio_base = 0, .gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE, .gpio_irq_base = IRQ_U300_GPIO_BASE,
.pinctrl_device = &pinctrl_device,
}; };
static struct platform_device gpio_device = { static struct platform_device gpio_device = {
...@@ -1597,23 +1605,16 @@ static struct platform_device dma_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 */ /* Pinmux settings */
static struct pinctrl_map __initdata u300_pinmux_map[] = { static struct pinctrl_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */ /* anonymous maps for chip power and EMIFs */
PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"),
PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"),
PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"),
/* per-device maps for MMC/SD, SPI and UART */ /* per-device maps for MMC/SD, SPI and UART */
PIN_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"),
PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"), PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"),
PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"), PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"),
}; };
struct u300_mux_hog { struct u300_mux_hog {
...@@ -1676,7 +1677,6 @@ static struct platform_device *platform_devs[] __initdata = { ...@@ -1676,7 +1677,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device, &gpio_device,
&nand_device, &nand_device,
&wdog_device, &wdog_device,
&pinmux_device,
}; };
/* /*
......
...@@ -24,12 +24,14 @@ enum u300_gpio_variant { ...@@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports * @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range) * @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) * @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 { struct u300_gpio_platform {
enum u300_gpio_variant variant; enum u300_gpio_variant variant;
u8 ports; u8 ports;
int gpio_base; int gpio_base;
int gpio_irq_base; int gpio_irq_base;
struct platform_device *pinctrl_device;
}; };
#endif /* __MACH_U300_GPIO_U300_H */ #endif /* __MACH_U300_GPIO_U300_H */
...@@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) ...@@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) { list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node); port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node); list_del(&port->node);
free_irq(port->irq, port);
kfree(port); kfree(port);
} }
} }
...@@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev) ...@@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip; 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); platform_set_drvdata(pdev, gpio);
return 0; return 0;
err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip: err_no_chip:
err_no_port: err_no_port:
u300_gpio_free_ports(gpio); u300_gpio_free_ports(gpio);
...@@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = { ...@@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove), .remove = __exit_p(u300_gpio_remove),
}; };
static int __init u300_gpio_init(void) static int __init u300_gpio_init(void)
{ {
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
......
...@@ -162,7 +162,7 @@ ...@@ -162,7 +162,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100 #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 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 * The DB3350 has 467 pads, I have enumerated the pads clockwise around the
...@@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = { ...@@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = {
.owner = THIS_MODULE, .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 u300_pmx *upmx;
struct resource *res; struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret; int ret;
int i; int i;
pr_err("U300 PMX PROBE\n");
/* Create state holders etc for this driver */ /* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx) if (!upmx)
...@@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
} }
/* We will handle a range of GPIO pins */ /* 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]); pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
}
platform_set_drvdata(pdev, upmx); 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; return 0;
...@@ -1115,7 +1120,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1115,7 +1120,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
return ret; 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); struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i; int i;
...@@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = { ...@@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE, .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) 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); arch_initcall(u300_pmx_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment