diff options
| author | KV Sujith <sujithkv@ti.com> | 2013-11-21 13:15:29 -0500 |
|---|---|---|
| committer | Sekhar Nori <nsekhar@ti.com> | 2013-12-25 13:32:11 -0500 |
| commit | c770844c3e30bed3c269efff1bbb9a14c2318e39 (patch) | |
| tree | e7bbeef5c10b5cce2673c77a5197de95653d3e36 /drivers/gpio | |
| parent | d3422a18dbc4a8aa1d430828b39e48d6c91f1791 (diff) | |
gpio: davinci: add OF support
This patch adds OF parser support for davinci gpio
driver and also appropriate documentation in gpio-davinci.txt
located at Documentation/devicetree/bindings/gpio/.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: KV Sujith <sujithkv@ti.com>
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
[prabhakar.csengg@gmail.com: simplified the OF code, removed
unnecessary DT property and also simplified
the commit message]
Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/gpio-davinci.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 92d9922cfcc7..37cf95254df1 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c | |||
| @@ -17,6 +17,9 @@ | |||
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
| 19 | #include <linux/irqdomain.h> | 19 | #include <linux/irqdomain.h> |
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/of.h> | ||
| 22 | #include <linux/of_device.h> | ||
| 20 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 21 | #include <linux/platform_data/gpio-davinci.h> | 24 | #include <linux/platform_data/gpio-davinci.h> |
| 22 | 25 | ||
| @@ -134,6 +137,40 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
| 134 | writel_relaxed((1 << offset), value ? &g->set_data : &g->clr_data); | 137 | writel_relaxed((1 << offset), value ? &g->set_data : &g->clr_data); |
| 135 | } | 138 | } |
| 136 | 139 | ||
| 140 | static struct davinci_gpio_platform_data * | ||
| 141 | davinci_gpio_get_pdata(struct platform_device *pdev) | ||
| 142 | { | ||
| 143 | struct device_node *dn = pdev->dev.of_node; | ||
| 144 | struct davinci_gpio_platform_data *pdata; | ||
| 145 | int ret; | ||
| 146 | u32 val; | ||
| 147 | |||
| 148 | if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) | ||
| 149 | return pdev->dev.platform_data; | ||
| 150 | |||
| 151 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 152 | if (!pdata) | ||
| 153 | return NULL; | ||
| 154 | |||
| 155 | ret = of_property_read_u32(dn, "ti,ngpio", &val); | ||
| 156 | if (ret) | ||
| 157 | goto of_err; | ||
| 158 | |||
| 159 | pdata->ngpio = val; | ||
| 160 | |||
| 161 | ret = of_property_read_u32(dn, "ti,davinci-gpio-unbanked", &val); | ||
| 162 | if (ret) | ||
| 163 | goto of_err; | ||
| 164 | |||
| 165 | pdata->gpio_unbanked = val; | ||
| 166 | |||
| 167 | return pdata; | ||
| 168 | |||
| 169 | of_err: | ||
| 170 | dev_err(&pdev->dev, "Populating pdata from DT failed: err %d\n", ret); | ||
| 171 | return NULL; | ||
| 172 | } | ||
| 173 | |||
| 137 | static int davinci_gpio_probe(struct platform_device *pdev) | 174 | static int davinci_gpio_probe(struct platform_device *pdev) |
| 138 | { | 175 | { |
| 139 | int i, base; | 176 | int i, base; |
| @@ -144,12 +181,14 @@ static int davinci_gpio_probe(struct platform_device *pdev) | |||
| 144 | struct device *dev = &pdev->dev; | 181 | struct device *dev = &pdev->dev; |
| 145 | struct resource *res; | 182 | struct resource *res; |
| 146 | 183 | ||
| 147 | pdata = dev->platform_data; | 184 | pdata = davinci_gpio_get_pdata(pdev); |
| 148 | if (!pdata) { | 185 | if (!pdata) { |
| 149 | dev_err(dev, "No platform data found\n"); | 186 | dev_err(dev, "No platform data found\n"); |
| 150 | return -EINVAL; | 187 | return -EINVAL; |
| 151 | } | 188 | } |
| 152 | 189 | ||
| 190 | dev->platform_data = pdata; | ||
| 191 | |||
| 153 | /* | 192 | /* |
| 154 | * The gpio banks conceptually expose a segmented bitmap, | 193 | * The gpio banks conceptually expose a segmented bitmap, |
| 155 | * and "ngpio" is one more than the largest zero-based | 194 | * and "ngpio" is one more than the largest zero-based |
| @@ -195,6 +234,9 @@ static int davinci_gpio_probe(struct platform_device *pdev) | |||
| 195 | if (chips[i].chip.ngpio > 32) | 234 | if (chips[i].chip.ngpio > 32) |
| 196 | chips[i].chip.ngpio = 32; | 235 | chips[i].chip.ngpio = 32; |
| 197 | 236 | ||
| 237 | #ifdef CONFIG_OF_GPIO | ||
| 238 | chips[i].chip.of_node = dev->of_node; | ||
| 239 | #endif | ||
| 198 | spin_lock_init(&chips[i].lock); | 240 | spin_lock_init(&chips[i].lock); |
| 199 | 241 | ||
| 200 | regs = gpio2regs(base); | 242 | regs = gpio2regs(base); |
| @@ -506,11 +548,20 @@ done: | |||
| 506 | return 0; | 548 | return 0; |
| 507 | } | 549 | } |
| 508 | 550 | ||
| 551 | #if IS_ENABLED(CONFIG_OF) | ||
| 552 | static const struct of_device_id davinci_gpio_ids[] = { | ||
| 553 | { .compatible = "ti,dm6441-gpio", }, | ||
| 554 | { /* sentinel */ }, | ||
| 555 | }; | ||
| 556 | MODULE_DEVICE_TABLE(of, davinci_gpio_ids); | ||
| 557 | #endif | ||
| 558 | |||
| 509 | static struct platform_driver davinci_gpio_driver = { | 559 | static struct platform_driver davinci_gpio_driver = { |
| 510 | .probe = davinci_gpio_probe, | 560 | .probe = davinci_gpio_probe, |
| 511 | .driver = { | 561 | .driver = { |
| 512 | .name = "davinci_gpio", | 562 | .name = "davinci_gpio", |
| 513 | .owner = THIS_MODULE, | 563 | .owner = THIS_MODULE, |
| 564 | .of_match_table = of_match_ptr(davinci_gpio_ids), | ||
| 514 | }, | 565 | }, |
| 515 | }; | 566 | }; |
| 516 | 567 | ||
