[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>
This commit is contained in:
@@ -279,7 +279,7 @@ static void sun4u_irq_enable(unsigned int virt_irq)
|
||||
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
|
||||
|
||||
if (likely(data)) {
|
||||
unsigned long cpuid, imap;
|
||||
unsigned long cpuid, imap, val;
|
||||
unsigned int tid;
|
||||
|
||||
cpuid = irq_choose_cpu(virt_irq);
|
||||
@@ -287,7 +287,11 @@ static void sun4u_irq_enable(unsigned int virt_irq)
|
||||
|
||||
tid = sun4u_compute_tid(imap, cpuid);
|
||||
|
||||
upa_writel(tid | IMAP_VALID, imap);
|
||||
val = upa_readq(imap);
|
||||
val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
|
||||
IMAP_AID_SAFARI | IMAP_NID_SAFARI);
|
||||
val |= tid | IMAP_VALID;
|
||||
upa_writeq(val, imap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,10 +301,10 @@ static void sun4u_irq_disable(unsigned int virt_irq)
|
||||
|
||||
if (likely(data)) {
|
||||
unsigned long imap = data->imap;
|
||||
u32 tmp = upa_readl(imap);
|
||||
u32 tmp = upa_readq(imap);
|
||||
|
||||
tmp &= ~IMAP_VALID;
|
||||
upa_writel(tmp, imap);
|
||||
upa_writeq(tmp, imap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +313,7 @@ static void sun4u_irq_end(unsigned int virt_irq)
|
||||
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
|
||||
|
||||
if (likely(data))
|
||||
upa_writel(ICLR_IDLE, data->iclr);
|
||||
upa_writeq(ICLR_IDLE, data->iclr);
|
||||
}
|
||||
|
||||
static void sun4v_irq_enable(unsigned int virt_irq)
|
||||
@@ -465,7 +469,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
|
||||
|
||||
BUG_ON(tlb_type == hypervisor);
|
||||
|
||||
ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
|
||||
ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
|
||||
bucket = &ivector_table[ino];
|
||||
if (!bucket->virt_irq) {
|
||||
bucket->virt_irq = virt_irq_alloc(__irq(bucket));
|
||||
|
Reference in New Issue
Block a user