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