aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKV Sujith <sujithkv@ti.com>2013-11-21 13:15:29 -0500
committerSekhar Nori <nsekhar@ti.com>2013-12-25 13:32:11 -0500
commitc770844c3e30bed3c269efff1bbb9a14c2318e39 (patch)
treee7bbeef5c10b5cce2673c77a5197de95653d3e36
parentd3422a18dbc4a8aa1d430828b39e48d6c91f1791 (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>
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-davinci.txt41
-rw-r--r--drivers/gpio/gpio-davinci.c57
2 files changed, 95 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
new file mode 100644
index 000000000000..a2e839d6e338
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
@@ -0,0 +1,41 @@
1Davinci GPIO controller bindings
2
3Required Properties:
4- compatible: should be "ti,dm6441-gpio"
5
6- reg: Physical base address of the controller and the size of memory mapped
7 registers.
8
9- gpio-controller : Marks the device node as a gpio controller.
10
11- interrupt-parent: phandle of the parent interrupt controller.
12
13- interrupts: Array of GPIO interrupt number. Only banked or unbanked IRQs are
14 supported at a time.
15
16- ti,ngpio: The number of GPIO pins supported.
17
18- ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt
19 line to processor.
20
21The GPIO controller also acts as an interrupt controller. It uses the default
22two cells specifier as described in Documentation/devicetree/bindings/
23interrupt-controller/interrupts.txt.
24
25Example:
26
27gpio: gpio@1e26000 {
28 compatible = "ti,dm6441-gpio";
29 gpio-controller;
30 reg = <0x226000 0x1000>;
31 interrupt-parent = <&intc>;
32 interrupts = <42 IRQ_TYPE_EDGE_BOTH 43 IRQ_TYPE_EDGE_BOTH
33 44 IRQ_TYPE_EDGE_BOTH 45 IRQ_TYPE_EDGE_BOTH
34 46 IRQ_TYPE_EDGE_BOTH 47 IRQ_TYPE_EDGE_BOTH
35 48 IRQ_TYPE_EDGE_BOTH 49 IRQ_TYPE_EDGE_BOTH
36 50 IRQ_TYPE_EDGE_BOTH>;
37 ti,ngpio = <144>;
38 ti,davinci-gpio-unbanked = <0>;
39 interrupt-controller;
40 #interrupt-cells = <2>;
41};
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
140static struct davinci_gpio_platform_data *
141davinci_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
169of_err:
170 dev_err(&pdev->dev, "Populating pdata from DT failed: err %d\n", ret);
171 return NULL;
172}
173
137static int davinci_gpio_probe(struct platform_device *pdev) 174static 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)
552static const struct of_device_id davinci_gpio_ids[] = {
553 { .compatible = "ti,dm6441-gpio", },
554 { /* sentinel */ },
555};
556MODULE_DEVICE_TABLE(of, davinci_gpio_ids);
557#endif
558
509static struct platform_driver davinci_gpio_driver = { 559static 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