aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-tc3589x.c
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2012-09-07 07:14:59 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-09-12 17:15:46 -0400
commit3113e679021a3a6bace1c62a8432cc0ec27c09ab (patch)
tree4577064b83b9c7da36bc64f35e76b58107658b2d /drivers/gpio/gpio-tc3589x.c
parentefe4c9496a80253492942624dd23caa3ca6782c8 (diff)
gpio: Enable the tc3298x GPIO expander driver for Device Tree
Here we provide a means to probe and extract vital information from Device Tree when booting with it enabled. Without this patch sub-devices wouldn't be able to reference the tc3589x-gpio expander from Device Tree. CC: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-tc3589x.c')
-rw-r--r--drivers/gpio/gpio-tc3589x.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c
index 6e8900933972..1e48317e70fb 100644
--- a/drivers/gpio/gpio-tc3589x.c
+++ b/drivers/gpio/gpio-tc3589x.c
@@ -11,6 +11,7 @@
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/gpio.h> 13#include <linux/gpio.h>
14#include <linux/of.h>
14#include <linux/irq.h> 15#include <linux/irq.h>
15#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
@@ -286,7 +287,8 @@ static struct irq_domain_ops tc3589x_irq_ops = {
286 .xlate = irq_domain_xlate_twocell, 287 .xlate = irq_domain_xlate_twocell,
287}; 288};
288 289
289static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio) 290static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio,
291 struct device_node *np)
290{ 292{
291 int base = tc3589x_gpio->irq_base; 293 int base = tc3589x_gpio->irq_base;
292 294
@@ -297,7 +299,7 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio)
297 } 299 }
298 else { 300 else {
299 tc3589x_gpio->domain = irq_domain_add_linear( 301 tc3589x_gpio->domain = irq_domain_add_linear(
300 NULL, tc3589x_gpio->chip.ngpio, 302 np, tc3589x_gpio->chip.ngpio,
301 &tc3589x_irq_ops, tc3589x_gpio); 303 &tc3589x_irq_ops, tc3589x_gpio);
302 } 304 }
303 305
@@ -313,13 +315,17 @@ static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
313{ 315{
314 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); 316 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
315 struct tc3589x_gpio_platform_data *pdata; 317 struct tc3589x_gpio_platform_data *pdata;
318 struct device_node *np = pdev->dev.of_node;
316 struct tc3589x_gpio *tc3589x_gpio; 319 struct tc3589x_gpio *tc3589x_gpio;
317 int ret; 320 int ret;
318 int irq; 321 int irq;
319 322
320 pdata = tc3589x->pdata->gpio; 323 pdata = tc3589x->pdata->gpio;
321 if (!pdata) 324
322 return -ENODEV; 325 if (!(pdata || np)) {
326 dev_err(&pdev->dev, "No platform data or Device Tree found\n");
327 return -EINVAL;
328 }
323 329
324 irq = platform_get_irq(pdev, 0); 330 irq = platform_get_irq(pdev, 0);
325 if (irq < 0) 331 if (irq < 0)
@@ -337,9 +343,11 @@ static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
337 tc3589x_gpio->chip = template_chip; 343 tc3589x_gpio->chip = template_chip;
338 tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; 344 tc3589x_gpio->chip.ngpio = tc3589x->num_gpio;
339 tc3589x_gpio->chip.dev = &pdev->dev; 345 tc3589x_gpio->chip.dev = &pdev->dev;
340 tc3589x_gpio->chip.base = pdata->gpio_base; 346 tc3589x_gpio->chip.base = (pdata) ? pdata->gpio_base : -1;
341 347
342 tc3589x_gpio->irq_base = tc3589x->irq_base + TC3589x_INT_GPIO(0); 348#ifdef CONFIG_OF_GPIO
349 tc3589x_gpio->chip.of_node = np;
350#endif
343 351
344 tc3589x_gpio->irq_base = tc3589x->irq_base ? 352 tc3589x_gpio->irq_base = tc3589x->irq_base ?
345 tc3589x->irq_base + TC3589x_INT_GPIO(0) : 0; 353 tc3589x->irq_base + TC3589x_INT_GPIO(0) : 0;
@@ -350,7 +358,7 @@ static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
350 if (ret < 0) 358 if (ret < 0)
351 goto out_free; 359 goto out_free;
352 360
353 ret = tc3589x_gpio_irq_init(tc3589x_gpio); 361 ret = tc3589x_gpio_irq_init(tc3589x_gpio, np);
354 if (ret) 362 if (ret)
355 goto out_free; 363 goto out_free;
356 364
@@ -367,7 +375,7 @@ static int __devinit tc3589x_gpio_probe(struct platform_device *pdev)
367 goto out_freeirq; 375 goto out_freeirq;
368 } 376 }
369 377
370 if (pdata->setup) 378 if (pdata && pdata->setup)
371 pdata->setup(tc3589x, tc3589x_gpio->chip.base); 379 pdata->setup(tc3589x, tc3589x_gpio->chip.base);
372 380
373 platform_set_drvdata(pdev, tc3589x_gpio); 381 platform_set_drvdata(pdev, tc3589x_gpio);
@@ -389,7 +397,7 @@ static int __devexit tc3589x_gpio_remove(struct platform_device *pdev)
389 int irq = platform_get_irq(pdev, 0); 397 int irq = platform_get_irq(pdev, 0);
390 int ret; 398 int ret;
391 399
392 if (pdata->remove) 400 if (pdata && pdata->remove)
393 pdata->remove(tc3589x, tc3589x_gpio->chip.base); 401 pdata->remove(tc3589x, tc3589x_gpio->chip.base);
394 402
395 ret = gpiochip_remove(&tc3589x_gpio->chip); 403 ret = gpiochip_remove(&tc3589x_gpio->chip);