diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2017-02-10 14:44:01 +0100 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2017-02-10 14:44:01 +0100 | 
| commit | d128dfb514f55af040c38a6b3b131d72b6f115d0 (patch) | |
| tree | c53755d2aa94bd71ca89008c2aaea8a39c24f24e | |
| parent | 3d88460dbd285e7f32437b530d5bb7cb916142fa (diff) | |
| parent | 88e20c74ee020f9e0c99dfce0dd9aa61c3f0cca0 (diff) | |
Merge tag 'irqchip-fixes-4.10' of git://git.infradead.org/users/jcooper/linux into irq/urgent
Pull irqchip fixes for v4.10 from Jason Cooper
- keystone: Fix scheduling while atomic for realtime
- mxs: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND
| -rw-r--r-- | drivers/irqchip/irq-keystone.c | 28 | ||||
| -rw-r--r-- | drivers/irqchip/irq-mxs.c | 4 | 
2 files changed, 23 insertions, 9 deletions
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 54a5e870a8f5..efbcf8435185 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -19,9 +19,9 @@  #include <linux/bitops.h>  #include <linux/module.h>  #include <linux/moduleparam.h> +#include <linux/interrupt.h>  #include <linux/irqdomain.h>  #include <linux/irqchip.h> -#include <linux/irqchip/chained_irq.h>  #include <linux/of.h>  #include <linux/of_platform.h>  #include <linux/mfd/syscon.h> @@ -39,6 +39,7 @@ struct keystone_irq_device {  	struct irq_domain	*irqd;  	struct regmap		*devctrl_regs;  	u32			devctrl_offset; +	raw_spinlock_t		wa_lock;  };  static inline u32 keystone_irq_readl(struct keystone_irq_device *kirq) @@ -83,17 +84,15 @@ static void keystone_irq_ack(struct irq_data *d)  	/* nothing to do here */  } -static void keystone_irq_handler(struct irq_desc *desc) +static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)  { -	unsigned int irq = irq_desc_get_irq(desc); -	struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); +	struct keystone_irq_device *kirq = keystone_irq; +	unsigned long wa_lock_flags;  	unsigned long pending;  	int src, virq;  	dev_dbg(kirq->dev, "start irq %d\n", irq); -	chained_irq_enter(irq_desc_get_chip(desc), desc); -  	pending = keystone_irq_readl(kirq);  	keystone_irq_writel(kirq, pending); @@ -111,13 +110,15 @@ static void keystone_irq_handler(struct irq_desc *desc)  			if (!virq)  				dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n",  					 src, virq); +			raw_spin_lock_irqsave(&kirq->wa_lock, wa_lock_flags);  			generic_handle_irq(virq); +			raw_spin_unlock_irqrestore(&kirq->wa_lock, +						   wa_lock_flags);  		}  	} -	chained_irq_exit(irq_desc_get_chip(desc), desc); -  	dev_dbg(kirq->dev, "end irq %d\n", irq); +	return IRQ_HANDLED;  }  static int keystone_irq_map(struct irq_domain *h, unsigned int virq, @@ -182,9 +183,16 @@ static int keystone_irq_probe(struct platform_device *pdev)  		return -ENODEV;  	} +	raw_spin_lock_init(&kirq->wa_lock); +  	platform_set_drvdata(pdev, kirq); -	irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq); +	ret = request_irq(kirq->irq, keystone_irq_handler, +			  0, dev_name(dev), kirq); +	if (ret) { +		irq_domain_remove(kirq->irqd); +		return ret; +	}  	/* clear all source bits */  	keystone_irq_writel(kirq, ~0x0); @@ -199,6 +207,8 @@ static int keystone_irq_remove(struct platform_device *pdev)  	struct keystone_irq_device *kirq = platform_get_drvdata(pdev);  	int hwirq; +	free_irq(kirq->irq, kirq); +  	for (hwirq = 0; hwirq < KEYSTONE_N_IRQ; hwirq++)  		irq_dispose_mapping(irq_find_mapping(kirq->irqd, hwirq)); diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 17304705f2cf..05fa9f7af53c 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -131,12 +131,16 @@ static struct irq_chip mxs_icoll_chip = {  	.irq_ack = icoll_ack_irq,  	.irq_mask = icoll_mask_irq,  	.irq_unmask = icoll_unmask_irq, +	.flags = IRQCHIP_MASK_ON_SUSPEND | +		 IRQCHIP_SKIP_SET_WAKE,  };  static struct irq_chip asm9260_icoll_chip = {  	.irq_ack = icoll_ack_irq,  	.irq_mask = asm9260_mask_irq,  	.irq_unmask = asm9260_unmask_irq, +	.flags = IRQCHIP_MASK_ON_SUSPEND | +		 IRQCHIP_SKIP_SET_WAKE,  };  asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)  | 
