aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r--arch/mips/netlogic/xlr/irq.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/arch/mips/netlogic/xlr/irq.c b/arch/mips/netlogic/xlr/irq.c
index 2033f5656f68..1446d58e364c 100644
--- a/arch/mips/netlogic/xlr/irq.c
+++ b/arch/mips/netlogic/xlr/irq.c
@@ -83,14 +83,71 @@ static void xlr_pic_mask(struct irq_data *d)
83 spin_unlock_irqrestore(&nlm_pic_lock, flags); 83 spin_unlock_irqrestore(&nlm_pic_lock, flags);
84} 84}
85 85
86#ifdef CONFIG_PCI
87/* Extra ACK needed for XLR on chip PCI controller */
88static void xlr_pci_ack(struct irq_data *d)
89{
90 nlm_reg_t *pci_mmio = netlogic_io_mmio(NETLOGIC_IO_PCIX_OFFSET);
91
92 netlogic_read_reg(pci_mmio, (0x140 >> 2));
93}
94
95/* Extra ACK needed for XLS on chip PCIe controller */
96static void xls_pcie_ack(struct irq_data *d)
97{
98 nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
99
100 switch (d->irq) {
101 case PIC_PCIE_LINK0_IRQ:
102 netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
103 break;
104 case PIC_PCIE_LINK1_IRQ:
105 netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
106 break;
107 case PIC_PCIE_LINK2_IRQ:
108 netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
109 break;
110 case PIC_PCIE_LINK3_IRQ:
111 netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
112 break;
113 }
114}
115
116/* For XLS B silicon, the 3,4 PCI interrupts are different */
117static void xls_pcie_ack_b(struct irq_data *d)
118{
119 nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
120
121 switch (d->irq) {
122 case PIC_PCIE_LINK0_IRQ:
123 netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
124 break;
125 case PIC_PCIE_LINK1_IRQ:
126 netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
127 break;
128 case PIC_PCIE_XLSB0_LINK2_IRQ:
129 netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
130 break;
131 case PIC_PCIE_XLSB0_LINK3_IRQ:
132 netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
133 break;
134 }
135}
136#endif
137
86static void xlr_pic_ack(struct irq_data *d) 138static void xlr_pic_ack(struct irq_data *d)
87{ 139{
88 unsigned long flags; 140 unsigned long flags;
89 nlm_reg_t *mmio; 141 nlm_reg_t *mmio;
90 int irq = d->irq; 142 int irq = d->irq;
143 void *hd = irq_data_get_irq_handler_data(d);
91 144
92 WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq); 145 WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
93 146
147 if (hd) {
148 void (*extra_ack)(void *) = hd;
149 extra_ack(d);
150 }
94 mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET); 151 mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
95 spin_lock_irqsave(&nlm_pic_lock, flags); 152 spin_lock_irqsave(&nlm_pic_lock, flags);
96 netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); 153 netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
@@ -162,6 +219,33 @@ void __init init_xlr_irqs(void)
162 nlm_irq_mask |= 219 nlm_irq_mask |=
163 ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE)); 220 ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
164#endif 221#endif
222
223#ifdef CONFIG_PCI
224 /*
225 * For PCI interrupts, we need to ack the PIC controller too, overload
226 * irq handler data to do this
227 */
228 if (nlm_chip_is_xls()) {
229 if (nlm_chip_is_xls_b()) {
230 irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
231 xls_pcie_ack_b);
232 irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
233 xls_pcie_ack_b);
234 irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
235 xls_pcie_ack_b);
236 irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
237 xls_pcie_ack_b);
238 } else {
239 irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
240 irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
241 irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
242 irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
243 }
244 } else {
245 /* XLR PCI controller ACK */
246 irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
247 }
248#endif
165 /* unmask all PIC related interrupts. If no handler is installed by the 249 /* unmask all PIC related interrupts. If no handler is installed by the
166 * drivers, it'll just ack the interrupt and return 250 * drivers, it'll just ack the interrupt and return
167 */ 251 */
@@ -199,7 +283,7 @@ asmlinkage void plat_irq_dispatch(void)
199 return; 283 return;
200 } 284 }
201 285
202 /* TODO use dcltz: optimize below code */ 286 /* use dcltz: optimize below code */
203 for (i = 63; i != -1; i--) { 287 for (i = 63; i != -1; i--) {
204 if (eirr & (1ULL << i)) 288 if (eirr & (1ULL << i))
205 break; 289 break;