FROMLIST: genirq: Add __irq_modify_status() helper to clear/set special flags

Some arch-specific flags need to be set/cleared, but not exposed to
random device drivers. Introduce a new helper (__irq_modify_status())
that takes an arbitrary mask, and rewrite irq_modify_status() to use
this new helper.

No functionnal change.

Bug: 191808738
Link: https://lore.kernel.org/lkml/20201124141449.572446-5-maz@kernel.org/
Change-Id: I2c2c0d6599d0ab39fad22462bf4c87694362fba8
Signed-off-by: Marc Zyngier <maz@kernel.org>
[minor port to 5.10]
Signed-off-by: Stephen Dickey <dickey@codeaurora.org>
This commit is contained in:
Marc Zyngier
2020-11-17 14:37:59 +00:00
committed by Todd Kjos
parent 77c9f446b6
commit 08327b9007
3 changed files with 21 additions and 4 deletions

View File

@@ -751,6 +751,9 @@ void
irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
void *data); void *data);
void __irq_modify_status(unsigned int irq, unsigned long clr,
unsigned long set, unsigned long mask);
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
static inline void irq_set_status_flags(unsigned int irq, unsigned long set) static inline void irq_set_status_flags(unsigned int irq, unsigned long set)

View File

@@ -1122,7 +1122,8 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
} }
EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name);
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) void __irq_modify_status(unsigned int irq, unsigned long clr,
unsigned long set, unsigned long mask)
{ {
unsigned long flags, trigger, tmp; unsigned long flags, trigger, tmp;
struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
@@ -1136,7 +1137,9 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
*/ */
WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN)); WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
irq_settings_clr_and_set(desc, clr, set); /* Warn when trying to clear or set a bit disallowed by the mask */
WARN_ON((clr | set) & ~mask);
__irq_settings_clr_and_set(desc, clr, set, mask);
trigger = irqd_get_trigger_type(&desc->irq_data); trigger = irqd_get_trigger_type(&desc->irq_data);
@@ -1159,6 +1162,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
irq_put_desc_unlock(desc, flags); irq_put_desc_unlock(desc, flags);
} }
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
{
__irq_modify_status(irq, clr, set, _IRQF_MODIFY_MASK);
}
EXPORT_SYMBOL_GPL(irq_modify_status); EXPORT_SYMBOL_GPL(irq_modify_status);
/** /**

View File

@@ -36,11 +36,17 @@ enum {
#undef IRQF_MODIFY_MASK #undef IRQF_MODIFY_MASK
#define IRQF_MODIFY_MASK GOT_YOU_MORON #define IRQF_MODIFY_MASK GOT_YOU_MORON
static inline void
__irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set, u32 mask)
{
desc->status_use_accessors &= ~(clr & mask);
desc->status_use_accessors |= (set & mask);
}
static inline void static inline void
irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set)
{ {
desc->status_use_accessors &= ~(clr & _IRQF_MODIFY_MASK); __irq_settings_clr_and_set(desc, clr, set, _IRQF_MODIFY_MASK);
desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK);
} }
static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) static inline bool irq_settings_is_per_cpu(struct irq_desc *desc)