From 43fac3238c1d9363b2a93d8d56c2be0c29c64e6c Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Tue, 30 Oct 2018 18:07:56 +0800 Subject: regmap: add a new macro:REGMAP_IRQ_REG_LINE(_id, _reg_bits) if there are lots of irqs for a device and the register addresses for these irqs is continuous, we can use this macro to initialize regmap_irq value. Signed-off-by: Tony Xie Signed-off-by: Mark Brown --- include/linux/regmap.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index a367d59c301d..3930f3331652 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1110,6 +1110,12 @@ struct regmap_irq { #define REGMAP_IRQ_REG(_irq, _off, _mask) \ [_irq] = { .reg_offset = (_off), .mask = (_mask) } +#define REGMAP_IRQ_REG_LINE(_id, _reg_bits) \ + [_id] = { \ + .mask = BIT((_id) % (_reg_bits)), \ + .reg_offset = (_id) / (_reg_bits), \ + } + /** * struct regmap_irq_chip - Description of a generic regmap irq_chip. * -- cgit v1.2.3 From bc998a730367a69a1449320d321187d7414668fa Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 7 Dec 2018 14:04:52 +0100 Subject: regmap: irq: handle HW using separate rising/falling edge interrupts Some interrupt controllers use separate bits for controlling rising and falling edge interrupts in the mask register i.e. they have one interrupt for rising edge and one for falling. We already handle the case where we have a single interrupt in the mask register and a separate type configuration register. Add a new switch to regmap_irq_chip which tells the framework to use the mask_base address for configuring the edge of the interrupts that define type_falling/rising_mask values. For such interrupts we never update the type_base bits. For interrupts that don't define type masks or their regmap irq chip doesn't set the type_in_mask to true everything stays the same. Signed-off-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- include/linux/regmap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 3930f3331652..c54c778f3051 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1137,6 +1137,9 @@ struct regmap_irq { * @ack_invert: Inverted ack register: cleared bits for ack. * @wake_invert: Inverted wake register: cleared bits are wake enabled. * @type_invert: Invert the type flags. + * @type_in_mask: Use the mask registers for controlling irq type. For + * interrupts defining type_rising/falling_mask use mask_base + * for edge configuration and never update bits in type_base. * @runtime_pm: Hold a runtime PM lock on the device when accessing it. * * @num_regs: Number of registers in each control bank. @@ -1175,6 +1178,7 @@ struct regmap_irq_chip { bool wake_invert:1; bool runtime_pm:1; bool type_invert:1; + bool type_in_mask:1; int num_regs; -- cgit v1.2.3 From 1c2928e3e3212252b505b746ec10951027a95813 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Tue, 18 Dec 2018 13:59:31 +0200 Subject: regmap: regmap-irq/gpio-max77620: add level-irq support Add level active IRQ support to regmap-irq irqchip. Change breaks existing regmap-irq type setting. Convert the existing drivers which use regmap-irq with trigger type setting (gpio-max77620) to work with this new approach. So we do not magically support level-active IRQs on gpio-max77620 - but add support to the regmap-irq for chips which support them =) We do not support distinguishing situation where HW supports rising and falling edge detection but not both. Separating this would require inventing yet another flags for IRQ types. Signed-off-by: Matti Vaittinen Signed-off-by: Mark Brown --- include/linux/regmap.h | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index c54c778f3051..0f1832e4c2c8 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1089,22 +1089,37 @@ int regmap_fields_read(struct regmap_field *field, unsigned int id, int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, unsigned int mask, unsigned int val, bool *change, bool async, bool force); +/** + * struct regmap_irq_type - IRQ type definitions. + * + * @type_reg_offset: Offset register for the irq type setting. + * @type_rising_val: Register value to configure RISING type irq. + * @type_falling_val: Register value to configure FALLING type irq. + * @type_level_low_val: Register value to configure LEVEL_LOW type irq. + * @type_level_high_val: Register value to configure LEVEL_HIGH type irq. + * @types_supported: logical OR of IRQ_TYPE_* flags indicating supported types. + */ +struct regmap_irq_type { + unsigned int type_reg_offset; + unsigned int type_reg_mask; + unsigned int type_rising_val; + unsigned int type_falling_val; + unsigned int type_level_low_val; + unsigned int type_level_high_val; + unsigned int types_supported; +}; /** * struct regmap_irq - Description of an IRQ for the generic regmap irq_chip. * * @reg_offset: Offset of the status/mask register within the bank * @mask: Mask used to flag/control the register. - * @type_reg_offset: Offset register for the irq type setting. - * @type_rising_mask: Mask bit to configure RISING type irq. - * @type_falling_mask: Mask bit to configure FALLING type irq. + * @type: IRQ trigger type setting details if supported. */ struct regmap_irq { unsigned int reg_offset; unsigned int mask; - unsigned int type_reg_offset; - unsigned int type_rising_mask; - unsigned int type_falling_mask; + struct regmap_irq_type type; }; #define REGMAP_IRQ_REG(_irq, _off, _mask) \ -- cgit v1.2.3 From c82ea33ead18801605b236523f21e5c893c7c253 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 19 Dec 2018 12:18:05 +0100 Subject: regmap: irq: add an option to clear status registers on unmask Some interrupt controllers whose interrupts are acked on read will set the status bits for masked interrupts without changing the state of the IRQ line. Some chips have an additional "feature" where if those set bits are not cleared before unmasking their respective interrupts, the IRQ line will change the state and we'll interpret this as an interrupt although it actually fired when it was masked. Add a new field to the irq chip struct that tells the regmap irq chip code to always clear the status registers before actually changing the irq mask values. Signed-off-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- include/linux/regmap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 0f1832e4c2c8..1781b6cb793c 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1155,6 +1155,9 @@ struct regmap_irq { * @type_in_mask: Use the mask registers for controlling irq type. For * interrupts defining type_rising/falling_mask use mask_base * for edge configuration and never update bits in type_base. + * @clear_on_unmask: For chips with interrupts cleared on read: read the status + * registers before unmasking interrupts to clear any bits + * set when they were masked. * @runtime_pm: Hold a runtime PM lock on the device when accessing it. * * @num_regs: Number of registers in each control bank. @@ -1194,6 +1197,7 @@ struct regmap_irq_chip { bool runtime_pm:1; bool type_invert:1; bool type_in_mask:1; + bool clear_on_unmask:1; int num_regs; -- cgit v1.2.3