Commit 37cdcd9e authored by David S. Miller's avatar David S. Miller

[SPARC64]: Kill ino_bucket->pil

And reuse that struct member for virt_irq, which will
be used in future changesets for the implementation of
mapping between real and virtual IRQ numbers.

This nicely kills off a ton of SBUS and PCI controller
PIL assignment code which is no longer necessary.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c6387a48
...@@ -157,7 +157,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node) ...@@ -157,7 +157,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node)
return 0; return 0;
} }
return sun4v_build_irq(sun4v_vdev_devhandle, irq, 5, 0); return sun4v_build_irq(sun4v_vdev_devhandle, irq, 0);
} }
static const char *cpu_mid_prop(void) static const char *cpu_mid_prop(void)
......
...@@ -70,7 +70,7 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY ...@@ -70,7 +70,7 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY
*/ */
#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist)
static struct irqaction *irq_action[NR_IRQS+1]; static struct irqaction *irq_action[NR_IRQS];
/* This only synchronizes entities which modify IRQ handler /* This only synchronizes entities which modify IRQ handler
* state and some selected user-level spots that want to * state and some selected user-level spots that want to
...@@ -116,12 +116,9 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -116,12 +116,9 @@ int show_interrupts(struct seq_file *p, void *v)
kstat_cpu(j).irqs[i]); kstat_cpu(j).irqs[i]);
} }
#endif #endif
seq_printf(p, " %s:%lx", action->name, seq_printf(p, " %s", action->name);
get_ino_in_irqaction(action)); for (action = action->next; action; action = action->next)
for (action = action->next; action; action = action->next) { seq_printf(p, ", %s", action->name);
seq_printf(p, ", %s:%lx", action->name,
get_ino_in_irqaction(action));
}
seq_putc(p, '\n'); seq_putc(p, '\n');
} }
out_unlock: out_unlock:
...@@ -245,48 +242,47 @@ void disable_irq(unsigned int irq) ...@@ -245,48 +242,47 @@ void disable_irq(unsigned int irq)
} }
} }
static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, static void build_irq_error(const char *msg, unsigned int ino, int inofixup,
unsigned long iclr, unsigned long imap, unsigned long iclr, unsigned long imap,
struct ino_bucket *bucket) struct ino_bucket *bucket)
{ {
prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " prom_printf("IRQ: INO %04x (%016lx:%016lx) --> "
"(%d:%d:%016lx:%016lx), halting...\n", "(%d:%016lx:%016lx), halting...\n",
ino, bucket->pil, bucket->iclr, bucket->imap, ino, bucket->iclr, bucket->imap,
pil, inofixup, iclr, imap); inofixup, iclr, imap);
prom_halt(); prom_halt();
} }
unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
{ {
struct ino_bucket *bucket; struct ino_bucket *bucket;
int ino; int ino;
BUG_ON(pil == 0);
BUG_ON(tlb_type == hypervisor); BUG_ON(tlb_type == hypervisor);
/* RULE: Both must be specified in all other cases. */ /* RULE: Both must be specified in all other cases. */
if (iclr == 0UL || imap == 0UL) { if (iclr == 0UL || imap == 0UL) {
prom_printf("Invalid build_irq %d %d %016lx %016lx\n", prom_printf("Invalid build_irq %d %016lx %016lx\n",
pil, inofixup, iclr, imap); inofixup, iclr, imap);
prom_halt(); prom_halt();
} }
ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
if (ino > NUM_IVECS) { if (ino > NUM_IVECS) {
prom_printf("Invalid INO %04x (%d:%d:%016lx:%016lx)\n", prom_printf("Invalid INO %04x (%d:%016lx:%016lx)\n",
ino, pil, inofixup, iclr, imap); ino, inofixup, iclr, imap);
prom_halt(); prom_halt();
} }
bucket = &ivector_table[ino]; bucket = &ivector_table[ino];
if (bucket->flags & IBF_ACTIVE) if (bucket->flags & IBF_ACTIVE)
build_irq_error("IRQ: Trying to build active INO bucket.\n", build_irq_error("IRQ: Trying to build active INO bucket.\n",
ino, pil, inofixup, iclr, imap, bucket); ino, inofixup, iclr, imap, bucket);
if (bucket->irq_info) { if (bucket->irq_info) {
if (bucket->imap != imap || bucket->iclr != iclr) if (bucket->imap != imap || bucket->iclr != iclr)
build_irq_error("IRQ: Trying to reinit INO bucket.\n", build_irq_error("IRQ: Trying to reinit INO bucket.\n",
ino, pil, inofixup, iclr, imap, bucket); ino, inofixup, iclr, imap, bucket);
goto out; goto out;
} }
...@@ -302,14 +298,13 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long ...@@ -302,14 +298,13 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long
*/ */
bucket->imap = imap; bucket->imap = imap;
bucket->iclr = iclr; bucket->iclr = iclr;
bucket->pil = pil;
bucket->flags = 0; bucket->flags = 0;
out: out:
return __irq(bucket); return __irq(bucket);
} }
unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags) unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags)
{ {
struct ino_bucket *bucket; struct ino_bucket *bucket;
unsigned long sysino; unsigned long sysino;
...@@ -328,7 +323,6 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsign ...@@ -328,7 +323,6 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsign
bucket->imap = ~0UL - sysino; bucket->imap = ~0UL - sysino;
bucket->iclr = ~0UL - sysino; bucket->iclr = ~0UL - sysino;
bucket->pil = pil;
bucket->flags = flags; bucket->flags = flags;
bucket->irq_info = kzalloc(sizeof(struct irq_desc), GFP_ATOMIC); bucket->irq_info = kzalloc(sizeof(struct irq_desc), GFP_ATOMIC);
...@@ -356,17 +350,13 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) ...@@ -356,17 +350,13 @@ static void atomic_bucket_insert(struct ino_bucket *bucket)
static int check_irq_sharing(int pil, unsigned long irqflags) static int check_irq_sharing(int pil, unsigned long irqflags)
{ {
struct irqaction *action, *tmp; struct irqaction *action;
action = *(irq_action + pil); action = *(irq_action + pil);
if (action) { if (action) {
if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { if (!(action->flags & SA_SHIRQ) || !(irqflags & SA_SHIRQ))
for (tmp = action; tmp->next; tmp = tmp->next)
;
} else {
return -EBUSY; return -EBUSY;
} }
}
return 0; return 0;
} }
...@@ -425,12 +415,12 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ ...@@ -425,12 +415,12 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
* installing a new handler, but is this really a problem, * installing a new handler, but is this really a problem,
* only the sysadmin is able to do this. * only the sysadmin is able to do this.
*/ */
rand_initialize_irq(irq); rand_initialize_irq(PIL_DEVICE_IRQ);
} }
spin_lock_irqsave(&irq_action_lock, flags); spin_lock_irqsave(&irq_action_lock, flags);
if (check_irq_sharing(bucket->pil, irqflags)) { if (check_irq_sharing(PIL_DEVICE_IRQ, irqflags)) {
spin_unlock_irqrestore(&irq_action_lock, flags); spin_unlock_irqrestore(&irq_action_lock, flags);
return -EBUSY; return -EBUSY;
} }
...@@ -454,7 +444,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ ...@@ -454,7 +444,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
put_ino_in_irqaction(action, irq); put_ino_in_irqaction(action, irq);
put_smpaff_in_irqaction(action, CPU_MASK_NONE); put_smpaff_in_irqaction(action, CPU_MASK_NONE);
append_irq_action(bucket->pil, action); append_irq_action(PIL_DEVICE_IRQ, action);
enable_irq(irq); enable_irq(irq);
...@@ -478,16 +468,15 @@ EXPORT_SYMBOL(request_irq); ...@@ -478,16 +468,15 @@ EXPORT_SYMBOL(request_irq);
static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id)
{ {
struct ino_bucket *bucket = __bucket(irq);
struct irqaction *action, **pp; struct irqaction *action, **pp;
pp = irq_action + bucket->pil; pp = irq_action + PIL_DEVICE_IRQ;
action = *pp; action = *pp;
if (unlikely(!action)) if (unlikely(!action))
return NULL; return NULL;
if (unlikely(!action->handler)) { if (unlikely(!action->handler)) {
printk("Freeing free IRQ %d\n", bucket->pil); printk("Freeing free IRQ %d\n", PIL_DEVICE_IRQ);
return NULL; return NULL;
} }
...@@ -648,7 +637,7 @@ static void process_bucket(struct ino_bucket *bp, struct pt_regs *regs) ...@@ -648,7 +637,7 @@ static void process_bucket(struct ino_bucket *bp, struct pt_regs *regs)
/* Test and add entropy */ /* Test and add entropy */
if (random & SA_SAMPLE_RANDOM) if (random & SA_SAMPLE_RANDOM)
add_interrupt_randomness(bp->pil); add_interrupt_randomness(PIL_DEVICE_IRQ);
out: out:
bp->flags &= ~IBF_INPROGRESS; bp->flags &= ~IBF_INPROGRESS;
} }
...@@ -691,7 +680,7 @@ void handler_irq(int irq, struct pt_regs *regs) ...@@ -691,7 +680,7 @@ void handler_irq(int irq, struct pt_regs *regs)
while (bp) { while (bp) {
struct ino_bucket *nbp = __bucket(bp->irq_chain); struct ino_bucket *nbp = __bucket(bp->irq_chain);
kstat_this_cpu.irqs[bp->pil]++; kstat_this_cpu.irqs[bp->virt_irq]++;
bp->irq_chain = 0; bp->irq_chain = 0;
process_bucket(bp, regs); process_bucket(bp, regs);
...@@ -817,16 +806,9 @@ static void distribute_irqs(void) ...@@ -817,16 +806,9 @@ static void distribute_irqs(void)
spin_lock_irqsave(&irq_action_lock, flags); spin_lock_irqsave(&irq_action_lock, flags);
cpu = 0; cpu = 0;
/*
* Skip the timer at [0], and very rare error/power intrs at [15].
* Also level [12], it causes problems on Ex000 systems.
*/
for (level = 1; level < NR_IRQS; level++) { for (level = 1; level < NR_IRQS; level++) {
struct irqaction *p = irq_action[level]; struct irqaction *p = irq_action[level];
if (level == 12)
continue;
while(p) { while(p) {
cpu = retarget_one_irq(p, cpu); cpu = retarget_one_irq(p, cpu);
p = p->next; p = p->next;
......
...@@ -276,74 +276,6 @@ static unsigned long __onboard_imap_off[] = { ...@@ -276,74 +276,6 @@ static unsigned long __onboard_imap_off[] = {
((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
(PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
/* PCI PSYCHO INO number to Sparc PIL level. */
static unsigned char psycho_pil_table[] = {
/*0x00*/0, 0, 0, 0, /* PCI A slot 0 Int A, B, C, D */
/*0x04*/0, 0, 0, 0, /* PCI A slot 1 Int A, B, C, D */
/*0x08*/0, 0, 0, 0, /* PCI A slot 2 Int A, B, C, D */
/*0x0c*/0, 0, 0, 0, /* PCI A slot 3 Int A, B, C, D */
/*0x10*/0, 0, 0, 0, /* PCI B slot 0 Int A, B, C, D */
/*0x14*/0, 0, 0, 0, /* PCI B slot 1 Int A, B, C, D */
/*0x18*/0, 0, 0, 0, /* PCI B slot 2 Int A, B, C, D */
/*0x1c*/0, 0, 0, 0, /* PCI B slot 3 Int A, B, C, D */
/*0x20*/5, /* SCSI */
/*0x21*/5, /* Ethernet */
/*0x22*/8, /* Parallel Port */
/*0x23*/13, /* Audio Record */
/*0x24*/14, /* Audio Playback */
/*0x25*/15, /* PowerFail */
/*0x26*/5, /* second SCSI */
/*0x27*/11, /* Floppy */
/*0x28*/5, /* Spare Hardware */
/*0x29*/9, /* Keyboard */
/*0x2a*/5, /* Mouse */
/*0x2b*/12, /* Serial */
/*0x2c*/10, /* Timer 0 */
/*0x2d*/11, /* Timer 1 */
/*0x2e*/15, /* Uncorrectable ECC */
/*0x2f*/15, /* Correctable ECC */
/*0x30*/15, /* PCI Bus A Error */
/*0x31*/15, /* PCI Bus B Error */
/*0x32*/15, /* Power Management */
};
static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
ret = psycho_pil_table[ino];
if (ret == 0 && pdev == NULL) {
ret = 5;
} else if (ret == 0) {
switch ((pdev->class >> 16) & 0xff) {
case PCI_BASE_CLASS_STORAGE:
ret = 5;
break;
case PCI_BASE_CLASS_NETWORK:
ret = 6;
break;
case PCI_BASE_CLASS_DISPLAY:
ret = 9;
break;
case PCI_BASE_CLASS_MULTIMEDIA:
case PCI_BASE_CLASS_MEMORY:
case PCI_BASE_CLASS_BRIDGE:
case PCI_BASE_CLASS_SERIAL:
ret = 10;
break;
default:
ret = 5;
break;
};
}
return ret;
}
static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
struct pci_dev *pdev, struct pci_dev *pdev,
unsigned int ino) unsigned int ino)
...@@ -351,7 +283,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, ...@@ -351,7 +283,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
struct ino_bucket *bucket; struct ino_bucket *bucket;
unsigned long imap, iclr; unsigned long imap, iclr;
unsigned long imap_off, iclr_off; unsigned long imap_off, iclr_off;
int pil, inofixup = 0; int inofixup = 0;
ino &= PCI_IRQ_INO; ino &= PCI_IRQ_INO;
if (ino < PSYCHO_ONBOARD_IRQ_BASE) { if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
...@@ -367,11 +299,6 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, ...@@ -367,11 +299,6 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
} }
/* Now build the IRQ bucket. */ /* Now build the IRQ bucket. */
pil = psycho_ino_to_pil(pdev, ino);
if (PIL_RESERVED(pil))
BUG();
imap = pbm->controller_regs + imap_off; imap = pbm->controller_regs + imap_off;
imap += 4; imap += 4;
...@@ -382,7 +309,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, ...@@ -382,7 +309,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
if ((ino & 0x20) == 0) if ((ino & 0x20) == 0)
inofixup = ino & 0x03; inofixup = ino & 0x03;
bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); bucket = __bucket(build_irq(inofixup, iclr, imap));
bucket->flags |= IBF_PCI; bucket->flags |= IBF_PCI;
return __irq(bucket); return __irq(bucket);
......
...@@ -523,78 +523,6 @@ static unsigned long __onboard_imap_off[] = { ...@@ -523,78 +523,6 @@ static unsigned long __onboard_imap_off[] = {
((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
(SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
/* PCI SABRE INO number to Sparc PIL level. */
static unsigned char sabre_pil_table[] = {
/*0x00*/0, 0, 0, 0, /* PCI A slot 0 Int A, B, C, D */
/*0x04*/0, 0, 0, 0, /* PCI A slot 1 Int A, B, C, D */
/*0x08*/0, 0, 0, 0, /* PCI A slot 2 Int A, B, C, D */
/*0x0c*/0, 0, 0, 0, /* PCI A slot 3 Int A, B, C, D */
/*0x10*/0, 0, 0, 0, /* PCI B slot 0 Int A, B, C, D */
/*0x14*/0, 0, 0, 0, /* PCI B slot 1 Int A, B, C, D */
/*0x18*/0, 0, 0, 0, /* PCI B slot 2 Int A, B, C, D */
/*0x1c*/0, 0, 0, 0, /* PCI B slot 3 Int A, B, C, D */
/*0x20*/5, /* SCSI */
/*0x21*/5, /* Ethernet */
/*0x22*/8, /* Parallel Port */
/*0x23*/13, /* Audio Record */
/*0x24*/14, /* Audio Playback */
/*0x25*/15, /* PowerFail */
/*0x26*/5, /* second SCSI */
/*0x27*/11, /* Floppy */
/*0x28*/5, /* Spare Hardware */
/*0x29*/9, /* Keyboard */
/*0x2a*/5, /* Mouse */
/*0x2b*/12, /* Serial */
/*0x2c*/10, /* Timer 0 */
/*0x2d*/11, /* Timer 1 */
/*0x2e*/15, /* Uncorrectable ECC */
/*0x2f*/15, /* Correctable ECC */
/*0x30*/15, /* PCI Bus A Error */
/*0x31*/15, /* PCI Bus B Error */
/*0x32*/15, /* Power Management */
};
static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
if (pdev &&
pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
return 9;
ret = sabre_pil_table[ino];
if (ret == 0 && pdev == NULL) {
ret = 5;
} else if (ret == 0) {
switch ((pdev->class >> 16) & 0xff) {
case PCI_BASE_CLASS_STORAGE:
ret = 5;
break;
case PCI_BASE_CLASS_NETWORK:
ret = 6;
break;
case PCI_BASE_CLASS_DISPLAY:
ret = 9;
break;
case PCI_BASE_CLASS_MULTIMEDIA:
case PCI_BASE_CLASS_MEMORY:
case PCI_BASE_CLASS_BRIDGE:
case PCI_BASE_CLASS_SERIAL:
ret = 10;
break;
default:
ret = 5;
break;
};
}
return ret;
}
/* When a device lives behind a bridge deeper in the PCI bus topology /* When a device lives behind a bridge deeper in the PCI bus topology
* than APB, a special sequence must run to make sure all pending DMA * than APB, a special sequence must run to make sure all pending DMA
* transfers at the time of IRQ delivery are visible in the coherency * transfers at the time of IRQ delivery are visible in the coherency
...@@ -619,7 +547,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, ...@@ -619,7 +547,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
struct ino_bucket *bucket; struct ino_bucket *bucket;
unsigned long imap, iclr; unsigned long imap, iclr;
unsigned long imap_off, iclr_off; unsigned long imap_off, iclr_off;
int pil, inofixup = 0; int inofixup = 0;
ino &= PCI_IRQ_INO; ino &= PCI_IRQ_INO;
if (ino < SABRE_ONBOARD_IRQ_BASE) { if (ino < SABRE_ONBOARD_IRQ_BASE) {
...@@ -635,11 +563,6 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, ...@@ -635,11 +563,6 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
} }
/* Now build the IRQ bucket. */ /* Now build the IRQ bucket. */
pil = sabre_ino_to_pil(pdev, ino);
if (PIL_RESERVED(pil))
BUG();
imap = pbm->controller_regs + imap_off; imap = pbm->controller_regs + imap_off;
imap += 4; imap += 4;
...@@ -650,7 +573,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, ...@@ -650,7 +573,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
if ((ino & 0x20) == 0) if ((ino & 0x20) == 0)
inofixup = ino & 0x03; inofixup = ino & 0x03;
bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); bucket = __bucket(build_irq(inofixup, iclr, imap));
bucket->flags |= IBF_PCI; bucket->flags |= IBF_PCI;
if (pdev) { if (pdev) {
......
...@@ -232,101 +232,6 @@ static unsigned long schizo_iclr_offset(unsigned long ino) ...@@ -232,101 +232,6 @@ static unsigned long schizo_iclr_offset(unsigned long ino)
return SCHIZO_ICLR_BASE + (ino * 8UL); return SCHIZO_ICLR_BASE + (ino * 8UL);
} }
/* PCI SCHIZO INO number to Sparc PIL level. This table only matters for
* INOs which will not have an associated PCI device struct, ie. onboard
* EBUS devices and PCI controller internal error interrupts.
*/
static unsigned char schizo_pil_table[] = {
/*0x00*/0, 0, 0, 0, /* PCI slot 0 Int A, B, C, D */
/*0x04*/0, 0, 0, 0, /* PCI slot 1 Int A, B, C, D */
/*0x08*/0, 0, 0, 0, /* PCI slot 2 Int A, B, C, D */
/*0x0c*/0, 0, 0, 0, /* PCI slot 3 Int A, B, C, D */
/*0x10*/0, 0, 0, 0, /* PCI slot 4 Int A, B, C, D */
/*0x14*/0, 0, 0, 0, /* PCI slot 5 Int A, B, C, D */
/*0x18*/5, /* SCSI */
/*0x19*/5, /* second SCSI */
/*0x1a*/0, /* UNKNOWN */
/*0x1b*/0, /* UNKNOWN */
/*0x1c*/8, /* Parallel */
/*0x1d*/5, /* Ethernet */
/*0x1e*/8, /* Firewire-1394 */
/*0x1f*/9, /* USB */
/*0x20*/13, /* Audio Record */
/*0x21*/14, /* Audio Playback */
/*0x22*/12, /* Serial */
/*0x23*/5, /* EBUS I2C */
/*0x24*/10, /* RTC Clock */
/*0x25*/11, /* Floppy */
/*0x26*/0, /* UNKNOWN */
/*0x27*/0, /* UNKNOWN */
/*0x28*/0, /* UNKNOWN */
/*0x29*/0, /* UNKNOWN */
/*0x2a*/10, /* UPA 1 */
/*0x2b*/10, /* UPA 2 */
/*0x2c*/0, /* UNKNOWN */
/*0x2d*/0, /* UNKNOWN */
/*0x2e*/0, /* UNKNOWN */
/*0x2f*/0, /* UNKNOWN */
/*0x30*/15, /* Uncorrectable ECC */
/*0x31*/15, /* Correctable ECC */
/*0x32*/15, /* PCI Bus A Error */
/*0x33*/15, /* PCI Bus B Error */
/*0x34*/15, /* Safari Bus Error */
/*0x35*/0, /* Reserved */
/*0x36*/0, /* Reserved */
/*0x37*/0, /* Reserved */
/*0x38*/0, /* Reserved for NewLink */
/*0x39*/0, /* Reserved for NewLink */
/*0x3a*/0, /* Reserved for NewLink */
/*0x3b*/0, /* Reserved for NewLink */
/*0x3c*/0, /* Reserved for NewLink */
/*0x3d*/0, /* Reserved for NewLink */
/*0x3e*/0, /* Reserved for NewLink */
/*0x3f*/0, /* Reserved for NewLink */
};
static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
if (pdev &&
pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
return 9;
ret = schizo_pil_table[ino];
if (ret == 0 && pdev == NULL) {
ret = 5;
} else if (ret == 0) {
switch ((pdev->class >> 16) & 0xff) {
case PCI_BASE_CLASS_STORAGE:
ret = 5;
break;
case PCI_BASE_CLASS_NETWORK:
ret = 6;
break;
case PCI_BASE_CLASS_DISPLAY:
ret = 9;
break;
case PCI_BASE_CLASS_MULTIMEDIA:
case PCI_BASE_CLASS_MEMORY:
case PCI_BASE_CLASS_BRIDGE:
case PCI_BASE_CLASS_SERIAL:
ret = 10;
break;
default:
ret = 5;
break;
};
}
return ret;
}
static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
{ {
unsigned long sync_reg = (unsigned long) _arg2; unsigned long sync_reg = (unsigned long) _arg2;
...@@ -372,17 +277,12 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, ...@@ -372,17 +277,12 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
struct ino_bucket *bucket; struct ino_bucket *bucket;
unsigned long imap, iclr; unsigned long imap, iclr;
unsigned long imap_off, iclr_off; unsigned long imap_off, iclr_off;
int pil, ign_fixup; int ign_fixup;
ino &= PCI_IRQ_INO; ino &= PCI_IRQ_INO;
imap_off = schizo_imap_offset(ino); imap_off = schizo_imap_offset(ino);
/* Now build the IRQ bucket. */ /* Now build the IRQ bucket. */
pil = schizo_ino_to_pil(pdev, ino);
if (PIL_RESERVED(pil))
BUG();
imap = pbm->pbm_regs + imap_off; imap = pbm->pbm_regs + imap_off;
imap += 4; imap += 4;
...@@ -405,7 +305,7 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, ...@@ -405,7 +305,7 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
ign_fixup = (1 << 6); ign_fixup = (1 << 6);
} }
bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket = __bucket(build_irq(ign_fixup, iclr, imap));
bucket->flags |= IBF_PCI; bucket->flags |= IBF_PCI;
if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
......
...@@ -843,38 +843,8 @@ static unsigned int pci_sun4v_irq_build(struct pci_pbm_info *pbm, ...@@ -843,38 +843,8 @@ static unsigned int pci_sun4v_irq_build(struct pci_pbm_info *pbm,
unsigned int devino) unsigned int devino)
{ {
u32 devhandle = pbm->devhandle; u32 devhandle = pbm->devhandle;
int pil;
pil = 5; return sun4v_build_irq(devhandle, devino, IBF_PCI);
if (pdev) {
switch ((pdev->class >> 16) & 0xff) {
case PCI_BASE_CLASS_STORAGE:
pil = 5;
break;
case PCI_BASE_CLASS_NETWORK:
pil = 6;
break;
case PCI_BASE_CLASS_DISPLAY:
pil = 9;
break;
case PCI_BASE_CLASS_MULTIMEDIA:
case PCI_BASE_CLASS_MEMORY:
case PCI_BASE_CLASS_BRIDGE:
case PCI_BASE_CLASS_SERIAL:
pil = 10;
break;
default:
pil = 5;
break;
};
}
BUG_ON(PIL_RESERVED(pil));
return sun4v_build_irq(devhandle, devino, pil, IBF_PCI);
} }
static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource)
......
...@@ -691,36 +691,6 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) ...@@ -691,36 +691,6 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts)
upa_writeq(val, cfg_reg); upa_writeq(val, cfg_reg);
} }
/* SBUS SYSIO INO number to Sparc PIL level. */
static unsigned char sysio_ino_to_pil[] = {
0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 0 */
0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 1 */
0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 2 */
0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 3 */
5, /* Onboard SCSI */
5, /* Onboard Ethernet */
/*XXX*/ 8, /* Onboard BPP */
0, /* Bogon */
13, /* Audio */
/*XXX*/15, /* PowerFail */
0, /* Bogon */
0, /* Bogon */
12, /* Zilog Serial Channels (incl. Keyboard/Mouse lines) */
11, /* Floppy */
0, /* Spare Hardware (bogon for now) */
0, /* Keyboard (bogon for now) */
0, /* Mouse (bogon for now) */
0, /* Serial (bogon for now) */
0, 0, /* Bogon, Bogon */
10, /* Timer 0 */
11, /* Timer 1 */
0, 0, /* Bogon, Bogon */
15, /* Uncorrectable SBUS Error */
15, /* Correctable SBUS Error */
15, /* SBUS Error */
/*XXX*/ 0, /* Power Management (bogon for now) */
};
/* INO number to IMAP register offset for SYSIO external IRQ's. /* INO number to IMAP register offset for SYSIO external IRQ's.
* This should conform to both Sunfire/Wildfire server and Fusion * This should conform to both Sunfire/Wildfire server and Fusion
* desktop designs. * desktop designs.
...@@ -812,21 +782,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) ...@@ -812,21 +782,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
struct sbus_iommu *iommu = sbus->iommu; struct sbus_iommu *iommu = sbus->iommu;
unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
unsigned long imap, iclr; unsigned long imap, iclr;
int pil, sbus_level = 0; int sbus_level = 0;
pil = sysio_ino_to_pil[ino];
if (!pil) {
printk("sbus_irq_build: Bad SYSIO INO[%x]\n", ino);
panic("Bad SYSIO IRQ translations...");
}
if (PIL_RESERVED(pil))
BUG();
imap = sysio_irq_offsets[ino]; imap = sysio_irq_offsets[ino];
if (imap == ((unsigned long)-1)) { if (imap == ((unsigned long)-1)) {
prom_printf("get_irq_translations: Bad SYSIO INO[%x] cpu[%d]\n", prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
ino, pil); ino);
prom_halt(); prom_halt();
} }
imap += reg_base; imap += reg_base;
...@@ -860,7 +821,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) ...@@ -860,7 +821,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
iclr += ((unsigned long)sbus_level - 1UL) * 8UL; iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
} }
return build_irq(pil, sbus_level, iclr, imap); return build_irq(sbus_level, iclr, imap);
} }
/* Error interrupt handling. */ /* Error interrupt handling. */
......
...@@ -37,14 +37,14 @@ struct irq_desc { ...@@ -37,14 +37,14 @@ struct irq_desc {
* line. Keep this in mind please. * line. Keep this in mind please.
*/ */
struct ino_bucket { struct ino_bucket {
/* Next handler in per-CPU PIL worklist. We know that /* Next handler in per-CPU IRQ worklist. We know that
* bucket pointers have the high 32-bits clear, so to * bucket pointers have the high 32-bits clear, so to
* save space we only store the bits we need. * save space we only store the bits we need.
*/ */
/*0x00*/unsigned int irq_chain; /*0x00*/unsigned int irq_chain;
/* PIL to schedule this IVEC at. */ /* Virtual interrupt number assigned to this INO. */
/*0x04*/unsigned char pil; /*0x04*/unsigned char virt_irq;
/* If an IVEC arrives while irq_info is NULL, we /* If an IVEC arrives while irq_info is NULL, we
* set this to notify request_irq() about the event. * set this to notify request_irq() about the event.
...@@ -95,7 +95,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; ...@@ -95,7 +95,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS];
#define __irq_ino(irq) \ #define __irq_ino(irq) \
(((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0])
#define __irq_pil(irq) ((struct ino_bucket *)(unsigned long)(irq))->pil
#define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq))
#define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) #define __irq(bucket) ((unsigned int)(unsigned long)(bucket))
...@@ -105,8 +104,8 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; ...@@ -105,8 +104,8 @@ extern struct ino_bucket ivector_table[NUM_IVECS];
extern void disable_irq(unsigned int); extern void disable_irq(unsigned int);
#define disable_irq_nosync disable_irq #define disable_irq_nosync disable_irq
extern void enable_irq(unsigned int); extern void enable_irq(unsigned int);
extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags); extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags);
extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
static __inline__ void set_softint(unsigned long bits) static __inline__ void set_softint(unsigned long bits)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment