@@ -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 */
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/pinctrl/pinmux.h>
#include <mach/gpio-u300.h>
+#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 <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver");
MODULE_LICENSE("GPL");
new file mode 100644
@@ -0,0 +1,3 @@
+int u300_gpio_probe(struct platform_device *pdev,
+ struct gpio_chip **chip);
+int u300_gpio_remove(struct platform_device *pdev);
@@ -19,6 +19,7 @@
#include <linux/err.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
+#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);