summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-csky-apb-intc.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
committerTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
commitd02cac152c97dffcb0cdd91e09b54fd6e2cca63d (patch)
tree68e4c6bd842703009f3edbf8f0e0e9326e4b2fad /drivers/irqchip/irq-csky-apb-intc.c
parent36e4617c01153757cde9e5fcd375a75a8f8425c3 (diff)
parenta50e32694fbcdbf55875095258b9398e2eabd71f (diff)
Merge tag 'asoc-v5.1' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v5.1 Lots and lots of new drivers so far, a highlight being the MediaTek BTCVSD which is a driver for a Bluetooth radio chip - the first such driver we've had upstream. Hopefully we will soon also see a baseband with an upstream driver! - Support for only powering up channels that are actively being used. - Quite a few improvements to simplify the generic card drivers, especially the merge of the SCU cards into the main generic drivers. - Lots of fixes for probing on Intel systems, trying to rationalize things to look more standard from a framework point of view. - New drivers for Asahi Kasei Microdevices AK4497, Cirrus Logic CS4341, Google ChromeOS embedded controllers, Ingenic JZ4725B, MediaTek BTCVSD, MT8183 and MT6358, NXP MICFIL, Rockchip RK3328, Spreadtrum DMA controllers, Qualcomm WCD9335, Xilinx S/PDIF and PCM formatters.
Diffstat (limited to 'drivers/irqchip/irq-csky-apb-intc.c')
-rw-r--r--drivers/irqchip/irq-csky-apb-intc.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/drivers/irqchip/irq-csky-apb-intc.c b/drivers/irqchip/irq-csky-apb-intc.c
index 2543baba8b1f..5a2ec43b7ddd 100644
--- a/drivers/irqchip/irq-csky-apb-intc.c
+++ b/drivers/irqchip/irq-csky-apb-intc.c
@@ -95,7 +95,7 @@ static inline void setup_irq_channel(u32 magic, void __iomem *reg_addr)
95 95
96 /* Setup 64 channel slots */ 96 /* Setup 64 channel slots */
97 for (i = 0; i < INTC_IRQS; i += 4) 97 for (i = 0; i < INTC_IRQS; i += 4)
98 writel_relaxed(build_channel_val(i, magic), reg_addr + i); 98 writel(build_channel_val(i, magic), reg_addr + i);
99} 99}
100 100
101static int __init 101static int __init
@@ -135,16 +135,10 @@ ck_intc_init_comm(struct device_node *node, struct device_node *parent)
135static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq, 135static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
136 u32 irq_base) 136 u32 irq_base)
137{ 137{
138 u32 irq;
139
140 if (hwirq == 0) 138 if (hwirq == 0)
141 return 0; 139 return 0;
142 140
143 while (hwirq) { 141 handle_domain_irq(root_domain, irq_base + __fls(hwirq), regs);
144 irq = __ffs(hwirq);
145 hwirq &= ~BIT(irq);
146 handle_domain_irq(root_domain, irq_base + irq, regs);
147 }
148 142
149 return 1; 143 return 1;
150} 144}
@@ -154,12 +148,16 @@ static void gx_irq_handler(struct pt_regs *regs)
154{ 148{
155 bool ret; 149 bool ret;
156 150
157 do { 151retry:
158 ret = handle_irq_perbit(regs, 152 ret = handle_irq_perbit(regs,
159 readl_relaxed(reg_base + GX_INTC_PEN31_00), 0); 153 readl(reg_base + GX_INTC_PEN63_32), 32);
160 ret |= handle_irq_perbit(regs, 154 if (ret)
161 readl_relaxed(reg_base + GX_INTC_PEN63_32), 32); 155 goto retry;
162 } while (ret); 156
157 ret = handle_irq_perbit(regs,
158 readl(reg_base + GX_INTC_PEN31_00), 0);
159 if (ret)
160 goto retry;
163} 161}
164 162
165static int __init 163static int __init
@@ -174,14 +172,14 @@ gx_intc_init(struct device_node *node, struct device_node *parent)
174 /* 172 /*
175 * Initial enable reg to disable all interrupts 173 * Initial enable reg to disable all interrupts
176 */ 174 */
177 writel_relaxed(0x0, reg_base + GX_INTC_NEN31_00); 175 writel(0x0, reg_base + GX_INTC_NEN31_00);
178 writel_relaxed(0x0, reg_base + GX_INTC_NEN63_32); 176 writel(0x0, reg_base + GX_INTC_NEN63_32);
179 177
180 /* 178 /*
181 * Initial mask reg with all unmasked, because we only use enalbe reg 179 * Initial mask reg with all unmasked, because we only use enalbe reg
182 */ 180 */
183 writel_relaxed(0x0, reg_base + GX_INTC_NMASK31_00); 181 writel(0x0, reg_base + GX_INTC_NMASK31_00);
184 writel_relaxed(0x0, reg_base + GX_INTC_NMASK63_32); 182 writel(0x0, reg_base + GX_INTC_NMASK63_32);
185 183
186 setup_irq_channel(0x03020100, reg_base + GX_INTC_SOURCE); 184 setup_irq_channel(0x03020100, reg_base + GX_INTC_SOURCE);
187 185
@@ -204,20 +202,29 @@ static void ck_irq_handler(struct pt_regs *regs)
204 void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00; 202 void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00;
205 void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32; 203 void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32;
206 204
207 do { 205retry:
208 /* handle 0 - 31 irqs */ 206 /* handle 0 - 63 irqs */
209 ret = handle_irq_perbit(regs, readl_relaxed(reg_pen_lo), 0); 207 ret = handle_irq_perbit(regs, readl(reg_pen_hi), 32);
210 ret |= handle_irq_perbit(regs, readl_relaxed(reg_pen_hi), 32); 208 if (ret)
209 goto retry;
211 210
212 if (nr_irq == INTC_IRQS) 211 ret = handle_irq_perbit(regs, readl(reg_pen_lo), 0);
213 continue; 212 if (ret)
213 goto retry;
214
215 if (nr_irq == INTC_IRQS)
216 return;
214 217
215 /* handle 64 - 127 irqs */ 218 /* handle 64 - 127 irqs */
216 ret |= handle_irq_perbit(regs, 219 ret = handle_irq_perbit(regs,
217 readl_relaxed(reg_pen_lo + CK_INTC_DUAL_BASE), 64); 220 readl(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
218 ret |= handle_irq_perbit(regs, 221 if (ret)
219 readl_relaxed(reg_pen_hi + CK_INTC_DUAL_BASE), 96); 222 goto retry;
220 } while (ret); 223
224 ret = handle_irq_perbit(regs,
225 readl(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
226 if (ret)
227 goto retry;
221} 228}
222 229
223static int __init 230static int __init
@@ -230,11 +237,11 @@ ck_intc_init(struct device_node *node, struct device_node *parent)
230 return ret; 237 return ret;
231 238
232 /* Initial enable reg to disable all interrupts */ 239 /* Initial enable reg to disable all interrupts */
233 writel_relaxed(0, reg_base + CK_INTC_NEN31_00); 240 writel(0, reg_base + CK_INTC_NEN31_00);
234 writel_relaxed(0, reg_base + CK_INTC_NEN63_32); 241 writel(0, reg_base + CK_INTC_NEN63_32);
235 242
236 /* Enable irq intc */ 243 /* Enable irq intc */
237 writel_relaxed(BIT(31), reg_base + CK_INTC_ICR); 244 writel(BIT(31), reg_base + CK_INTC_ICR);
238 245
239 ck_set_gc(node, reg_base, CK_INTC_NEN31_00, 0); 246 ck_set_gc(node, reg_base, CK_INTC_NEN31_00, 0);
240 ck_set_gc(node, reg_base, CK_INTC_NEN63_32, 32); 247 ck_set_gc(node, reg_base, CK_INTC_NEN63_32, 32);
@@ -260,8 +267,8 @@ ck_dual_intc_init(struct device_node *node, struct device_node *parent)
260 return ret; 267 return ret;
261 268
262 /* Initial enable reg to disable all interrupts */ 269 /* Initial enable reg to disable all interrupts */
263 writel_relaxed(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE); 270 writel(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE);
264 writel_relaxed(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE); 271 writel(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE);
265 272
266 ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN31_00, 64); 273 ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN31_00, 64);
267 ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN63_32, 96); 274 ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN63_32, 96);