diff options
author | Lee Jones <lee.jones@linaro.org> | 2013-01-31 11:07:40 +0000 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-02-06 22:38:48 +0100 |
commit | f30a3839b33c560b374c69be9ba2621d3d6a3d10 (patch) | |
tree | 97cb517942efbf5a3dd611824c7ad3809d39b2b4 /drivers/pinctrl | |
parent | b9fab6e45d2d41de5495f7d40808e9e131652f92 (diff) |
pinctrl/abx500: add Device Tree support
This patch will allow the ABX500 Pinctrl driver to be probed when
Device Tree is enabled with an appropriate node contained.
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/pinctrl-abx500.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index a9e720ffabf..17508b5820f 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -14,6 +14,8 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/err.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/irq.h> @@ -1106,22 +1108,44 @@ static int abx500_get_gpio_num(struct abx500_pinctrl_soc_data *soc) return npins; } +static const struct of_device_id abx500_gpio_match[] = { + { .compatible = "stericsson,ab8500-gpio", .data = (void *)PINCTRL_AB8500, }, + { .compatible = "stericsson,ab8505-gpio", .data = (void *)PINCTRL_AB8505, }, + { .compatible = "stericsson,ab8540-gpio", .data = (void *)PINCTRL_AB8540, }, + { .compatible = "stericsson,ab9540-gpio", .data = (void *)PINCTRL_AB9540, }, +}; + static int abx500_gpio_probe(struct platform_device *pdev) { struct ab8500_platform_data *abx500_pdata = dev_get_platdata(pdev->dev.parent); - struct abx500_gpio_platform_data *pdata; + struct abx500_gpio_platform_data *pdata = NULL; + struct device_node *np = pdev->dev.of_node; struct abx500_pinctrl *pct; const struct platform_device_id *platid = platform_get_device_id(pdev); + unsigned int id = -1; int ret, err; int i; - pdata = abx500_pdata->gpio; + if (abx500_pdata) + pdata = abx500_pdata->gpio; if (!pdata) { - dev_err(&pdev->dev, "gpio platform data missing\n"); - return -ENODEV; + if (np) { + const struct of_device_id *match; + + match = of_match_device(abx500_gpio_match, &pdev->dev); + if (!match) + return -ENODEV; + id = (unsigned long)match->data; + } else { + dev_err(&pdev->dev, "gpio dt and platform data missing\n"); + return -ENODEV; + } } + if (platid) + id = platid->driver_data; + pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl), GFP_KERNEL); if (pct == NULL) { @@ -1136,12 +1160,13 @@ static int abx500_gpio_probe(struct platform_device *pdev) pct->chip.dev = &pdev->dev; pct->chip.base = pdata->gpio_base; pct->irq_base = pdata->irq_base; + pct->chip.base = (np) ? -1 : pdata->gpio_base; /* initialize the lock */ mutex_init(&pct->lock); /* Poke in other ASIC variants here */ - switch (platid->driver_data) { + switch (id) { case PINCTRL_AB8500: abx500_pinctrl_ab8500_init(&pct->soc); break; @@ -1256,6 +1281,7 @@ static struct platform_driver abx500_gpio_driver = { .driver = { .name = "abx500-gpio", .owner = THIS_MODULE, + .of_match_table = abx500_gpio_match, }, .probe = abx500_gpio_probe, .remove = abx500_gpio_remove, |