diff options
Diffstat (limited to 'drivers/gpio/gpio-pca953x.c')
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae17956..0c5eaf5f4c90 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/irqdomain.h> | ||
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
20 | #include <linux/i2c/pca953x.h> | 21 | #include <linux/i2c/pca953x.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -83,6 +84,7 @@ struct pca953x_chip { | |||
83 | u32 irq_trig_raise; | 84 | u32 irq_trig_raise; |
84 | u32 irq_trig_fall; | 85 | u32 irq_trig_fall; |
85 | int irq_base; | 86 | int irq_base; |
87 | struct irq_domain *domain; | ||
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | struct i2c_client *client; | 90 | struct i2c_client *client; |
@@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d) | |||
333 | { | 335 | { |
334 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 336 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
335 | 337 | ||
336 | chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); | 338 | chip->irq_mask &= ~(1 << d->hwirq); |
337 | } | 339 | } |
338 | 340 | ||
339 | static void pca953x_irq_unmask(struct irq_data *d) | 341 | static void pca953x_irq_unmask(struct irq_data *d) |
340 | { | 342 | { |
341 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 343 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
342 | 344 | ||
343 | chip->irq_mask |= 1 << (d->irq - chip->irq_base); | 345 | chip->irq_mask |= 1 << d->hwirq; |
344 | } | 346 | } |
345 | 347 | ||
346 | static void pca953x_irq_bus_lock(struct irq_data *d) | 348 | static void pca953x_irq_bus_lock(struct irq_data *d) |
@@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 374 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
373 | { | 375 | { |
374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 376 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
375 | u32 level = d->irq - chip->irq_base; | 377 | u32 mask = 1 << d->hwirq; |
376 | u32 mask = 1 << level; | ||
377 | 378 | ||
378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 379 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 380 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
@@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
454 | 455 | ||
455 | do { | 456 | do { |
456 | level = __ffs(pending); | 457 | level = __ffs(pending); |
457 | handle_nested_irq(level + chip->irq_base); | 458 | handle_nested_irq(irq_find_mapping(chip->domain, level)); |
458 | 459 | ||
459 | pending &= ~(1 << level); | 460 | pending &= ~(1 << level); |
460 | } while (pending); | 461 | } while (pending); |
@@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
499 | if (chip->irq_base < 0) | 500 | if (chip->irq_base < 0) |
500 | goto out_failed; | 501 | goto out_failed; |
501 | 502 | ||
503 | chip->domain = irq_domain_add_legacy(client->dev.of_node, | ||
504 | chip->gpio_chip.ngpio, | ||
505 | chip->irq_base, | ||
506 | 0, | ||
507 | &irq_domain_simple_ops, | ||
508 | NULL); | ||
509 | if (!chip->domain) { | ||
510 | ret = -ENODEV; | ||
511 | goto out_irqdesc_free; | ||
512 | } | ||
513 | |||
502 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { | 514 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { |
503 | int irq = lvl + chip->irq_base; | 515 | int irq = lvl + chip->irq_base; |
504 | 516 | ||
@@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
521 | if (ret) { | 533 | if (ret) { |
522 | dev_err(&client->dev, "failed to request irq %d\n", | 534 | dev_err(&client->dev, "failed to request irq %d\n", |
523 | client->irq); | 535 | client->irq); |
524 | goto out_failed; | 536 | goto out_irqdesc_free; |
525 | } | 537 | } |
526 | 538 | ||
527 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; | 539 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; |
@@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
529 | 541 | ||
530 | return 0; | 542 | return 0; |
531 | 543 | ||
544 | out_irqdesc_free: | ||
545 | irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); | ||
532 | out_failed: | 546 | out_failed: |
533 | chip->irq_base = -1; | 547 | chip->irq_base = -1; |
534 | return ret; | 548 | return ret; |
@@ -751,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client) | |||
751 | return 0; | 765 | return 0; |
752 | } | 766 | } |
753 | 767 | ||
768 | static const struct of_device_id pca953x_dt_ids[] = { | ||
769 | { .compatible = "nxp,pca9534", }, | ||
770 | { .compatible = "nxp,pca9535", }, | ||
771 | { .compatible = "nxp,pca9536", }, | ||
772 | { .compatible = "nxp,pca9537", }, | ||
773 | { .compatible = "nxp,pca9538", }, | ||
774 | { .compatible = "nxp,pca9539", }, | ||
775 | { .compatible = "nxp,pca9554", }, | ||
776 | { .compatible = "nxp,pca9555", }, | ||
777 | { .compatible = "nxp,pca9556", }, | ||
778 | { .compatible = "nxp,pca9557", }, | ||
779 | { .compatible = "nxp,pca9574", }, | ||
780 | { .compatible = "nxp,pca9575", }, | ||
781 | |||
782 | { .compatible = "maxim,max7310", }, | ||
783 | { .compatible = "maxim,max7312", }, | ||
784 | { .compatible = "maxim,max7313", }, | ||
785 | { .compatible = "maxim,max7315", }, | ||
786 | |||
787 | { .compatible = "ti,pca6107", }, | ||
788 | { .compatible = "ti,tca6408", }, | ||
789 | { .compatible = "ti,tca6416", }, | ||
790 | { .compatible = "ti,tca6424", }, | ||
791 | { } | ||
792 | }; | ||
793 | |||
794 | MODULE_DEVICE_TABLE(of, pca953x_dt_ids); | ||
795 | |||
754 | static struct i2c_driver pca953x_driver = { | 796 | static struct i2c_driver pca953x_driver = { |
755 | .driver = { | 797 | .driver = { |
756 | .name = "pca953x", | 798 | .name = "pca953x", |
799 | .of_match_table = pca953x_dt_ids, | ||
757 | }, | 800 | }, |
758 | .probe = pca953x_probe, | 801 | .probe = pca953x_probe, |
759 | .remove = pca953x_remove, | 802 | .remove = pca953x_remove, |