diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2011-02-10 13:16:14 +0100 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-19 12:58:22 +0100 | 
| commit | d4d5e08960844a062da8387ee5f16ca7a33200d0 (patch) | |
| tree | 1154fd87e25595ae9391740a1d9a3d60f69770de /kernel | |
| parent | 2bff17ad2107c66fc8ca96501a7128dd7fa7a390 (diff) | |
| download | olio-linux-3.10-d4d5e08960844a062da8387ee5f16ca7a33200d0.tar.xz olio-linux-3.10-d4d5e08960844a062da8387ee5f16ca7a33200d0.zip  | |
genirq: Add IRQCHIP_SET_TYPE_MASKED flag
irq_chips, which require to mask the chip before changing the trigger
type should set this flag. So the core takes care of it and the
requirement for looking into desc->status in the chip goes away.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/irq/chip.c | 4 | ||||
| -rw-r--r-- | kernel/irq/internals.h | 2 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 16 | 
3 files changed, 17 insertions, 5 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9e9220da4de..4687457fe7f 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -367,7 +367,7 @@ static inline void mask_ack_irq(struct irq_desc *desc)  	irq_state_set_masked(desc);  } -static inline void mask_irq(struct irq_desc *desc) +void mask_irq(struct irq_desc *desc)  {  	if (desc->irq_data.chip->irq_mask) {  		desc->irq_data.chip->irq_mask(&desc->irq_data); @@ -375,7 +375,7 @@ static inline void mask_irq(struct irq_desc *desc)  	}  } -static inline void unmask_irq(struct irq_desc *desc) +void unmask_irq(struct irq_desc *desc)  {  	if (desc->irq_data.chip->irq_unmask) {  		desc->irq_data.chip->irq_unmask(&desc->irq_data); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 6776453c454..1d500fbde0d 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -84,6 +84,8 @@ extern int irq_startup(struct irq_desc *desc);  extern void irq_shutdown(struct irq_desc *desc);  extern void irq_enable(struct irq_desc *desc);  extern void irq_disable(struct irq_desc *desc); +extern void mask_irq(struct irq_desc *desc); +extern void unmask_irq(struct irq_desc *desc);  extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index b5de828e58d..50809c79c7a 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -554,8 +554,8 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc)  int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,  		      unsigned long flags)  { -	int ret;  	struct irq_chip *chip = desc->irq_data.chip; +	int ret, unmask = 0;  	if (!chip || !chip->irq_set_type) {  		/* @@ -568,6 +568,14 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,  	}  	flags &= IRQ_TYPE_SENSE_MASK; + +	if (chip->flags & IRQCHIP_SET_TYPE_MASKED) { +		if (!(desc->istate & IRQS_MASKED)) +			mask_irq(desc); +		if (!(desc->istate & IRQS_DISABLED)) +			unmask = 1; +	} +  	/* caller masked out all except trigger mode flags */  	ret = chip->irq_set_type(&desc->irq_data, flags); @@ -588,11 +596,13 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,  		if (chip != desc->irq_data.chip)  			irq_chip_set_defaults(desc->irq_data.chip); -		return 0; +		ret = 0;  	default:  		pr_err("setting trigger mode %lu for irq %u failed (%pF)\n",  		       flags, irq, chip->irq_set_type);  	} +	if (unmask) +		unmask_irq(desc);  	return ret;  } @@ -669,7 +679,7 @@ again:  #ifdef CONFIG_SMP  /* - * Check whether we need to change the affinity of the interrupt thread. + * Check whether we need to chasnge the affinity of the interrupt thread.   */  static void  irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)  |