diff options
author | Daniel Mack <zonque@gmail.com> | 2012-07-25 11:35:39 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-08-05 05:39:41 -0400 |
commit | 72121572670973bec6fb1b9fdb454b106b253235 (patch) | |
tree | f3100d2748ca68fd0397d936d718c398021bd9a9 /drivers/gpio | |
parent | f7da0bdbf585c0404fc89901ee4bdb806e70530f (diff) |
GPIO: gpio-pxa: fix devicetree functions
Provide an of_xlate function for the PXA GPIO chips and make it work for
devicetree environments.
Successfully tested on a PXA3xx board.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-pxa.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 58a6a63a6ece..793767b0962a 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -62,6 +62,7 @@ int pxa_last_gpio; | |||
62 | 62 | ||
63 | #ifdef CONFIG_OF | 63 | #ifdef CONFIG_OF |
64 | static struct irq_domain *domain; | 64 | static struct irq_domain *domain; |
65 | static struct device_node *pxa_gpio_of_node; | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
67 | struct pxa_gpio_chip { | 68 | struct pxa_gpio_chip { |
@@ -277,6 +278,24 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
277 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 278 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
278 | } | 279 | } |
279 | 280 | ||
281 | #ifdef CONFIG_OF_GPIO | ||
282 | static int pxa_gpio_of_xlate(struct gpio_chip *gc, | ||
283 | const struct of_phandle_args *gpiospec, | ||
284 | u32 *flags) | ||
285 | { | ||
286 | if (gpiospec->args[0] > pxa_last_gpio) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip) | ||
290 | return -EINVAL; | ||
291 | |||
292 | if (flags) | ||
293 | *flags = gpiospec->args[1]; | ||
294 | |||
295 | return gpiospec->args[0] % 32; | ||
296 | } | ||
297 | #endif | ||
298 | |||
280 | static int __devinit pxa_init_gpio_chip(int gpio_end, | 299 | static int __devinit pxa_init_gpio_chip(int gpio_end, |
281 | int (*set_wake)(unsigned int, unsigned int)) | 300 | int (*set_wake)(unsigned int, unsigned int)) |
282 | { | 301 | { |
@@ -304,6 +323,11 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, | |||
304 | c->get = pxa_gpio_get; | 323 | c->get = pxa_gpio_get; |
305 | c->set = pxa_gpio_set; | 324 | c->set = pxa_gpio_set; |
306 | c->to_irq = pxa_gpio_to_irq; | 325 | c->to_irq = pxa_gpio_to_irq; |
326 | #ifdef CONFIG_OF_GPIO | ||
327 | c->of_node = pxa_gpio_of_node; | ||
328 | c->of_xlate = pxa_gpio_of_xlate; | ||
329 | c->of_gpio_n_cells = 2; | ||
330 | #endif | ||
307 | 331 | ||
308 | /* number of GPIOs on last bank may be less than 32 */ | 332 | /* number of GPIOs on last bank may be less than 32 */ |
309 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 333 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
@@ -505,6 +529,7 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
505 | 529 | ||
506 | const struct irq_domain_ops pxa_irq_domain_ops = { | 530 | const struct irq_domain_ops pxa_irq_domain_ops = { |
507 | .map = pxa_irq_domain_map, | 531 | .map = pxa_irq_domain_map, |
532 | .xlate = irq_domain_xlate_twocell, | ||
508 | }; | 533 | }; |
509 | 534 | ||
510 | #ifdef CONFIG_OF | 535 | #ifdef CONFIG_OF |
@@ -545,6 +570,7 @@ static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | |||
545 | } | 570 | } |
546 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, | 571 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, |
547 | &pxa_irq_domain_ops, NULL); | 572 | &pxa_irq_domain_ops, NULL); |
573 | pxa_gpio_of_node = np; | ||
548 | return 0; | 574 | return 0; |
549 | err: | 575 | err: |
550 | iounmap(gpio_reg_base); | 576 | iounmap(gpio_reg_base); |