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 | |
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')
-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 | ||