aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic
diff options
context:
space:
mode:
authorJayachandran C <jchandra@broadcom.com>2013-12-21 06:22:13 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-24 16:39:46 -0500
commitc24a8a7a99885d5b986f38f6631f69e7794a3e5e (patch)
treea0d6702fc1c45cba157a5734215c509fa4b216c6 /arch/mips/netlogic
parent27547abf36af7964b53a8c9265e266df692d4806 (diff)
MIPS: Netlogic: Add MSI support for XLP
Add MSI chip and MSIX chip definitions. For MSI, we map the link interrupt to a MSI link IRQ which will do a second level of dispatch based on the MSI status register. The MSI chip definitions use the MSI enable register to enable and disable the MSI irqs. For MSI-X, we split the 32 available MSI-X vectors across the four PCIe links (8 each). These PIC interrupts generate an IRQ per link which uses a second level dispatch as well. The MSI-X chip definition uses the standard functions to enable and disable interrupts. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6270/
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r--arch/mips/netlogic/common/irq.c29
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c12
2 files changed, 31 insertions, 10 deletions
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index 1c7e3a1b81ab..3800bf6551ab 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -180,6 +180,7 @@ static void __init nlm_init_percpu_irqs(void)
180#endif 180#endif
181} 181}
182 182
183
183void nlm_setup_pic_irq(int node, int picirq, int irq, int irt) 184void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)
184{ 185{
185 struct nlm_pic_irq *pic_data; 186 struct nlm_pic_irq *pic_data;
@@ -207,24 +208,24 @@ void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
207 208
208static void nlm_init_node_irqs(int node) 209static void nlm_init_node_irqs(int node)
209{ 210{
210 int i, irt;
211 uint64_t irqmask;
212 struct nlm_soc_info *nodep; 211 struct nlm_soc_info *nodep;
212 int i, irt;
213 213
214 pr_info("Init IRQ for node %d\n", node); 214 pr_info("Init IRQ for node %d\n", node);
215 nodep = nlm_get_node(node); 215 nodep = nlm_get_node(node);
216 irqmask = PERCPU_IRQ_MASK; 216 nodep->irqmask = PERCPU_IRQ_MASK;
217 for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) { 217 for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {
218 irt = nlm_irq_to_irt(i); 218 irt = nlm_irq_to_irt(i);
219 if (irt == -1) 219 if (irt == -1) /* unused irq */
220 continue; 220 continue;
221 nlm_setup_pic_irq(node, i, i, irt); 221 nodep->irqmask |= 1ull << i;
222 /* set interrupts to first cpu in node */ 222 if (irt == -2) /* not a direct PIC irq */
223 continue;
224
223 nlm_pic_init_irt(nodep->picbase, irt, i, 225 nlm_pic_init_irt(nodep->picbase, irt, i,
224 node * NLM_CPUS_PER_NODE, 0); 226 node * NLM_CPUS_PER_NODE, 0);
225 irqmask |= (1ull << i); 227 nlm_setup_pic_irq(node, i, i, irt);
226 } 228 }
227 nodep->irqmask = irqmask;
228} 229}
229 230
230void nlm_smp_irq_init(int hwcpuid) 231void nlm_smp_irq_init(int hwcpuid)
@@ -256,6 +257,18 @@ asmlinkage void plat_irq_dispatch(void)
256 return; 257 return;
257 } 258 }
258 259
260#if defined(CONFIG_PCI_MSI) && defined(CONFIG_CPU_XLP)
261 /* PCI interrupts need a second level dispatch for MSI bits */
262 if (i >= PIC_PCIE_LINK_MSI_IRQ(0) && i <= PIC_PCIE_LINK_MSI_IRQ(3)) {
263 nlm_dispatch_msi(node, i);
264 return;
265 }
266 if (i >= PIC_PCIE_MSIX_IRQ(0) && i <= PIC_PCIE_MSIX_IRQ(3)) {
267 nlm_dispatch_msix(node, i);
268 return;
269 }
270
271#endif
259 /* top level irq handling */ 272 /* top level irq handling */
260 do_IRQ(nlm_irq_to_xirq(node, i)); 273 do_IRQ(nlm_irq_to_xirq(node, i));
261} 274}
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 56c50ba43c9b..56930219964b 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -135,9 +135,17 @@ int nlm_irq_to_irt(int irq)
135 case PIC_I2C_3_IRQ: 135 case PIC_I2C_3_IRQ:
136 irt = irt + 3; break; 136 irt = irt + 3; break;
137 } 137 }
138 } else if (irq >= PIC_PCIE_LINK_0_IRQ && irq <= PIC_PCIE_LINK_3_IRQ) { 138 } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) &&
139 irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) {
139 /* HW bug, PCI IRT entries are bad on early silicon, fix */ 140 /* HW bug, PCI IRT entries are bad on early silicon, fix */
140 irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ); 141 irt = PIC_IRT_PCIE_LINK_INDEX(irq -
142 PIC_PCIE_LINK_LEGACY_IRQ_BASE);
143 } else if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) &&
144 irq <= PIC_PCIE_LINK_MSI_IRQ(3)) {
145 irt = -2;
146 } else if (irq >= PIC_PCIE_MSIX_IRQ(0) &&
147 irq <= PIC_PCIE_MSIX_IRQ(3)) {
148 irt = -2;
141 } else { 149 } else {
142 irt = -1; 150 irt = -1;
143 } 151 }