aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-02 20:31:36 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-07 01:44:06 -0400
commit861fe90656b8e20d750d73c57088dc52d316ce7b (patch)
tree3f7df274478242ecf9f4186637c9cc38f59b5b8a /arch/sparc64/kernel/irq.c
parent4cad69174f385c183b2bcb369fb4304d8624ab96 (diff)
[SPARC64]: SUN4U PCI-E controller support.
Some minor refactoring in the generic code was necessary for this: 1) This controller requires 8-byte access to the interrupt map and clear register. They are 64-bits on all the other SBUS and PCI controllers anyways, so this was easy to cure. 2) The IMAP register has a different layout and some bits that we need to preserve, so use a read/modify/write when making changes to the IMAP register in generic code. 3) Flushing the entire IOMMU TLB is best done with a single write to a register on this PCI controller, add a iommu->iommu_flushinv for this. Still lacks MSI support, that will come later. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 6241e3dbbd57..3edc18e1b818 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -279,7 +279,7 @@ static void sun4u_irq_enable(unsigned int virt_irq)
279 struct irq_handler_data *data = get_irq_chip_data(virt_irq); 279 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
280 280
281 if (likely(data)) { 281 if (likely(data)) {
282 unsigned long cpuid, imap; 282 unsigned long cpuid, imap, val;
283 unsigned int tid; 283 unsigned int tid;
284 284
285 cpuid = irq_choose_cpu(virt_irq); 285 cpuid = irq_choose_cpu(virt_irq);
@@ -287,7 +287,11 @@ static void sun4u_irq_enable(unsigned int virt_irq)
287 287
288 tid = sun4u_compute_tid(imap, cpuid); 288 tid = sun4u_compute_tid(imap, cpuid);
289 289
290 upa_writel(tid | IMAP_VALID, imap); 290 val = upa_readq(imap);
291 val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
292 IMAP_AID_SAFARI | IMAP_NID_SAFARI);
293 val |= tid | IMAP_VALID;
294 upa_writeq(val, imap);
291 } 295 }
292} 296}
293 297
@@ -297,10 +301,10 @@ static void sun4u_irq_disable(unsigned int virt_irq)
297 301
298 if (likely(data)) { 302 if (likely(data)) {
299 unsigned long imap = data->imap; 303 unsigned long imap = data->imap;
300 u32 tmp = upa_readl(imap); 304 u32 tmp = upa_readq(imap);
301 305
302 tmp &= ~IMAP_VALID; 306 tmp &= ~IMAP_VALID;
303 upa_writel(tmp, imap); 307 upa_writeq(tmp, imap);
304 } 308 }
305} 309}
306 310
@@ -309,7 +313,7 @@ static void sun4u_irq_end(unsigned int virt_irq)
309 struct irq_handler_data *data = get_irq_chip_data(virt_irq); 313 struct irq_handler_data *data = get_irq_chip_data(virt_irq);
310 314
311 if (likely(data)) 315 if (likely(data))
312 upa_writel(ICLR_IDLE, data->iclr); 316 upa_writeq(ICLR_IDLE, data->iclr);
313} 317}
314 318
315static void sun4v_irq_enable(unsigned int virt_irq) 319static void sun4v_irq_enable(unsigned int virt_irq)
@@ -465,7 +469,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
465 469
466 BUG_ON(tlb_type == hypervisor); 470 BUG_ON(tlb_type == hypervisor);
467 471
468 ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; 472 ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
469 bucket = &ivector_table[ino]; 473 bucket = &ivector_table[ino];
470 if (!bucket->virt_irq) { 474 if (!bucket->virt_irq) {
471 bucket->virt_irq = virt_irq_alloc(__irq(bucket)); 475 bucket->virt_irq = virt_irq_alloc(__irq(bucket));