Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: ath79: add IRQ handling code for the QCA955X SoCs

The IRQ routing in the QCA955x SoCs is slightly
different from the routing implemented in the
already supported SoCs.

Cc: Rodriguez, Luis <rodrigue@qca.qualcomm.com>
Cc: Giori, Kathy <kgiori@qca.qualcomm.com>
Cc: QCA Linux Team <qca-linux-team@qca.qualcomm.com>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4955/
Signed-off-by: John Crispin <blogic@openwrt.org>

authored by

Gabor Juhos and committed by
John Crispin
53330332 41583c05

+140 -8
+103 -7
arch/mips/ath79/irq.c
··· 103 103 104 104 if (soc_is_ar71xx() || soc_is_ar913x()) 105 105 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 106 - else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) 106 + else if (soc_is_ar724x() || 107 + soc_is_ar933x() || 108 + soc_is_ar934x() || 109 + soc_is_qca955x()) 107 110 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 108 111 else 109 112 BUG(); ··· 153 150 irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); 154 151 } 155 152 153 + static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) 154 + { 155 + u32 status; 156 + 157 + disable_irq_nosync(irq); 158 + 159 + status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); 160 + status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; 161 + 162 + if (status == 0) { 163 + spurious_interrupt(); 164 + goto enable; 165 + } 166 + 167 + if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { 168 + /* TODO: flush DDR? */ 169 + generic_handle_irq(ATH79_IP2_IRQ(0)); 170 + } 171 + 172 + if (status & QCA955X_EXT_INT_WMAC_ALL) { 173 + /* TODO: flush DDR? */ 174 + generic_handle_irq(ATH79_IP2_IRQ(1)); 175 + } 176 + 177 + enable: 178 + enable_irq(irq); 179 + } 180 + 181 + static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) 182 + { 183 + u32 status; 184 + 185 + disable_irq_nosync(irq); 186 + 187 + status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); 188 + status &= QCA955X_EXT_INT_PCIE_RC2_ALL | 189 + QCA955X_EXT_INT_USB1 | 190 + QCA955X_EXT_INT_USB2; 191 + 192 + if (status == 0) { 193 + spurious_interrupt(); 194 + goto enable; 195 + } 196 + 197 + if (status & QCA955X_EXT_INT_USB1) { 198 + /* TODO: flush DDR? */ 199 + generic_handle_irq(ATH79_IP3_IRQ(0)); 200 + } 201 + 202 + if (status & QCA955X_EXT_INT_USB2) { 203 + /* TODO: flush DDR? */ 204 + generic_handle_irq(ATH79_IP3_IRQ(1)); 205 + } 206 + 207 + if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { 208 + /* TODO: flush DDR? */ 209 + generic_handle_irq(ATH79_IP3_IRQ(2)); 210 + } 211 + 212 + enable: 213 + enable_irq(irq); 214 + } 215 + 216 + static void qca955x_irq_init(void) 217 + { 218 + int i; 219 + 220 + for (i = ATH79_IP2_IRQ_BASE; 221 + i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) 222 + irq_set_chip_and_handler(i, &dummy_irq_chip, 223 + handle_level_irq); 224 + 225 + irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); 226 + 227 + for (i = ATH79_IP3_IRQ_BASE; 228 + i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) 229 + irq_set_chip_and_handler(i, &dummy_irq_chip, 230 + handle_level_irq); 231 + 232 + irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); 233 + } 234 + 156 235 asmlinkage void plat_irq_dispatch(void) 157 236 { 158 237 unsigned long pending; ··· 270 185 * Issue a flush in the handlers to ensure that the driver sees 271 186 * the update. 272 187 */ 188 + 189 + static void ath79_default_ip2_handler(void) 190 + { 191 + do_IRQ(ATH79_CPU_IRQ(2)); 192 + } 193 + 194 + static void ath79_default_ip3_handler(void) 195 + { 196 + do_IRQ(ATH79_CPU_IRQ(3)); 197 + } 198 + 273 199 static void ar71xx_ip2_handler(void) 274 200 { 275 201 ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); ··· 302 206 static void ar933x_ip2_handler(void) 303 207 { 304 208 ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); 305 - do_IRQ(ATH79_CPU_IRQ(2)); 306 - } 307 - 308 - static void ar934x_ip2_handler(void) 309 - { 310 209 do_IRQ(ATH79_CPU_IRQ(2)); 311 210 } 312 211 ··· 350 259 ath79_ip2_handler = ar933x_ip2_handler; 351 260 ath79_ip3_handler = ar933x_ip3_handler; 352 261 } else if (soc_is_ar934x()) { 353 - ath79_ip2_handler = ar934x_ip2_handler; 262 + ath79_ip2_handler = ath79_default_ip2_handler; 354 263 ath79_ip3_handler = ar934x_ip3_handler; 264 + } else if (soc_is_qca955x()) { 265 + ath79_ip2_handler = ath79_default_ip2_handler; 266 + ath79_ip3_handler = ath79_default_ip3_handler; 355 267 } else { 356 268 BUG(); 357 269 } ··· 365 271 366 272 if (soc_is_ar934x()) 367 273 ar934x_ip2_irq_init(); 274 + else if (soc_is_qca955x()) 275 + qca955x_irq_init(); 368 276 }
+32
arch/mips/include/asm/mach-ath79/ar71xx_regs.h
··· 300 300 #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac 301 301 302 302 #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 303 + #define QCA955X_RESET_REG_EXT_INT_STATUS 0xac 303 304 304 305 #define MISC_INT_ETHSW BIT(12) 305 306 #define MISC_INT_TIMER4 BIT(10) ··· 398 397 (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \ 399 398 AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ 400 399 AR934X_PCIE_WMAC_INT_PCIE_RC3) 400 + 401 + #define QCA955X_EXT_INT_WMAC_MISC BIT(0) 402 + #define QCA955X_EXT_INT_WMAC_TX BIT(1) 403 + #define QCA955X_EXT_INT_WMAC_RXLP BIT(2) 404 + #define QCA955X_EXT_INT_WMAC_RXHP BIT(3) 405 + #define QCA955X_EXT_INT_PCIE_RC1 BIT(4) 406 + #define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5) 407 + #define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6) 408 + #define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7) 409 + #define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8) 410 + #define QCA955X_EXT_INT_PCIE_RC2 BIT(12) 411 + #define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13) 412 + #define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14) 413 + #define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15) 414 + #define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16) 415 + #define QCA955X_EXT_INT_USB1 BIT(24) 416 + #define QCA955X_EXT_INT_USB2 BIT(28) 417 + 418 + #define QCA955X_EXT_INT_WMAC_ALL \ 419 + (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \ 420 + QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP) 421 + 422 + #define QCA955X_EXT_INT_PCIE_RC1_ALL \ 423 + (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \ 424 + QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \ 425 + QCA955X_EXT_INT_PCIE_RC1_INT3) 426 + 427 + #define QCA955X_EXT_INT_PCIE_RC2_ALL \ 428 + (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \ 429 + QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ 430 + QCA955X_EXT_INT_PCIE_RC2_INT3) 401 431 402 432 #define REV_ID_MAJOR_MASK 0xfff0 403 433 #define REV_ID_MAJOR_AR71XX 0x00a0
+5 -1
arch/mips/include/asm/mach-ath79/irq.h
··· 10 10 #define __ASM_MACH_ATH79_IRQ_H 11 11 12 12 #define MIPS_CPU_IRQ_BASE 0 13 - #define NR_IRQS 48 13 + #define NR_IRQS 51 14 14 15 15 #define ATH79_CPU_IRQ(_x) (MIPS_CPU_IRQ_BASE + (_x)) 16 16 ··· 25 25 #define ATH79_IP2_IRQ_BASE (ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT) 26 26 #define ATH79_IP2_IRQ_COUNT 2 27 27 #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) 28 + 29 + #define ATH79_IP3_IRQ_BASE (ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT) 30 + #define ATH79_IP3_IRQ_COUNT 3 31 + #define ATH79_IP3_IRQ(_x) (ATH79_IP3_IRQ_BASE + (_x)) 28 32 29 33 #include_next <irq.h> 30 34