summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 11:38:57 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 11:38:57 -0500
commitecb50f0afd35a51ef487e8a54b976052eb03d729 (patch)
tree27457f87d3dc2ce6c81e16d795f953e66c2fff45
parenta157508c9790ccd1c8b5c6a828d6ba85bbe95aaa (diff)
parent1655b0530d9502e69686220491ffb15ba0738c58 (diff)
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 ...
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt26
-rw-r--r--arch/arm/mach-bcm/Kconfig1
-rw-r--r--arch/arm/plat-orion/gpio.c8
-rw-r--r--drivers/irqchip/Kconfig7
-rw-r--r--drivers/irqchip/Makefile4
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c2
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.c26
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.h2
-rw-r--r--drivers/irqchip/irq-atmel-aic.c66
-rw-r--r--drivers/irqchip/irq-atmel-aic5.c65
-rw-r--r--drivers/irqchip/irq-bcm7120-l2.c174
-rw-r--r--drivers/irqchip/irq-brcmstb-l2.c41
-rw-r--r--drivers/irqchip/irq-dw-apb-ictl.c32
-rw-r--r--drivers/irqchip/irq-hip04.c3
-rw-r--r--drivers/irqchip/irq-sunxi-nmi.c4
-rw-r--r--drivers/irqchip/irq-tb10x.c4
-rw-r--r--include/linux/irq.h32
-rw-r--r--kernel/irq/generic-chip.c36
18 files changed, 345 insertions, 188 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
index ff812a8a82bc..bae1f2187226 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
@@ -13,7 +13,12 @@ Such an interrupt controller has the following hardware design:
13 or if they will output an interrupt signal at this 2nd level interrupt 13 or if they will output an interrupt signal at this 2nd level interrupt
14 controller, in particular for UARTs 14 controller, in particular for UARTs
15 15
16- not all 32-bits within the interrupt controller actually map to an interrupt 16- typically has one 32-bit enable word and one 32-bit status word, but on
17 some hardware may have more than one enable/status pair
18
19- no atomic set/clear operations
20
21- not all bits within the interrupt controller actually map to an interrupt
17 22
18The typical hardware layout for this controller is represented below: 23The typical hardware layout for this controller is represented below:
19 24
@@ -48,7 +53,9 @@ The typical hardware layout for this controller is represented below:
48Required properties: 53Required properties:
49 54
50- compatible: should be "brcm,bcm7120-l2-intc" 55- compatible: should be "brcm,bcm7120-l2-intc"
51- reg: specifies the base physical address and size of the registers 56- reg: specifies the base physical address and size of the registers;
57 multiple pairs may be specified, with the first pair handling IRQ offsets
58 0..31 and the second pair handling 32..63
52- interrupt-controller: identifies the node as an interrupt controller 59- interrupt-controller: identifies the node as an interrupt controller
53- #interrupt-cells: specifies the number of cells needed to encode an interrupt 60- #interrupt-cells: specifies the number of cells needed to encode an interrupt
54 source, should be 1. 61 source, should be 1.
@@ -59,18 +66,21 @@ Required properties:
59- brcm,int-map-mask: 32-bits bit mask describing how many and which interrupts 66- brcm,int-map-mask: 32-bits bit mask describing how many and which interrupts
60 are wired to this 2nd level interrupt controller, and how they match their 67 are wired to this 2nd level interrupt controller, and how they match their
61 respective interrupt parents. Should match exactly the number of interrupts 68 respective interrupt parents. Should match exactly the number of interrupts
62 specified in the 'interrupts' property. 69 specified in the 'interrupts' property, multiplied by the number of
70 enable/status register pairs implemented by this controller. For
71 multiple parent IRQs with multiple enable/status words, this looks like:
72 <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
63 73
64Optional properties: 74Optional properties:
65 75
66- brcm,irq-can-wake: if present, this means the L2 controller can be used as a 76- brcm,irq-can-wake: if present, this means the L2 controller can be used as a
67 wakeup source for system suspend/resume. 77 wakeup source for system suspend/resume.
68 78
69- brcm,int-fwd-mask: if present, a 32-bits bit mask to configure for the 79- brcm,int-fwd-mask: if present, a bit mask to configure the interrupts which
70 interrupts which have a mux gate, typically UARTs. Setting these bits will 80 have a mux gate, typically UARTs. Setting these bits will make their
71 make their respective interrupts outputs bypass this 2nd level interrupt 81 respective interrupt outputs bypass this 2nd level interrupt controller
72 controller completely, it completely transparent for the interrupt controller 82 completely; it is completely transparent for the interrupt controller
73 parent 83 parent. This should have one 32-bit word per enable/status pair.
74 84
75Example: 85Example:
76 86
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 1bd39b45d08b..aaeec78c3ec4 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -143,6 +143,7 @@ config ARCH_BRCMSTB
143 select HAVE_ARM_ARCH_TIMER 143 select HAVE_ARM_ARCH_TIMER
144 select BRCMSTB_GISB_ARB 144 select BRCMSTB_GISB_ARB
145 select BRCMSTB_L2_IRQ 145 select BRCMSTB_L2_IRQ
146 select BCM7120_L2_IRQ
146 help 147 help
147 Say Y if you intend to run the kernel on a Broadcom ARM-based STB 148 Say Y if you intend to run the kernel on a Broadcom ARM-based STB
148 chipset. 149 chipset.
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index e048f6198d68..14f6e647c739 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -505,9 +505,9 @@ static void orion_gpio_unmask_irq(struct irq_data *d)
505 u32 mask = d->mask; 505 u32 mask = d->mask;
506 506
507 irq_gc_lock(gc); 507 irq_gc_lock(gc);
508 reg_val = irq_reg_readl(gc->reg_base + ct->regs.mask); 508 reg_val = irq_reg_readl(gc, ct->regs.mask);
509 reg_val |= mask; 509 reg_val |= mask;
510 irq_reg_writel(reg_val, gc->reg_base + ct->regs.mask); 510 irq_reg_writel(gc, reg_val, ct->regs.mask);
511 irq_gc_unlock(gc); 511 irq_gc_unlock(gc);
512} 512}
513 513
@@ -519,9 +519,9 @@ static void orion_gpio_mask_irq(struct irq_data *d)
519 u32 reg_val; 519 u32 reg_val;
520 520
521 irq_gc_lock(gc); 521 irq_gc_lock(gc);
522 reg_val = irq_reg_readl(gc->reg_base + ct->regs.mask); 522 reg_val = irq_reg_readl(gc, ct->regs.mask);
523 reg_val &= ~mask; 523 reg_val &= ~mask;
524 irq_reg_writel(reg_val, gc->reg_base + ct->regs.mask); 524 irq_reg_writel(gc, reg_val, ct->regs.mask);
525 irq_gc_unlock(gc); 525 irq_gc_unlock(gc);
526} 526}
527 527
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b21f12f1766d..9efe5f10f97b 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -48,14 +48,19 @@ config ATMEL_AIC5_IRQ
48 select MULTI_IRQ_HANDLER 48 select MULTI_IRQ_HANDLER
49 select SPARSE_IRQ 49 select SPARSE_IRQ
50 50
51config BCM7120_L2_IRQ
52 bool
53 select GENERIC_IRQ_CHIP
54 select IRQ_DOMAIN
55
51config BRCMSTB_L2_IRQ 56config BRCMSTB_L2_IRQ
52 bool 57 bool
53 depends on ARM
54 select GENERIC_IRQ_CHIP 58 select GENERIC_IRQ_CHIP
55 select IRQ_DOMAIN 59 select IRQ_DOMAIN
56 60
57config DW_APB_ICTL 61config DW_APB_ICTL
58 bool 62 bool
63 select GENERIC_IRQ_CHIP
59 select IRQ_DOMAIN 64 select IRQ_DOMAIN
60 65
61config IMGPDC_IRQ 66config IMGPDC_IRQ
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 173bb5fa2cc9..f0909d05eae3 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -35,6 +35,6 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
35obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o 35obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
36obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o 36obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
37obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o 37obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
38obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o \ 38obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
39 irq-bcm7120-l2.o 39obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
40obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o 40obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index b907550ae9a5..a3fd2b37ddb6 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -268,7 +268,7 @@ static int armada_xp_set_affinity(struct irq_data *d,
268 writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq)); 268 writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
269 raw_spin_unlock(&irq_controller_lock); 269 raw_spin_unlock(&irq_controller_lock);
270 270
271 return 0; 271 return IRQ_SET_MASK_OK;
272} 272}
273#endif 273#endif
274 274
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
index cc4f9d80122e..d111ac779c40 100644
--- a/drivers/irqchip/irq-atmel-aic-common.c
+++ b/drivers/irqchip/irq-atmel-aic-common.c
@@ -167,6 +167,32 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root)
167 iounmap(regs); 167 iounmap(regs);
168} 168}
169 169
170#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
171#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
172#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
173
174void __init aic_common_rtt_irq_fixup(struct device_node *root)
175{
176 struct device_node *np;
177 void __iomem *regs;
178
179 /*
180 * The at91sam9263 SoC has 2 instances of the RTT block, hence we
181 * iterate over the DT to find each occurrence.
182 */
183 for_each_compatible_node(np, NULL, "atmel,at91sam9260-rtt") {
184 regs = of_iomap(np, 0);
185 if (!regs)
186 continue;
187
188 writel(readl(regs + AT91_RTT_MR) &
189 ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN),
190 regs + AT91_RTT_MR);
191
192 iounmap(regs);
193 }
194}
195
170void __init aic_common_irq_fixup(const struct of_device_id *matches) 196void __init aic_common_irq_fixup(const struct of_device_id *matches)
171{ 197{
172 struct device_node *root = of_find_node_by_path("/"); 198 struct device_node *root = of_find_node_by_path("/");
diff --git a/drivers/irqchip/irq-atmel-aic-common.h b/drivers/irqchip/irq-atmel-aic-common.h
index 90aa00e918d6..603f0a9d5411 100644
--- a/drivers/irqchip/irq-atmel-aic-common.h
+++ b/drivers/irqchip/irq-atmel-aic-common.h
@@ -34,6 +34,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
34 34
35void __init aic_common_rtc_irq_fixup(struct device_node *root); 35void __init aic_common_rtc_irq_fixup(struct device_node *root);
36 36
37void __init aic_common_rtt_irq_fixup(struct device_node *root);
38
37void __init aic_common_irq_fixup(const struct of_device_id *matches); 39void __init aic_common_irq_fixup(const struct of_device_id *matches);
38 40
39#endif /* __IRQ_ATMEL_AIC_COMMON_H */ 41#endif /* __IRQ_ATMEL_AIC_COMMON_H */
diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c
index 9a2cf3c1a3a5..dae3604b32a9 100644
--- a/drivers/irqchip/irq-atmel-aic.c
+++ b/drivers/irqchip/irq-atmel-aic.c
@@ -65,11 +65,11 @@ aic_handle(struct pt_regs *regs)
65 u32 irqnr; 65 u32 irqnr;
66 u32 irqstat; 66 u32 irqstat;
67 67
68 irqnr = irq_reg_readl(gc->reg_base + AT91_AIC_IVR); 68 irqnr = irq_reg_readl(gc, AT91_AIC_IVR);
69 irqstat = irq_reg_readl(gc->reg_base + AT91_AIC_ISR); 69 irqstat = irq_reg_readl(gc, AT91_AIC_ISR);
70 70
71 if (!irqstat) 71 if (!irqstat)
72 irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR); 72 irq_reg_writel(gc, 0, AT91_AIC_EOICR);
73 else 73 else
74 handle_domain_irq(aic_domain, irqnr, regs); 74 handle_domain_irq(aic_domain, irqnr, regs);
75} 75}
@@ -80,7 +80,7 @@ static int aic_retrigger(struct irq_data *d)
80 80
81 /* Enable interrupt on AIC5 */ 81 /* Enable interrupt on AIC5 */
82 irq_gc_lock(gc); 82 irq_gc_lock(gc);
83 irq_reg_writel(d->mask, gc->reg_base + AT91_AIC_ISCR); 83 irq_reg_writel(gc, d->mask, AT91_AIC_ISCR);
84 irq_gc_unlock(gc); 84 irq_gc_unlock(gc);
85 85
86 return 0; 86 return 0;
@@ -92,12 +92,12 @@ static int aic_set_type(struct irq_data *d, unsigned type)
92 unsigned int smr; 92 unsigned int smr;
93 int ret; 93 int ret;
94 94
95 smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(d->hwirq)); 95 smr = irq_reg_readl(gc, AT91_AIC_SMR(d->hwirq));
96 ret = aic_common_set_type(d, type, &smr); 96 ret = aic_common_set_type(d, type, &smr);
97 if (ret) 97 if (ret)
98 return ret; 98 return ret;
99 99
100 irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(d->hwirq)); 100 irq_reg_writel(gc, smr, AT91_AIC_SMR(d->hwirq));
101 101
102 return 0; 102 return 0;
103} 103}
@@ -108,8 +108,8 @@ static void aic_suspend(struct irq_data *d)
108 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 108 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
109 109
110 irq_gc_lock(gc); 110 irq_gc_lock(gc);
111 irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IDCR); 111 irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IDCR);
112 irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IECR); 112 irq_reg_writel(gc, gc->wake_active, AT91_AIC_IECR);
113 irq_gc_unlock(gc); 113 irq_gc_unlock(gc);
114} 114}
115 115
@@ -118,8 +118,8 @@ static void aic_resume(struct irq_data *d)
118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
119 119
120 irq_gc_lock(gc); 120 irq_gc_lock(gc);
121 irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IDCR); 121 irq_reg_writel(gc, gc->wake_active, AT91_AIC_IDCR);
122 irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IECR); 122 irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IECR);
123 irq_gc_unlock(gc); 123 irq_gc_unlock(gc);
124} 124}
125 125
@@ -128,8 +128,8 @@ static void aic_pm_shutdown(struct irq_data *d)
128 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 128 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
129 129
130 irq_gc_lock(gc); 130 irq_gc_lock(gc);
131 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR); 131 irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
132 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR); 132 irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
133 irq_gc_unlock(gc); 133 irq_gc_unlock(gc);
134} 134}
135#else 135#else
@@ -148,24 +148,24 @@ static void __init aic_hw_init(struct irq_domain *domain)
148 * will not Lock out nIRQ 148 * will not Lock out nIRQ
149 */ 149 */
150 for (i = 0; i < 8; i++) 150 for (i = 0; i < 8; i++)
151 irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR); 151 irq_reg_writel(gc, 0, AT91_AIC_EOICR);
152 152
153 /* 153 /*
154 * Spurious Interrupt ID in Spurious Vector Register. 154 * Spurious Interrupt ID in Spurious Vector Register.
155 * When there is no current interrupt, the IRQ Vector Register 155 * When there is no current interrupt, the IRQ Vector Register
156 * reads the value stored in AIC_SPU 156 * reads the value stored in AIC_SPU
157 */ 157 */
158 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_SPU); 158 irq_reg_writel(gc, 0xffffffff, AT91_AIC_SPU);
159 159
160 /* No debugging in AIC: Debug (Protect) Control Register */ 160 /* No debugging in AIC: Debug (Protect) Control Register */
161 irq_reg_writel(0, gc->reg_base + AT91_AIC_DCR); 161 irq_reg_writel(gc, 0, AT91_AIC_DCR);
162 162
163 /* Disable and clear all interrupts initially */ 163 /* Disable and clear all interrupts initially */
164 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR); 164 irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
165 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR); 165 irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
166 166
167 for (i = 0; i < 32; i++) 167 for (i = 0; i < 32; i++)
168 irq_reg_writel(i, gc->reg_base + AT91_AIC_SVR(i)); 168 irq_reg_writel(gc, i, AT91_AIC_SVR(i));
169} 169}
170 170
171static int aic_irq_domain_xlate(struct irq_domain *d, 171static int aic_irq_domain_xlate(struct irq_domain *d,
@@ -195,10 +195,10 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
195 gc = dgc->gc[idx]; 195 gc = dgc->gc[idx];
196 196
197 irq_gc_lock(gc); 197 irq_gc_lock(gc);
198 smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(*out_hwirq)); 198 smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
199 ret = aic_common_set_priority(intspec[2], &smr); 199 ret = aic_common_set_priority(intspec[2], &smr);
200 if (!ret) 200 if (!ret)
201 irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(*out_hwirq)); 201 irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
202 irq_gc_unlock(gc); 202 irq_gc_unlock(gc);
203 203
204 return ret; 204 return ret;
@@ -209,16 +209,32 @@ static const struct irq_domain_ops aic_irq_ops = {
209 .xlate = aic_irq_domain_xlate, 209 .xlate = aic_irq_domain_xlate,
210}; 210};
211 211
212static void __init at91sam9_aic_irq_fixup(struct device_node *root) 212static void __init at91rm9200_aic_irq_fixup(struct device_node *root)
213{ 213{
214 aic_common_rtc_irq_fixup(root); 214 aic_common_rtc_irq_fixup(root);
215} 215}
216 216
217static void __init at91sam9260_aic_irq_fixup(struct device_node *root)
218{
219 aic_common_rtt_irq_fixup(root);
220}
221
222static void __init at91sam9g45_aic_irq_fixup(struct device_node *root)
223{
224 aic_common_rtc_irq_fixup(root);
225 aic_common_rtt_irq_fixup(root);
226}
227
217static const struct of_device_id __initdata aic_irq_fixups[] = { 228static const struct of_device_id __initdata aic_irq_fixups[] = {
218 { .compatible = "atmel,at91sam9g45", .data = at91sam9_aic_irq_fixup }, 229 { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup },
219 { .compatible = "atmel,at91sam9n12", .data = at91sam9_aic_irq_fixup }, 230 { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup },
220 { .compatible = "atmel,at91sam9rl", .data = at91sam9_aic_irq_fixup }, 231 { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup },
221 { .compatible = "atmel,at91sam9x5", .data = at91sam9_aic_irq_fixup }, 232 { .compatible = "atmel,at91sam9rl", .data = at91sam9g45_aic_irq_fixup },
233 { .compatible = "atmel,at91sam9x5", .data = at91rm9200_aic_irq_fixup },
234 { .compatible = "atmel,at91sam9260", .data = at91sam9260_aic_irq_fixup },
235 { .compatible = "atmel,at91sam9261", .data = at91sam9260_aic_irq_fixup },
236 { .compatible = "atmel,at91sam9263", .data = at91sam9260_aic_irq_fixup },
237 { .compatible = "atmel,at91sam9g20", .data = at91sam9260_aic_irq_fixup },
222 { /* sentinel */ }, 238 { /* sentinel */ },
223}; 239};
224 240
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
index a11aae8fb006..a2e8c3f876cb 100644
--- a/drivers/irqchip/irq-atmel-aic5.c
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -75,11 +75,11 @@ aic5_handle(struct pt_regs *regs)
75 u32 irqnr; 75 u32 irqnr;
76 u32 irqstat; 76 u32 irqstat;
77 77
78 irqnr = irq_reg_readl(gc->reg_base + AT91_AIC5_IVR); 78 irqnr = irq_reg_readl(gc, AT91_AIC5_IVR);
79 irqstat = irq_reg_readl(gc->reg_base + AT91_AIC5_ISR); 79 irqstat = irq_reg_readl(gc, AT91_AIC5_ISR);
80 80
81 if (!irqstat) 81 if (!irqstat)
82 irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR); 82 irq_reg_writel(gc, 0, AT91_AIC5_EOICR);
83 else 83 else
84 handle_domain_irq(aic5_domain, irqnr, regs); 84 handle_domain_irq(aic5_domain, irqnr, regs);
85} 85}
@@ -92,8 +92,8 @@ static void aic5_mask(struct irq_data *d)
92 92
93 /* Disable interrupt on AIC5 */ 93 /* Disable interrupt on AIC5 */
94 irq_gc_lock(gc); 94 irq_gc_lock(gc);
95 irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR); 95 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
96 irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR); 96 irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
97 gc->mask_cache &= ~d->mask; 97 gc->mask_cache &= ~d->mask;
98 irq_gc_unlock(gc); 98 irq_gc_unlock(gc);
99} 99}
@@ -106,8 +106,8 @@ static void aic5_unmask(struct irq_data *d)
106 106
107 /* Enable interrupt on AIC5 */ 107 /* Enable interrupt on AIC5 */
108 irq_gc_lock(gc); 108 irq_gc_lock(gc);
109 irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR); 109 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
110 irq_reg_writel(1, gc->reg_base + AT91_AIC5_IECR); 110 irq_reg_writel(gc, 1, AT91_AIC5_IECR);
111 gc->mask_cache |= d->mask; 111 gc->mask_cache |= d->mask;
112 irq_gc_unlock(gc); 112 irq_gc_unlock(gc);
113} 113}
@@ -120,8 +120,8 @@ static int aic5_retrigger(struct irq_data *d)
120 120
121 /* Enable interrupt on AIC5 */ 121 /* Enable interrupt on AIC5 */
122 irq_gc_lock(gc); 122 irq_gc_lock(gc);
123 irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR); 123 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
124 irq_reg_writel(1, gc->reg_base + AT91_AIC5_ISCR); 124 irq_reg_writel(gc, 1, AT91_AIC5_ISCR);
125 irq_gc_unlock(gc); 125 irq_gc_unlock(gc);
126 126
127 return 0; 127 return 0;
@@ -136,11 +136,11 @@ static int aic5_set_type(struct irq_data *d, unsigned type)
136 int ret; 136 int ret;
137 137
138 irq_gc_lock(gc); 138 irq_gc_lock(gc);
139 irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR); 139 irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
140 smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR); 140 smr = irq_reg_readl(gc, AT91_AIC5_SMR);
141 ret = aic_common_set_type(d, type, &smr); 141 ret = aic_common_set_type(d, type, &smr);
142 if (!ret) 142 if (!ret)
143 irq_reg_writel(smr, gc->reg_base + AT91_AIC5_SMR); 143 irq_reg_writel(gc, smr, AT91_AIC5_SMR);
144 irq_gc_unlock(gc); 144 irq_gc_unlock(gc);
145 145
146 return ret; 146 return ret;
@@ -162,12 +162,11 @@ static void aic5_suspend(struct irq_data *d)
162 if ((mask & gc->mask_cache) == (mask & gc->wake_active)) 162 if ((mask & gc->mask_cache) == (mask & gc->wake_active))
163 continue; 163 continue;
164 164
165 irq_reg_writel(i + gc->irq_base, 165 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
166 bgc->reg_base + AT91_AIC5_SSR);
167 if (mask & gc->wake_active) 166 if (mask & gc->wake_active)
168 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR); 167 irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
169 else 168 else
170 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR); 169 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
171 } 170 }
172 irq_gc_unlock(bgc); 171 irq_gc_unlock(bgc);
173} 172}
@@ -187,12 +186,11 @@ static void aic5_resume(struct irq_data *d)
187 if ((mask & gc->mask_cache) == (mask & gc->wake_active)) 186 if ((mask & gc->mask_cache) == (mask & gc->wake_active))
188 continue; 187 continue;
189 188
190 irq_reg_writel(i + gc->irq_base, 189 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
191 bgc->reg_base + AT91_AIC5_SSR);
192 if (mask & gc->mask_cache) 190 if (mask & gc->mask_cache)
193 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR); 191 irq_reg_writel(bgc, 1, AT91_AIC5_IECR);
194 else 192 else
195 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR); 193 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
196 } 194 }
197 irq_gc_unlock(bgc); 195 irq_gc_unlock(bgc);
198} 196}
@@ -207,10 +205,9 @@ static void aic5_pm_shutdown(struct irq_data *d)
207 205
208 irq_gc_lock(bgc); 206 irq_gc_lock(bgc);
209 for (i = 0; i < dgc->irqs_per_chip; i++) { 207 for (i = 0; i < dgc->irqs_per_chip; i++) {
210 irq_reg_writel(i + gc->irq_base, 208 irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
211 bgc->reg_base + AT91_AIC5_SSR); 209 irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
212 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR); 210 irq_reg_writel(bgc, 1, AT91_AIC5_ICCR);
213 irq_reg_writel(1, bgc->reg_base + AT91_AIC5_ICCR);
214 } 211 }
215 irq_gc_unlock(bgc); 212 irq_gc_unlock(bgc);
216} 213}
@@ -230,24 +227,24 @@ static void __init aic5_hw_init(struct irq_domain *domain)
230 * will not Lock out nIRQ 227 * will not Lock out nIRQ
231 */ 228 */
232 for (i = 0; i < 8; i++) 229 for (i = 0; i < 8; i++)
233 irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR); 230 irq_reg_writel(gc, 0, AT91_AIC5_EOICR);
234 231
235 /* 232 /*
236 * Spurious Interrupt ID in Spurious Vector Register. 233 * Spurious Interrupt ID in Spurious Vector Register.
237 * When there is no current interrupt, the IRQ Vector Register 234 * When there is no current interrupt, the IRQ Vector Register
238 * reads the value stored in AIC_SPU 235 * reads the value stored in AIC_SPU
239 */ 236 */
240 irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC5_SPU); 237 irq_reg_writel(gc, 0xffffffff, AT91_AIC5_SPU);
241 238
242 /* No debugging in AIC: Debug (Protect) Control Register */ 239 /* No debugging in AIC: Debug (Protect) Control Register */
243 irq_reg_writel(0, gc->reg_base + AT91_AIC5_DCR); 240 irq_reg_writel(gc, 0, AT91_AIC5_DCR);
244 241
245 /* Disable and clear all interrupts initially */ 242 /* Disable and clear all interrupts initially */
246 for (i = 0; i < domain->revmap_size; i++) { 243 for (i = 0; i < domain->revmap_size; i++) {
247 irq_reg_writel(i, gc->reg_base + AT91_AIC5_SSR); 244 irq_reg_writel(gc, i, AT91_AIC5_SSR);
248 irq_reg_writel(i, gc->reg_base + AT91_AIC5_SVR); 245 irq_reg_writel(gc, i, AT91_AIC5_SVR);
249 irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR); 246 irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
250 irq_reg_writel(1, gc->reg_base + AT91_AIC5_ICCR); 247 irq_reg_writel(gc, 1, AT91_AIC5_ICCR);
251 } 248 }
252} 249}
253 250
@@ -273,11 +270,11 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
273 gc = dgc->gc[0]; 270 gc = dgc->gc[0];
274 271
275 irq_gc_lock(gc); 272 irq_gc_lock(gc);
276 irq_reg_writel(*out_hwirq, gc->reg_base + AT91_AIC5_SSR); 273 irq_reg_writel(gc, *out_hwirq, AT91_AIC5_SSR);
277 smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR); 274 smr = irq_reg_readl(gc, AT91_AIC5_SMR);
278 ret = aic_common_set_priority(intspec[2], &smr); 275 ret = aic_common_set_priority(intspec[2], &smr);
279 if (!ret) 276 if (!ret)
280 irq_reg_writel(intspec[2] | smr, gc->reg_base + AT91_AIC5_SMR); 277 irq_reg_writel(gc, intspec[2] | smr, AT91_AIC5_SMR);
281 irq_gc_unlock(gc); 278 irq_gc_unlock(gc);
282 279
283 return ret; 280 return ret;
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index 5fb38a2ac226..8eec8e1201d9 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kconfig.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/of.h> 18#include <linux/of.h>
18#include <linux/of_irq.h> 19#include <linux/of_irq.h>
@@ -23,47 +24,52 @@
23#include <linux/io.h> 24#include <linux/io.h>
24#include <linux/irqdomain.h> 25#include <linux/irqdomain.h>
25#include <linux/reboot.h> 26#include <linux/reboot.h>
27#include <linux/bitops.h>
26#include <linux/irqchip/chained_irq.h> 28#include <linux/irqchip/chained_irq.h>
27 29
28#include "irqchip.h" 30#include "irqchip.h"
29 31
30#include <asm/mach/irq.h>
31
32/* Register offset in the L2 interrupt controller */ 32/* Register offset in the L2 interrupt controller */
33#define IRQEN 0x00 33#define IRQEN 0x00
34#define IRQSTAT 0x04 34#define IRQSTAT 0x04
35 35
36#define MAX_WORDS 4
37#define IRQS_PER_WORD 32
38
36struct bcm7120_l2_intc_data { 39struct bcm7120_l2_intc_data {
37 void __iomem *base; 40 unsigned int n_words;
41 void __iomem *base[MAX_WORDS];
38 struct irq_domain *domain; 42 struct irq_domain *domain;
39 bool can_wake; 43 bool can_wake;
40 u32 irq_fwd_mask; 44 u32 irq_fwd_mask[MAX_WORDS];
41 u32 irq_map_mask; 45 u32 irq_map_mask[MAX_WORDS];
42 u32 saved_mask;
43}; 46};
44 47
45static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) 48static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
46{ 49{
47 struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc); 50 struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc);
48 struct irq_chip *chip = irq_desc_get_chip(desc); 51 struct irq_chip *chip = irq_desc_get_chip(desc);
49 u32 status; 52 unsigned int idx;
50 53
51 chained_irq_enter(chip, desc); 54 chained_irq_enter(chip, desc);
52 55
53 status = __raw_readl(b->base + IRQSTAT); 56 for (idx = 0; idx < b->n_words; idx++) {
54 57 int base = idx * IRQS_PER_WORD;
55 if (status == 0) { 58 struct irq_chip_generic *gc =
56 do_bad_IRQ(irq, desc); 59 irq_get_domain_generic_chip(b->domain, base);
57 goto out; 60 unsigned long pending;
61 int hwirq;
62
63 irq_gc_lock(gc);
64 pending = irq_reg_readl(gc, IRQSTAT) & gc->mask_cache;
65 irq_gc_unlock(gc);
66
67 for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
68 generic_handle_irq(irq_find_mapping(b->domain,
69 base + hwirq));
70 }
58 } 71 }
59 72
60 do {
61 irq = ffs(status) - 1;
62 status &= ~(1 << irq);
63 generic_handle_irq(irq_find_mapping(b->domain, irq));
64 } while (status);
65
66out:
67 chained_irq_exit(chip, desc); 73 chained_irq_exit(chip, desc);
68} 74}
69 75
@@ -71,26 +77,20 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d)
71{ 77{
72 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 78 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
73 struct bcm7120_l2_intc_data *b = gc->private; 79 struct bcm7120_l2_intc_data *b = gc->private;
74 u32 reg;
75 80
76 irq_gc_lock(gc); 81 irq_gc_lock(gc);
77 /* Save the current mask and the interrupt forward mask */ 82 if (b->can_wake)
78 b->saved_mask = __raw_readl(b->base) | b->irq_fwd_mask; 83 irq_reg_writel(gc, gc->mask_cache | gc->wake_active, IRQEN);
79 if (b->can_wake) {
80 reg = b->saved_mask | gc->wake_active;
81 __raw_writel(reg, b->base);
82 }
83 irq_gc_unlock(gc); 84 irq_gc_unlock(gc);
84} 85}
85 86
86static void bcm7120_l2_intc_resume(struct irq_data *d) 87static void bcm7120_l2_intc_resume(struct irq_data *d)
87{ 88{
88 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 89 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
89 struct bcm7120_l2_intc_data *b = gc->private;
90 90
91 /* Restore the saved mask */ 91 /* Restore the saved mask */
92 irq_gc_lock(gc); 92 irq_gc_lock(gc);
93 __raw_writel(b->saved_mask, b->base); 93 irq_reg_writel(gc, gc->mask_cache, IRQEN);
94 irq_gc_unlock(gc); 94 irq_gc_unlock(gc);
95} 95}
96 96
@@ -99,6 +99,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
99 int irq, const __be32 *map_mask) 99 int irq, const __be32 *map_mask)
100{ 100{
101 int parent_irq; 101 int parent_irq;
102 unsigned int idx;
102 103
103 parent_irq = irq_of_parse_and_map(dn, irq); 104 parent_irq = irq_of_parse_and_map(dn, irq);
104 if (!parent_irq) { 105 if (!parent_irq) {
@@ -106,7 +107,12 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
106 return -EINVAL; 107 return -EINVAL;
107 } 108 }
108 109
109 data->irq_map_mask |= be32_to_cpup(map_mask + irq); 110 /* For multiple parent IRQs with multiple words, this looks like:
111 * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
112 */
113 for (idx = 0; idx < data->n_words; idx++)
114 data->irq_map_mask[idx] |=
115 be32_to_cpup(map_mask + irq * data->n_words + idx);
110 116
111 irq_set_handler_data(parent_irq, data); 117 irq_set_handler_data(parent_irq, data);
112 irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle); 118 irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle);
@@ -123,26 +129,41 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
123 struct irq_chip_type *ct; 129 struct irq_chip_type *ct;
124 const __be32 *map_mask; 130 const __be32 *map_mask;
125 int num_parent_irqs; 131 int num_parent_irqs;
126 int ret = 0, len, irq; 132 int ret = 0, len;
133 unsigned int idx, irq, flags;
127 134
128 data = kzalloc(sizeof(*data), GFP_KERNEL); 135 data = kzalloc(sizeof(*data), GFP_KERNEL);
129 if (!data) 136 if (!data)
130 return -ENOMEM; 137 return -ENOMEM;
131 138
132 data->base = of_iomap(dn, 0); 139 for (idx = 0; idx < MAX_WORDS; idx++) {
133 if (!data->base) { 140 data->base[idx] = of_iomap(dn, idx);
141 if (!data->base[idx])
142 break;
143 data->n_words = idx + 1;
144 }
145 if (!data->n_words) {
134 pr_err("failed to remap intc L2 registers\n"); 146 pr_err("failed to remap intc L2 registers\n");
135 ret = -ENOMEM; 147 ret = -ENOMEM;
136 goto out_free; 148 goto out_unmap;
137 } 149 }
138 150
139 if (of_property_read_u32(dn, "brcm,int-fwd-mask", &data->irq_fwd_mask)) 151 /* Enable all interrupts specified in the interrupt forward mask;
140 data->irq_fwd_mask = 0; 152 * disable all others. If the property doesn't exist (-EINVAL),
141 153 * assume all zeroes.
142 /* Enable all interrupt specified in the interrupt forward mask and have
143 * the other disabled
144 */ 154 */
145 __raw_writel(data->irq_fwd_mask, data->base + IRQEN); 155 ret = of_property_read_u32_array(dn, "brcm,int-fwd-mask",
156 data->irq_fwd_mask, data->n_words);
157 if (ret == 0 || ret == -EINVAL) {
158 for (idx = 0; idx < data->n_words; idx++)
159 __raw_writel(data->irq_fwd_mask[idx],
160 data->base[idx] + IRQEN);
161 } else {
162 /* property exists but has the wrong number of words */
163 pr_err("invalid int-fwd-mask property\n");
164 ret = -EINVAL;
165 goto out_unmap;
166 }
146 167
147 num_parent_irqs = of_irq_count(dn); 168 num_parent_irqs = of_irq_count(dn);
148 if (num_parent_irqs <= 0) { 169 if (num_parent_irqs <= 0) {
@@ -152,7 +173,8 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
152 } 173 }
153 174
154 map_mask = of_get_property(dn, "brcm,int-map-mask", &len); 175 map_mask = of_get_property(dn, "brcm,int-map-mask", &len);
155 if (!map_mask || (len != (sizeof(*map_mask) * num_parent_irqs))) { 176 if (!map_mask ||
177 (len != (sizeof(*map_mask) * num_parent_irqs * data->n_words))) {
156 pr_err("invalid brcm,int-map-mask property\n"); 178 pr_err("invalid brcm,int-map-mask property\n");
157 ret = -EINVAL; 179 ret = -EINVAL;
158 goto out_unmap; 180 goto out_unmap;
@@ -164,56 +186,70 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
164 goto out_unmap; 186 goto out_unmap;
165 } 187 }
166 188
167 data->domain = irq_domain_add_linear(dn, 32, 189 data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words,
168 &irq_generic_chip_ops, NULL); 190 &irq_generic_chip_ops, NULL);
169 if (!data->domain) { 191 if (!data->domain) {
170 ret = -ENOMEM; 192 ret = -ENOMEM;
171 goto out_unmap; 193 goto out_unmap;
172 } 194 }
173 195
174 ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, 196 /* MIPS chips strapped for BE will automagically configure the
175 dn->full_name, handle_level_irq, clr, 0, 197 * peripheral registers for CPU-native byte order.
176 IRQ_GC_INIT_MASK_CACHE); 198 */
199 flags = IRQ_GC_INIT_MASK_CACHE;
200 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
201 flags |= IRQ_GC_BE_IO;
202
203 ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1,
204 dn->full_name, handle_level_irq, clr, 0, flags);
177 if (ret) { 205 if (ret) {
178 pr_err("failed to allocate generic irq chip\n"); 206 pr_err("failed to allocate generic irq chip\n");
179 goto out_free_domain; 207 goto out_free_domain;
180 } 208 }
181 209
182 gc = irq_get_domain_generic_chip(data->domain, 0); 210 if (of_property_read_bool(dn, "brcm,irq-can-wake"))
183 gc->unused = 0xfffffff & ~data->irq_map_mask;
184 gc->reg_base = data->base;
185 gc->private = data;
186 ct = gc->chip_types;
187
188 ct->regs.mask = IRQEN;
189 ct->chip.irq_mask = irq_gc_mask_clr_bit;
190 ct->chip.irq_unmask = irq_gc_mask_set_bit;
191 ct->chip.irq_ack = irq_gc_noop;
192 ct->chip.irq_suspend = bcm7120_l2_intc_suspend;
193 ct->chip.irq_resume = bcm7120_l2_intc_resume;
194
195 if (of_property_read_bool(dn, "brcm,irq-can-wake")) {
196 data->can_wake = true; 211 data->can_wake = true;
197 /* This IRQ chip can wake the system, set all relevant child 212
198 * interupts in wake_enabled mask 213 for (idx = 0; idx < data->n_words; idx++) {
199 */ 214 irq = idx * IRQS_PER_WORD;
200 gc->wake_enabled = 0xffffffff; 215 gc = irq_get_domain_generic_chip(data->domain, irq);
201 gc->wake_enabled &= ~gc->unused; 216
202 ct->chip.irq_set_wake = irq_gc_set_wake; 217 gc->unused = 0xffffffff & ~data->irq_map_mask[idx];
218 gc->reg_base = data->base[idx];
219 gc->private = data;
220 ct = gc->chip_types;
221
222 ct->regs.mask = IRQEN;
223 ct->chip.irq_mask = irq_gc_mask_clr_bit;
224 ct->chip.irq_unmask = irq_gc_mask_set_bit;
225 ct->chip.irq_ack = irq_gc_noop;
226 ct->chip.irq_suspend = bcm7120_l2_intc_suspend;
227 ct->chip.irq_resume = bcm7120_l2_intc_resume;
228
229 if (data->can_wake) {
230 /* This IRQ chip can wake the system, set all
231 * relevant child interupts in wake_enabled mask
232 */
233 gc->wake_enabled = 0xffffffff;
234 gc->wake_enabled &= ~gc->unused;
235 ct->chip.irq_set_wake = irq_gc_set_wake;
236 }
203 } 237 }
204 238
205 pr_info("registered BCM7120 L2 intc (mem: 0x%p, parent IRQ(s): %d)\n", 239 pr_info("registered BCM7120 L2 intc (mem: 0x%p, parent IRQ(s): %d)\n",
206 data->base, num_parent_irqs); 240 data->base[0], num_parent_irqs);
207 241
208 return 0; 242 return 0;
209 243
210out_free_domain: 244out_free_domain:
211 irq_domain_remove(data->domain); 245 irq_domain_remove(data->domain);
212out_unmap: 246out_unmap:
213 iounmap(data->base); 247 for (idx = 0; idx < MAX_WORDS; idx++) {
214out_free: 248 if (data->base[idx])
249 iounmap(data->base[idx]);
250 }
215 kfree(data); 251 kfree(data);
216 return ret; 252 return ret;
217} 253}
218IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,bcm7120-l2-intc", 254IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc",
219 bcm7120_l2_intc_of_init); 255 bcm7120_l2_intc_of_init);
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index 14691a4cb84c..313c2c64498a 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -18,7 +18,9 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kconfig.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
22#include <linux/of.h> 24#include <linux/of.h>
23#include <linux/of_irq.h> 25#include <linux/of_irq.h>
24#include <linux/of_address.h> 26#include <linux/of_address.h>
@@ -30,8 +32,6 @@
30#include <linux/irqchip.h> 32#include <linux/irqchip.h>
31#include <linux/irqchip/chained_irq.h> 33#include <linux/irqchip/chained_irq.h>
32 34
33#include <asm/mach/irq.h>
34
35#include "irqchip.h" 35#include "irqchip.h"
36 36
37/* Register offsets in the L2 interrupt controller */ 37/* Register offsets in the L2 interrupt controller */
@@ -54,23 +54,26 @@ struct brcmstb_l2_intc_data {
54static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) 54static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
55{ 55{
56 struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); 56 struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc);
57 struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0);
57 struct irq_chip *chip = irq_desc_get_chip(desc); 58 struct irq_chip *chip = irq_desc_get_chip(desc);
58 u32 status; 59 u32 status;
59 60
60 chained_irq_enter(chip, desc); 61 chained_irq_enter(chip, desc);
61 62
62 status = __raw_readl(b->base + CPU_STATUS) & 63 status = irq_reg_readl(gc, CPU_STATUS) &
63 ~(__raw_readl(b->base + CPU_MASK_STATUS)); 64 ~(irq_reg_readl(gc, CPU_MASK_STATUS));
64 65
65 if (status == 0) { 66 if (status == 0) {
66 do_bad_IRQ(irq, desc); 67 raw_spin_lock(&desc->lock);
68 handle_bad_irq(irq, desc);
69 raw_spin_unlock(&desc->lock);
67 goto out; 70 goto out;
68 } 71 }
69 72
70 do { 73 do {
71 irq = ffs(status) - 1; 74 irq = ffs(status) - 1;
72 /* ack at our level */ 75 /* ack at our level */
73 __raw_writel(1 << irq, b->base + CPU_CLEAR); 76 irq_reg_writel(gc, 1 << irq, CPU_CLEAR);
74 status &= ~(1 << irq); 77 status &= ~(1 << irq);
75 generic_handle_irq(irq_find_mapping(b->domain, irq)); 78 generic_handle_irq(irq_find_mapping(b->domain, irq));
76 } while (status); 79 } while (status);
@@ -85,12 +88,12 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
85 88
86 irq_gc_lock(gc); 89 irq_gc_lock(gc);
87 /* Save the current mask */ 90 /* Save the current mask */
88 b->saved_mask = __raw_readl(b->base + CPU_MASK_STATUS); 91 b->saved_mask = irq_reg_readl(gc, CPU_MASK_STATUS);
89 92
90 if (b->can_wake) { 93 if (b->can_wake) {
91 /* Program the wakeup mask */ 94 /* Program the wakeup mask */
92 __raw_writel(~gc->wake_active, b->base + CPU_MASK_SET); 95 irq_reg_writel(gc, ~gc->wake_active, CPU_MASK_SET);
93 __raw_writel(gc->wake_active, b->base + CPU_MASK_CLEAR); 96 irq_reg_writel(gc, gc->wake_active, CPU_MASK_CLEAR);
94 } 97 }
95 irq_gc_unlock(gc); 98 irq_gc_unlock(gc);
96} 99}
@@ -102,11 +105,11 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
102 105
103 irq_gc_lock(gc); 106 irq_gc_lock(gc);
104 /* Clear unmasked non-wakeup interrupts */ 107 /* Clear unmasked non-wakeup interrupts */
105 __raw_writel(~b->saved_mask & ~gc->wake_active, b->base + CPU_CLEAR); 108 irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active, CPU_CLEAR);
106 109
107 /* Restore the saved mask */ 110 /* Restore the saved mask */
108 __raw_writel(b->saved_mask, b->base + CPU_MASK_SET); 111 irq_reg_writel(gc, b->saved_mask, CPU_MASK_SET);
109 __raw_writel(~b->saved_mask, b->base + CPU_MASK_CLEAR); 112 irq_reg_writel(gc, ~b->saved_mask, CPU_MASK_CLEAR);
110 irq_gc_unlock(gc); 113 irq_gc_unlock(gc);
111} 114}
112 115
@@ -118,6 +121,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
118 struct irq_chip_generic *gc; 121 struct irq_chip_generic *gc;
119 struct irq_chip_type *ct; 122 struct irq_chip_type *ct;
120 int ret; 123 int ret;
124 unsigned int flags;
121 125
122 data = kzalloc(sizeof(*data), GFP_KERNEL); 126 data = kzalloc(sizeof(*data), GFP_KERNEL);
123 if (!data) 127 if (!data)
@@ -131,8 +135,8 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
131 } 135 }
132 136
133 /* Disable all interrupts by default */ 137 /* Disable all interrupts by default */
134 __raw_writel(0xffffffff, data->base + CPU_MASK_SET); 138 writel(0xffffffff, data->base + CPU_MASK_SET);
135 __raw_writel(0xffffffff, data->base + CPU_CLEAR); 139 writel(0xffffffff, data->base + CPU_CLEAR);
136 140
137 data->parent_irq = irq_of_parse_and_map(np, 0); 141 data->parent_irq = irq_of_parse_and_map(np, 0);
138 if (!data->parent_irq) { 142 if (!data->parent_irq) {
@@ -148,9 +152,16 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
148 goto out_unmap; 152 goto out_unmap;
149 } 153 }
150 154
155 /* MIPS chips strapped for BE will automagically configure the
156 * peripheral registers for CPU-native byte order.
157 */
158 flags = 0;
159 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
160 flags |= IRQ_GC_BE_IO;
161
151 /* Allocate a single Generic IRQ chip for this node */ 162 /* Allocate a single Generic IRQ chip for this node */
152 ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, 163 ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
153 np->full_name, handle_edge_irq, clr, 0, 0); 164 np->full_name, handle_edge_irq, clr, 0, flags);
154 if (ret) { 165 if (ret) {
155 pr_err("failed to allocate generic irq chip\n"); 166 pr_err("failed to allocate generic irq chip\n");
156 goto out_free_domain; 167 goto out_free_domain;
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)
50 chained_irq_exit(chip, desc); 50 chained_irq_exit(chip, desc);
51} 51}
52 52
53#ifdef CONFIG_PM
54static void dw_apb_ictl_resume(struct irq_data *d)
55{
56 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
57 struct irq_chip_type *ct = irq_data_get_chip_type(d);
58
59 irq_gc_lock(gc);
60 writel_relaxed(~0, gc->reg_base + ct->regs.enable);
61 writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
62 irq_gc_unlock(gc);
63}
64#else
65#define dw_apb_ictl_resume NULL
66#endif /* CONFIG_PM */
67
53static int __init dw_apb_ictl_init(struct device_node *np, 68static int __init dw_apb_ictl_init(struct device_node *np,
54 struct device_node *parent) 69 struct device_node *parent)
55{ 70{
@@ -94,16 +109,16 @@ static int __init dw_apb_ictl_init(struct device_node *np,
94 */ 109 */
95 110
96 /* mask and enable all interrupts */ 111 /* mask and enable all interrupts */
97 writel(~0, iobase + APB_INT_MASK_L); 112 writel_relaxed(~0, iobase + APB_INT_MASK_L);
98 writel(~0, iobase + APB_INT_MASK_H); 113 writel_relaxed(~0, iobase + APB_INT_MASK_H);
99 writel(~0, iobase + APB_INT_ENABLE_L); 114 writel_relaxed(~0, iobase + APB_INT_ENABLE_L);
100 writel(~0, iobase + APB_INT_ENABLE_H); 115 writel_relaxed(~0, iobase + APB_INT_ENABLE_H);
101 116
102 reg = readl(iobase + APB_INT_ENABLE_H); 117 reg = readl_relaxed(iobase + APB_INT_ENABLE_H);
103 if (reg) 118 if (reg)
104 nrirqs = 32 + fls(reg); 119 nrirqs = 32 + fls(reg);
105 else 120 else
106 nrirqs = fls(readl(iobase + APB_INT_ENABLE_L)); 121 nrirqs = fls(readl_relaxed(iobase + APB_INT_ENABLE_L));
107 122
108 domain = irq_domain_add_linear(np, nrirqs, 123 domain = irq_domain_add_linear(np, nrirqs,
109 &irq_generic_chip_ops, NULL); 124 &irq_generic_chip_ops, NULL);
@@ -115,6 +130,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
115 130
116 ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1, 131 ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1,
117 np->name, handle_level_irq, clr, 0, 132 np->name, handle_level_irq, clr, 0,
133 IRQ_GC_MASK_CACHE_PER_TYPE |
118 IRQ_GC_INIT_MASK_CACHE); 134 IRQ_GC_INIT_MASK_CACHE);
119 if (ret) { 135 if (ret) {
120 pr_err("%s: unable to alloc irq domain gc\n", np->full_name); 136 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,
126 gc->reg_base = iobase; 142 gc->reg_base = iobase;
127 143
128 gc->chip_types[0].regs.mask = APB_INT_MASK_L; 144 gc->chip_types[0].regs.mask = APB_INT_MASK_L;
145 gc->chip_types[0].regs.enable = APB_INT_ENABLE_L;
129 gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; 146 gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
130 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; 147 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
148 gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume;
131 149
132 if (nrirqs > 32) { 150 if (nrirqs > 32) {
133 gc->chip_types[1].regs.mask = APB_INT_MASK_H; 151 gc->chip_types[1].regs.mask = APB_INT_MASK_H;
152 gc->chip_types[1].regs.enable = APB_INT_ENABLE_H;
134 gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit; 153 gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit;
135 gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit; 154 gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit;
155 gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume;
136 } 156 }
137 157
138 irq_set_handler_data(irq, gc); 158 irq_set_handler_data(irq, gc);
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 9c8f833522e6..29b8f21b74d0 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -176,8 +176,7 @@ static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs)
176 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 176 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
177 177
178 if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) { 178 if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) {
179 irqnr = irq_find_mapping(hip04_data.domain, irqnr); 179 handle_domain_irq(hip04_data.domain, irqnr, regs);
180 handle_IRQ(irqnr, regs);
181 continue; 180 continue;
182 } 181 }
183 if (irqnr < 16) { 182 if (irqnr < 16) {
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
index 12f547a44ae4..4a9ce5b50c5b 100644
--- a/drivers/irqchip/irq-sunxi-nmi.c
+++ b/drivers/irqchip/irq-sunxi-nmi.c
@@ -50,12 +50,12 @@ static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = {
50static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, 50static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
51 u32 val) 51 u32 val)
52{ 52{
53 irq_reg_writel(val, gc->reg_base + off); 53 irq_reg_writel(gc, val, off);
54} 54}
55 55
56static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off) 56static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off)
57{ 57{
58 return irq_reg_readl(gc->reg_base + off); 58 return irq_reg_readl(gc, off);
59} 59}
60 60
61static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) 61static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc)
diff --git a/drivers/irqchip/irq-tb10x.c b/drivers/irqchip/irq-tb10x.c
index 7c44c99bf1f2..accc20036a3c 100644
--- a/drivers/irqchip/irq-tb10x.c
+++ b/drivers/irqchip/irq-tb10x.c
@@ -43,12 +43,12 @@
43static inline void ab_irqctl_writereg(struct irq_chip_generic *gc, u32 reg, 43static inline void ab_irqctl_writereg(struct irq_chip_generic *gc, u32 reg,
44 u32 val) 44 u32 val)
45{ 45{
46 irq_reg_writel(val, gc->reg_base + reg); 46 irq_reg_writel(gc, val, reg);
47} 47}
48 48
49static inline u32 ab_irqctl_readreg(struct irq_chip_generic *gc, u32 reg) 49static inline u32 ab_irqctl_readreg(struct irq_chip_generic *gc, u32 reg)
50{ 50{
51 return irq_reg_readl(gc->reg_base + reg); 51 return irq_reg_readl(gc, reg);
52} 52}
53 53
54static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type) 54static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 03f48d936f66..8588e5efe577 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -20,6 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/topology.h> 21#include <linux/topology.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/io.h>
23 24
24#include <asm/irq.h> 25#include <asm/irq.h>
25#include <asm/ptrace.h> 26#include <asm/ptrace.h>
@@ -639,13 +640,6 @@ void arch_teardown_hwirq(unsigned int irq);
639void irq_init_desc(unsigned int irq); 640void irq_init_desc(unsigned int irq);
640#endif 641#endif
641 642
642#ifndef irq_reg_writel
643# define irq_reg_writel(val, addr) writel(val, addr)
644#endif
645#ifndef irq_reg_readl
646# define irq_reg_readl(addr) readl(addr)
647#endif
648
649/** 643/**
650 * struct irq_chip_regs - register offsets for struct irq_gci 644 * struct irq_chip_regs - register offsets for struct irq_gci
651 * @enable: Enable register offset to reg_base 645 * @enable: Enable register offset to reg_base
@@ -692,6 +686,8 @@ struct irq_chip_type {
692 * struct irq_chip_generic - Generic irq chip data structure 686 * struct irq_chip_generic - Generic irq chip data structure
693 * @lock: Lock to protect register and cache data access 687 * @lock: Lock to protect register and cache data access
694 * @reg_base: Register base address (virtual) 688 * @reg_base: Register base address (virtual)
689 * @reg_readl: Alternate I/O accessor (defaults to readl if NULL)
690 * @reg_writel: Alternate I/O accessor (defaults to writel if NULL)
695 * @irq_base: Interrupt base nr for this chip 691 * @irq_base: Interrupt base nr for this chip
696 * @irq_cnt: Number of interrupts handled by this chip 692 * @irq_cnt: Number of interrupts handled by this chip
697 * @mask_cache: Cached mask register shared between all chip types 693 * @mask_cache: Cached mask register shared between all chip types
@@ -716,6 +712,8 @@ struct irq_chip_type {
716struct irq_chip_generic { 712struct irq_chip_generic {
717 raw_spinlock_t lock; 713 raw_spinlock_t lock;
718 void __iomem *reg_base; 714 void __iomem *reg_base;
715 u32 (*reg_readl)(void __iomem *addr);
716 void (*reg_writel)(u32 val, void __iomem *addr);
719 unsigned int irq_base; 717 unsigned int irq_base;
720 unsigned int irq_cnt; 718 unsigned int irq_cnt;
721 u32 mask_cache; 719 u32 mask_cache;
@@ -740,12 +738,14 @@ struct irq_chip_generic {
740 * the parent irq. Usually GPIO implementations 738 * the parent irq. Usually GPIO implementations
741 * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private 739 * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private
742 * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask 740 * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask
741 * @IRQ_GC_BE_IO: Use big-endian register accesses (default: LE)
743 */ 742 */
744enum irq_gc_flags { 743enum irq_gc_flags {
745 IRQ_GC_INIT_MASK_CACHE = 1 << 0, 744 IRQ_GC_INIT_MASK_CACHE = 1 << 0,
746 IRQ_GC_INIT_NESTED_LOCK = 1 << 1, 745 IRQ_GC_INIT_NESTED_LOCK = 1 << 1,
747 IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2, 746 IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2,
748 IRQ_GC_NO_MASK = 1 << 3, 747 IRQ_GC_NO_MASK = 1 << 3,
748 IRQ_GC_BE_IO = 1 << 4,
749}; 749};
750 750
751/* 751/*
@@ -821,4 +821,22 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { }
821static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } 821static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
822#endif 822#endif
823 823
824static inline void irq_reg_writel(struct irq_chip_generic *gc,
825 u32 val, int reg_offset)
826{
827 if (gc->reg_writel)
828 gc->reg_writel(val, gc->reg_base + reg_offset);
829 else
830 writel(val, gc->reg_base + reg_offset);
831}
832
833static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
834 int reg_offset)
835{
836 if (gc->reg_readl)
837 return gc->reg_readl(gc->reg_base + reg_offset);
838 else
839 return readl(gc->reg_base + reg_offset);
840}
841
824#endif /* _LINUX_IRQ_H */ 842#endif /* _LINUX_IRQ_H */
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index cf80e7b0ddab..61024e8abdef 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -39,7 +39,7 @@ void irq_gc_mask_disable_reg(struct irq_data *d)
39 u32 mask = d->mask; 39 u32 mask = d->mask;
40 40
41 irq_gc_lock(gc); 41 irq_gc_lock(gc);
42 irq_reg_writel(mask, gc->reg_base + ct->regs.disable); 42 irq_reg_writel(gc, mask, ct->regs.disable);
43 *ct->mask_cache &= ~mask; 43 *ct->mask_cache &= ~mask;
44 irq_gc_unlock(gc); 44 irq_gc_unlock(gc);
45} 45}
@@ -59,7 +59,7 @@ void irq_gc_mask_set_bit(struct irq_data *d)
59 59
60 irq_gc_lock(gc); 60 irq_gc_lock(gc);
61 *ct->mask_cache |= mask; 61 *ct->mask_cache |= mask;
62 irq_reg_writel(*ct->mask_cache, gc->reg_base + ct->regs.mask); 62 irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
63 irq_gc_unlock(gc); 63 irq_gc_unlock(gc);
64} 64}
65EXPORT_SYMBOL_GPL(irq_gc_mask_set_bit); 65EXPORT_SYMBOL_GPL(irq_gc_mask_set_bit);
@@ -79,7 +79,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d)
79 79
80 irq_gc_lock(gc); 80 irq_gc_lock(gc);
81 *ct->mask_cache &= ~mask; 81 *ct->mask_cache &= ~mask;
82 irq_reg_writel(*ct->mask_cache, gc->reg_base + ct->regs.mask); 82 irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
83 irq_gc_unlock(gc); 83 irq_gc_unlock(gc);
84} 84}
85EXPORT_SYMBOL_GPL(irq_gc_mask_clr_bit); 85EXPORT_SYMBOL_GPL(irq_gc_mask_clr_bit);
@@ -98,7 +98,7 @@ void irq_gc_unmask_enable_reg(struct irq_data *d)
98 u32 mask = d->mask; 98 u32 mask = d->mask;
99 99
100 irq_gc_lock(gc); 100 irq_gc_lock(gc);
101 irq_reg_writel(mask, gc->reg_base + ct->regs.enable); 101 irq_reg_writel(gc, mask, ct->regs.enable);
102 *ct->mask_cache |= mask; 102 *ct->mask_cache |= mask;
103 irq_gc_unlock(gc); 103 irq_gc_unlock(gc);
104} 104}
@@ -114,7 +114,7 @@ void irq_gc_ack_set_bit(struct irq_data *d)
114 u32 mask = d->mask; 114 u32 mask = d->mask;
115 115
116 irq_gc_lock(gc); 116 irq_gc_lock(gc);
117 irq_reg_writel(mask, gc->reg_base + ct->regs.ack); 117 irq_reg_writel(gc, mask, ct->regs.ack);
118 irq_gc_unlock(gc); 118 irq_gc_unlock(gc);
119} 119}
120EXPORT_SYMBOL_GPL(irq_gc_ack_set_bit); 120EXPORT_SYMBOL_GPL(irq_gc_ack_set_bit);
@@ -130,7 +130,7 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
130 u32 mask = ~d->mask; 130 u32 mask = ~d->mask;
131 131
132 irq_gc_lock(gc); 132 irq_gc_lock(gc);
133 irq_reg_writel(mask, gc->reg_base + ct->regs.ack); 133 irq_reg_writel(gc, mask, ct->regs.ack);
134 irq_gc_unlock(gc); 134 irq_gc_unlock(gc);
135} 135}
136 136
@@ -145,8 +145,8 @@ void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
145 u32 mask = d->mask; 145 u32 mask = d->mask;
146 146
147 irq_gc_lock(gc); 147 irq_gc_lock(gc);
148 irq_reg_writel(mask, gc->reg_base + ct->regs.mask); 148 irq_reg_writel(gc, mask, ct->regs.mask);
149 irq_reg_writel(mask, gc->reg_base + ct->regs.ack); 149 irq_reg_writel(gc, mask, ct->regs.ack);
150 irq_gc_unlock(gc); 150 irq_gc_unlock(gc);
151} 151}
152 152
@@ -161,7 +161,7 @@ void irq_gc_eoi(struct irq_data *d)
161 u32 mask = d->mask; 161 u32 mask = d->mask;
162 162
163 irq_gc_lock(gc); 163 irq_gc_lock(gc);
164 irq_reg_writel(mask, gc->reg_base + ct->regs.eoi); 164 irq_reg_writel(gc, mask, ct->regs.eoi);
165 irq_gc_unlock(gc); 165 irq_gc_unlock(gc);
166} 166}
167 167
@@ -191,6 +191,16 @@ int irq_gc_set_wake(struct irq_data *d, unsigned int on)
191 return 0; 191 return 0;
192} 192}
193 193
194static u32 irq_readl_be(void __iomem *addr)
195{
196 return ioread32be(addr);
197}
198
199static void irq_writel_be(u32 val, void __iomem *addr)
200{
201 iowrite32be(val, addr);
202}
203
194static void 204static void
195irq_init_generic_chip(struct irq_chip_generic *gc, const char *name, 205irq_init_generic_chip(struct irq_chip_generic *gc, const char *name,
196 int num_ct, unsigned int irq_base, 206 int num_ct, unsigned int irq_base,
@@ -245,7 +255,7 @@ irq_gc_init_mask_cache(struct irq_chip_generic *gc, enum irq_gc_flags flags)
245 } 255 }
246 ct[i].mask_cache = mskptr; 256 ct[i].mask_cache = mskptr;
247 if (flags & IRQ_GC_INIT_MASK_CACHE) 257 if (flags & IRQ_GC_INIT_MASK_CACHE)
248 *mskptr = irq_reg_readl(gc->reg_base + mskreg); 258 *mskptr = irq_reg_readl(gc, mskreg);
249 } 259 }
250} 260}
251 261
@@ -300,7 +310,13 @@ int irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
300 dgc->gc[i] = gc = tmp; 310 dgc->gc[i] = gc = tmp;
301 irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip, 311 irq_init_generic_chip(gc, name, num_ct, i * irqs_per_chip,
302 NULL, handler); 312 NULL, handler);
313
303 gc->domain = d; 314 gc->domain = d;
315 if (gcflags & IRQ_GC_BE_IO) {
316 gc->reg_readl = &irq_readl_be;
317 gc->reg_writel = &irq_writel_be;
318 }
319
304 raw_spin_lock_irqsave(&gc_lock, flags); 320 raw_spin_lock_irqsave(&gc_lock, flags);
305 list_add_tail(&gc->list, &gc_list); 321 list_add_tail(&gc->list, &gc_list);
306 raw_spin_unlock_irqrestore(&gc_lock, flags); 322 raw_spin_unlock_irqrestore(&gc_lock, flags);