diff options
| -rw-r--r-- | drivers/base/regmap/regmap-irq.c | 82 | ||||
| -rw-r--r-- | include/linux/regmap.h | 8 |
2 files changed, 90 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 9b0d202414d0..0b0ea3b88a91 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
| @@ -674,6 +674,88 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) | |||
| 674 | } | 674 | } |
| 675 | EXPORT_SYMBOL_GPL(regmap_del_irq_chip); | 675 | EXPORT_SYMBOL_GPL(regmap_del_irq_chip); |
| 676 | 676 | ||
| 677 | static void devm_regmap_irq_chip_release(struct device *dev, void *res) | ||
| 678 | { | ||
| 679 | struct regmap_irq_chip_data *d = *(struct regmap_irq_chip_data **)res; | ||
| 680 | |||
| 681 | regmap_del_irq_chip(d->irq, d); | ||
| 682 | } | ||
| 683 | |||
| 684 | static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data) | ||
| 685 | |||
| 686 | { | ||
| 687 | struct regmap_irq_chip_data **r = res; | ||
| 688 | |||
| 689 | if (!r || !*r) { | ||
| 690 | WARN_ON(!r || !*r); | ||
| 691 | return 0; | ||
| 692 | } | ||
| 693 | return *r == data; | ||
| 694 | } | ||
| 695 | |||
| 696 | /** | ||
| 697 | * devm_regmap_add_irq_chip(): Resource manager regmap_add_irq_chip() | ||
| 698 | * | ||
| 699 | * @dev: The device pointer on which irq_chip belongs to. | ||
| 700 | * @map: The regmap for the device. | ||
| 701 | * @irq: The IRQ the device uses to signal interrupts | ||
| 702 | * @irq_flags: The IRQF_ flags to use for the primary interrupt. | ||
| 703 | * @chip: Configuration for the interrupt controller. | ||
| 704 | * @data: Runtime data structure for the controller, allocated on success | ||
| 705 | * | ||
| 706 | * Returns 0 on success or an errno on failure. | ||
| 707 | * | ||
| 708 | * The regmap_irq_chip data automatically be released when the device is | ||
| 709 | * unbound. | ||
| 710 | */ | ||
| 711 | int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, | ||
| 712 | int irq_flags, int irq_base, | ||
| 713 | const struct regmap_irq_chip *chip, | ||
| 714 | struct regmap_irq_chip_data **data) | ||
| 715 | { | ||
| 716 | struct regmap_irq_chip_data **ptr, *d; | ||
| 717 | int ret; | ||
| 718 | |||
| 719 | ptr = devres_alloc(devm_regmap_irq_chip_release, sizeof(*ptr), | ||
| 720 | GFP_KERNEL); | ||
| 721 | if (!ptr) | ||
| 722 | return -ENOMEM; | ||
| 723 | |||
| 724 | ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base, | ||
| 725 | chip, &d); | ||
| 726 | if (ret < 0) { | ||
| 727 | devres_free(ptr); | ||
| 728 | return ret; | ||
| 729 | } | ||
| 730 | |||
| 731 | *ptr = d; | ||
| 732 | devres_add(dev, ptr); | ||
| 733 | *data = d; | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip); | ||
| 737 | |||
| 738 | /** | ||
| 739 | * devm_regmap_del_irq_chip(): Resource managed regmap_del_irq_chip() | ||
| 740 | * | ||
| 741 | * @dev: Device for which which resource was allocated. | ||
| 742 | * @irq: Primary IRQ for the device | ||
| 743 | * @d: regmap_irq_chip_data allocated by regmap_add_irq_chip() | ||
| 744 | */ | ||
| 745 | void devm_regmap_del_irq_chip(struct device *dev, int irq, | ||
| 746 | struct regmap_irq_chip_data *data) | ||
| 747 | { | ||
| 748 | int rc; | ||
| 749 | |||
| 750 | WARN_ON(irq != data->irq); | ||
| 751 | rc = devres_release(dev, devm_regmap_irq_chip_release, | ||
| 752 | devm_regmap_irq_chip_match, data); | ||
| 753 | |||
| 754 | if (rc != 0) | ||
| 755 | WARN_ON(rc); | ||
| 756 | } | ||
| 757 | EXPORT_SYMBOL_GPL(devm_regmap_del_irq_chip); | ||
| 758 | |||
| 677 | /** | 759 | /** |
| 678 | * regmap_irq_chip_get_base(): Retrieve interrupt base for a regmap IRQ chip | 760 | * regmap_irq_chip_get_base(): Retrieve interrupt base for a regmap IRQ chip |
| 679 | * | 761 | * |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 18394343f489..de428962bfe6 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
| @@ -868,6 +868,14 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, | |||
| 868 | int irq_base, const struct regmap_irq_chip *chip, | 868 | int irq_base, const struct regmap_irq_chip *chip, |
| 869 | struct regmap_irq_chip_data **data); | 869 | struct regmap_irq_chip_data **data); |
| 870 | void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); | 870 | void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); |
| 871 | |||
| 872 | int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, | ||
| 873 | int irq_flags, int irq_base, | ||
| 874 | const struct regmap_irq_chip *chip, | ||
| 875 | struct regmap_irq_chip_data **data); | ||
| 876 | void devm_regmap_del_irq_chip(struct device *dev, int irq, | ||
| 877 | struct regmap_irq_chip_data *data); | ||
| 878 | |||
| 871 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); | 879 | int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); |
| 872 | int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq); | 880 | int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq); |
| 873 | struct irq_domain *regmap_irq_get_domain(struct regmap_irq_chip_data *data); | 881 | struct irq_domain *regmap_irq_get_domain(struct regmap_irq_chip_data *data); |
