summaryrefslogtreecommitdiff
path: root/drivers/irqchip/irq-dw-apb-ictl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 19:38:57 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 19:38:57 +0300
commitecb50f0afd35a51ef487e8a54b976052eb03d729 (patch)
tree27457f87d3dc2ce6c81e16d795f953e66c2fff45 /drivers/irqchip/irq-dw-apb-ictl.c
parenta157508c9790ccd1c8b5c6a828d6ba85bbe95aaa (diff)
parent1655b0530d9502e69686220491ffb15ba0738c58 (diff)
downloadlinux-ecb50f0afd35a51ef487e8a54b976052eb03d729.tar.xz
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner: "This is the first (boring) part of irq updates: - support for big endian I/O accessors in the generic irq chip - cleanup of brcmstb/bcm7120 drivers so they can be reused for non ARM SoCs - the usual pile of fixes and updates for the various ARM irq chips" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits) irqchip: dw-apb-ictl: Add PM support irqchip: dw-apb-ictl: Enable IRQ_GC_MASK_CACHE_PER_TYPE irqchip: dw-apb-ictl: Always use use {readl|writel}_relaxed ARM: orion: convert the irq_reg_{readl,writel} calls to the new API irqchip: atmel-aic: Add missing entry for rm9200 irq fixups irqchip: atmel-aic: Rename at91sam9_aic_irq_fixup for naming consistency irqchip: atmel-aic: Add specific irq fixup function for sam9g45 and sam9rl irqchip: atmel-aic: Add irq fixups for at91sam926x SoCs irqchip: atmel-aic: Add irq fixup for RTT block irqchip: brcmstb-l2: Convert driver to use irq_reg_{readl,writel} irqchip: bcm7120-l2: Convert driver to use irq_reg_{readl,writel} irqchip: bcm7120-l2: Decouple driver from brcmstb-l2 irqchip: bcm7120-l2: Extend driver to support 64+ bit controllers irqchip: bcm7120-l2: Use gc->mask_cache to simplify suspend/resume functions irqchip: bcm7120-l2: Fix missing nibble in gc->unused mask irqchip: bcm7120-l2: Make sure all register accesses use base+offset irqchip: bcm7120-l2, brcmstb-l2: Remove ARM Kconfig dependency irqchip: bcm7120-l2: Eliminate bad IRQ check irqchip: brcmstb-l2: Eliminate dependency on ARM code genirq: Generic chip: Add big endian I/O accessors ...
Diffstat (limited to 'drivers/irqchip/irq-dw-apb-ictl.c')
-rw-r--r--drivers/irqchip/irq-dw-apb-ictl.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c
index 31e231e1f566..53bb7326a60a 100644
--- a/drivers/irqchip/irq-dw-apb-ictl.c
+++ b/drivers/irqchip/irq-dw-apb-ictl.c
@@ -50,6 +50,21 @@ static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+#ifdef CONFIG_PM
+static void dw_apb_ictl_resume(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+
+ irq_gc_lock(gc);
+ writel_relaxed(~0, gc->reg_base + ct->regs.enable);
+ writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
+ irq_gc_unlock(gc);
+}
+#else
+#define dw_apb_ictl_resume NULL
+#endif /* CONFIG_PM */
+
static int __init dw_apb_ictl_init(struct device_node *np,
struct device_node *parent)
{
@@ -94,16 +109,16 @@ static int __init dw_apb_ictl_init(struct device_node *np,
*/
/* mask and enable all interrupts */
- writel(~0, iobase + APB_INT_MASK_L);
- writel(~0, iobase + APB_INT_MASK_H);
- writel(~0, iobase + APB_INT_ENABLE_L);
- writel(~0, iobase + APB_INT_ENABLE_H);
+ writel_relaxed(~0, iobase + APB_INT_MASK_L);
+ writel_relaxed(~0, iobase + APB_INT_MASK_H);
+ writel_relaxed(~0, iobase + APB_INT_ENABLE_L);
+ writel_relaxed(~0, iobase + APB_INT_ENABLE_H);
- reg = readl(iobase + APB_INT_ENABLE_H);
+ reg = readl_relaxed(iobase + APB_INT_ENABLE_H);
if (reg)
nrirqs = 32 + fls(reg);
else
- nrirqs = fls(readl(iobase + APB_INT_ENABLE_L));
+ nrirqs = fls(readl_relaxed(iobase + APB_INT_ENABLE_L));
domain = irq_domain_add_linear(np, nrirqs,
&irq_generic_chip_ops, NULL);
@@ -115,6 +130,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1,
np->name, handle_level_irq, clr, 0,
+ IRQ_GC_MASK_CACHE_PER_TYPE |
IRQ_GC_INIT_MASK_CACHE);
if (ret) {
pr_err("%s: unable to alloc irq domain gc\n", np->full_name);
@@ -126,13 +142,17 @@ static int __init dw_apb_ictl_init(struct device_node *np,
gc->reg_base = iobase;
gc->chip_types[0].regs.mask = APB_INT_MASK_L;
+ gc->chip_types[0].regs.enable = APB_INT_ENABLE_L;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
+ gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume;
if (nrirqs > 32) {
gc->chip_types[1].regs.mask = APB_INT_MASK_H;
+ gc->chip_types[1].regs.enable = APB_INT_ENABLE_H;
gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit;
gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit;
+ gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume;
}
irq_set_handler_data(irq, gc);