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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.6-rc7 169 lines 4.0 kB view raw
1/* 2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling 3 * 4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 7 * 8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 as published 12 * by the Free Software Foundation. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/interrupt.h> 18#include <linux/irqchip.h> 19#include <linux/of_irq.h> 20 21#include <asm/irq_cpu.h> 22#include <asm/mipsregs.h> 23 24#include <asm/mach-ath79/ath79.h> 25#include <asm/mach-ath79/ar71xx_regs.h> 26#include "common.h" 27#include "machtypes.h" 28 29 30static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) 31{ 32 u32 status; 33 34 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); 35 36 if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { 37 ath79_ddr_wb_flush(3); 38 generic_handle_irq(ATH79_IP2_IRQ(0)); 39 } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { 40 ath79_ddr_wb_flush(4); 41 generic_handle_irq(ATH79_IP2_IRQ(1)); 42 } else { 43 spurious_interrupt(); 44 } 45} 46 47static void ar934x_ip2_irq_init(void) 48{ 49 int i; 50 51 for (i = ATH79_IP2_IRQ_BASE; 52 i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) 53 irq_set_chip_and_handler(i, &dummy_irq_chip, 54 handle_level_irq); 55 56 irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); 57} 58 59static void qca955x_ip2_irq_dispatch(struct irq_desc *desc) 60{ 61 u32 status; 62 63 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); 64 status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; 65 66 if (status == 0) { 67 spurious_interrupt(); 68 return; 69 } 70 71 if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { 72 /* TODO: flush DDR? */ 73 generic_handle_irq(ATH79_IP2_IRQ(0)); 74 } 75 76 if (status & QCA955X_EXT_INT_WMAC_ALL) { 77 /* TODO: flush DDR? */ 78 generic_handle_irq(ATH79_IP2_IRQ(1)); 79 } 80} 81 82static void qca955x_ip3_irq_dispatch(struct irq_desc *desc) 83{ 84 u32 status; 85 86 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); 87 status &= QCA955X_EXT_INT_PCIE_RC2_ALL | 88 QCA955X_EXT_INT_USB1 | 89 QCA955X_EXT_INT_USB2; 90 91 if (status == 0) { 92 spurious_interrupt(); 93 return; 94 } 95 96 if (status & QCA955X_EXT_INT_USB1) { 97 /* TODO: flush DDR? */ 98 generic_handle_irq(ATH79_IP3_IRQ(0)); 99 } 100 101 if (status & QCA955X_EXT_INT_USB2) { 102 /* TODO: flush DDR? */ 103 generic_handle_irq(ATH79_IP3_IRQ(1)); 104 } 105 106 if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { 107 /* TODO: flush DDR? */ 108 generic_handle_irq(ATH79_IP3_IRQ(2)); 109 } 110} 111 112static void qca955x_irq_init(void) 113{ 114 int i; 115 116 for (i = ATH79_IP2_IRQ_BASE; 117 i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) 118 irq_set_chip_and_handler(i, &dummy_irq_chip, 119 handle_level_irq); 120 121 irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); 122 123 for (i = ATH79_IP3_IRQ_BASE; 124 i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) 125 irq_set_chip_and_handler(i, &dummy_irq_chip, 126 handle_level_irq); 127 128 irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); 129} 130 131void __init arch_init_irq(void) 132{ 133 unsigned irq_wb_chan2 = -1; 134 unsigned irq_wb_chan3 = -1; 135 bool misc_is_ar71xx; 136 137 if (mips_machtype == ATH79_MACH_GENERIC_OF) { 138 irqchip_init(); 139 return; 140 } 141 142 if (soc_is_ar71xx() || soc_is_ar724x() || 143 soc_is_ar913x() || soc_is_ar933x()) { 144 irq_wb_chan2 = 3; 145 irq_wb_chan3 = 2; 146 } else if (soc_is_ar934x()) { 147 irq_wb_chan3 = 2; 148 } 149 150 ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3); 151 152 if (soc_is_ar71xx() || soc_is_ar913x()) 153 misc_is_ar71xx = true; 154 else if (soc_is_ar724x() || 155 soc_is_ar933x() || 156 soc_is_ar934x() || 157 soc_is_qca955x()) 158 misc_is_ar71xx = false; 159 else 160 BUG(); 161 ath79_misc_irq_init( 162 ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS, 163 ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx); 164 165 if (soc_is_ar934x()) 166 ar934x_ip2_irq_init(); 167 else if (soc_is_qca955x()) 168 qca955x_irq_init(); 169}