mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 08:46:43 +07:00
[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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c6387a48cf
commit
37cdcd9e82
@ -157,7 +157,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node)
|
||||
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)
|
||||
|
@ -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)
|
||||
|
||||
static struct irqaction *irq_action[NR_IRQS+1];
|
||||
static struct irqaction *irq_action[NR_IRQS];
|
||||
|
||||
/* This only synchronizes entities which modify IRQ handler
|
||||
* state and some selected user-level spots that want to
|
||||
@ -116,12 +116,9 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||
kstat_cpu(j).irqs[i]);
|
||||
}
|
||||
#endif
|
||||
seq_printf(p, " %s:%lx", action->name,
|
||||
get_ino_in_irqaction(action));
|
||||
for (action = action->next; action; action = action->next) {
|
||||
seq_printf(p, ", %s:%lx", action->name,
|
||||
get_ino_in_irqaction(action));
|
||||
}
|
||||
seq_printf(p, " %s", action->name);
|
||||
for (action = action->next; action; action = action->next)
|
||||
seq_printf(p, ", %s", action->name);
|
||||
seq_putc(p, '\n');
|
||||
}
|
||||
out_unlock:
|
||||
@ -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,
|
||||
struct ino_bucket *bucket)
|
||||
{
|
||||
prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> "
|
||||
"(%d:%d:%016lx:%016lx), halting...\n",
|
||||
ino, bucket->pil, bucket->iclr, bucket->imap,
|
||||
pil, inofixup, iclr, imap);
|
||||
prom_printf("IRQ: INO %04x (%016lx:%016lx) --> "
|
||||
"(%d:%016lx:%016lx), halting...\n",
|
||||
ino, bucket->iclr, bucket->imap,
|
||||
inofixup, iclr, imap);
|
||||
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;
|
||||
int ino;
|
||||
|
||||
BUG_ON(pil == 0);
|
||||
BUG_ON(tlb_type == hypervisor);
|
||||
|
||||
/* RULE: Both must be specified in all other cases. */
|
||||
if (iclr == 0UL || imap == 0UL) {
|
||||
prom_printf("Invalid build_irq %d %d %016lx %016lx\n",
|
||||
pil, inofixup, iclr, imap);
|
||||
prom_printf("Invalid build_irq %d %016lx %016lx\n",
|
||||
inofixup, iclr, imap);
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
|
||||
if (ino > NUM_IVECS) {
|
||||
prom_printf("Invalid INO %04x (%d:%d:%016lx:%016lx)\n",
|
||||
ino, pil, inofixup, iclr, imap);
|
||||
prom_printf("Invalid INO %04x (%d:%016lx:%016lx)\n",
|
||||
ino, inofixup, iclr, imap);
|
||||
prom_halt();
|
||||
}
|
||||
|
||||
bucket = &ivector_table[ino];
|
||||
if (bucket->flags & IBF_ACTIVE)
|
||||
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->imap != imap || bucket->iclr != iclr)
|
||||
build_irq_error("IRQ: Trying to reinit INO bucket.\n",
|
||||
ino, pil, inofixup, iclr, imap, bucket);
|
||||
ino, inofixup, iclr, imap, bucket);
|
||||
|
||||
goto out;
|
||||
}
|
||||
@ -302,14 +298,13 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long
|
||||
*/
|
||||
bucket->imap = imap;
|
||||
bucket->iclr = iclr;
|
||||
bucket->pil = pil;
|
||||
bucket->flags = 0;
|
||||
|
||||
out:
|
||||
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;
|
||||
unsigned long sysino;
|
||||
@ -328,7 +323,6 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsign
|
||||
bucket->imap = ~0UL - sysino;
|
||||
bucket->iclr = ~0UL - sysino;
|
||||
|
||||
bucket->pil = pil;
|
||||
bucket->flags = flags;
|
||||
|
||||
bucket->irq_info = kzalloc(sizeof(struct irq_desc), GFP_ATOMIC);
|
||||
@ -356,17 +350,13 @@ static void atomic_bucket_insert(struct ino_bucket *bucket)
|
||||
|
||||
static int check_irq_sharing(int pil, unsigned long irqflags)
|
||||
{
|
||||
struct irqaction *action, *tmp;
|
||||
struct irqaction *action;
|
||||
|
||||
action = *(irq_action + pil);
|
||||
if (action) {
|
||||
if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
|
||||
for (tmp = action; tmp->next; tmp = tmp->next)
|
||||
;
|
||||
} else {
|
||||
if (!(action->flags & SA_SHIRQ) || !(irqflags & SA_SHIRQ))
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
* 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);
|
||||
|
||||
if (check_irq_sharing(bucket->pil, irqflags)) {
|
||||
if (check_irq_sharing(PIL_DEVICE_IRQ, irqflags)) {
|
||||
spin_unlock_irqrestore(&irq_action_lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -454,7 +444,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
|
||||
put_ino_in_irqaction(action, irq);
|
||||
put_smpaff_in_irqaction(action, CPU_MASK_NONE);
|
||||
|
||||
append_irq_action(bucket->pil, action);
|
||||
append_irq_action(PIL_DEVICE_IRQ, action);
|
||||
|
||||
enable_irq(irq);
|
||||
|
||||
@ -478,16 +468,15 @@ EXPORT_SYMBOL(request_irq);
|
||||
|
||||
static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id)
|
||||
{
|
||||
struct ino_bucket *bucket = __bucket(irq);
|
||||
struct irqaction *action, **pp;
|
||||
|
||||
pp = irq_action + bucket->pil;
|
||||
pp = irq_action + PIL_DEVICE_IRQ;
|
||||
action = *pp;
|
||||
if (unlikely(!action))
|
||||
return NULL;
|
||||
|
||||
if (unlikely(!action->handler)) {
|
||||
printk("Freeing free IRQ %d\n", bucket->pil);
|
||||
printk("Freeing free IRQ %d\n", PIL_DEVICE_IRQ);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -648,7 +637,7 @@ static void process_bucket(struct ino_bucket *bp, struct pt_regs *regs)
|
||||
|
||||
/* Test and add entropy */
|
||||
if (random & SA_SAMPLE_RANDOM)
|
||||
add_interrupt_randomness(bp->pil);
|
||||
add_interrupt_randomness(PIL_DEVICE_IRQ);
|
||||
out:
|
||||
bp->flags &= ~IBF_INPROGRESS;
|
||||
}
|
||||
@ -691,7 +680,7 @@ void handler_irq(int irq, struct pt_regs *regs)
|
||||
while (bp) {
|
||||
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;
|
||||
process_bucket(bp, regs);
|
||||
@ -817,16 +806,9 @@ static void distribute_irqs(void)
|
||||
spin_lock_irqsave(&irq_action_lock, flags);
|
||||
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++) {
|
||||
struct irqaction *p = irq_action[level];
|
||||
|
||||
if (level == 12)
|
||||
continue;
|
||||
|
||||
while(p) {
|
||||
cpu = retarget_one_irq(p, cpu);
|
||||
p = p->next;
|
||||
|
@ -276,74 +276,6 @@ static unsigned long __onboard_imap_off[] = {
|
||||
((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((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,
|
||||
struct pci_dev *pdev,
|
||||
unsigned int ino)
|
||||
@ -351,7 +283,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
|
||||
struct ino_bucket *bucket;
|
||||
unsigned long imap, iclr;
|
||||
unsigned long imap_off, iclr_off;
|
||||
int pil, inofixup = 0;
|
||||
int inofixup = 0;
|
||||
|
||||
ino &= PCI_IRQ_INO;
|
||||
if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
|
||||
@ -367,11 +299,6 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
|
||||
}
|
||||
|
||||
/* Now build the IRQ bucket. */
|
||||
pil = psycho_ino_to_pil(pdev, ino);
|
||||
|
||||
if (PIL_RESERVED(pil))
|
||||
BUG();
|
||||
|
||||
imap = pbm->controller_regs + imap_off;
|
||||
imap += 4;
|
||||
|
||||
@ -382,7 +309,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
|
||||
if ((ino & 0x20) == 0)
|
||||
inofixup = ino & 0x03;
|
||||
|
||||
bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
|
||||
bucket = __bucket(build_irq(inofixup, iclr, imap));
|
||||
bucket->flags |= IBF_PCI;
|
||||
|
||||
return __irq(bucket);
|
||||
|
@ -523,78 +523,6 @@ static unsigned long __onboard_imap_off[] = {
|
||||
((ino & 0x20) ? (SABRE_ICLR_SCSI + (((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
|
||||
* 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
|
||||
@ -619,7 +547,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
|
||||
struct ino_bucket *bucket;
|
||||
unsigned long imap, iclr;
|
||||
unsigned long imap_off, iclr_off;
|
||||
int pil, inofixup = 0;
|
||||
int inofixup = 0;
|
||||
|
||||
ino &= PCI_IRQ_INO;
|
||||
if (ino < SABRE_ONBOARD_IRQ_BASE) {
|
||||
@ -635,11 +563,6 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
|
||||
}
|
||||
|
||||
/* Now build the IRQ bucket. */
|
||||
pil = sabre_ino_to_pil(pdev, ino);
|
||||
|
||||
if (PIL_RESERVED(pil))
|
||||
BUG();
|
||||
|
||||
imap = pbm->controller_regs + imap_off;
|
||||
imap += 4;
|
||||
|
||||
@ -650,7 +573,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
|
||||
if ((ino & 0x20) == 0)
|
||||
inofixup = ino & 0x03;
|
||||
|
||||
bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
|
||||
bucket = __bucket(build_irq(inofixup, iclr, imap));
|
||||
bucket->flags |= IBF_PCI;
|
||||
|
||||
if (pdev) {
|
||||
|
@ -232,101 +232,6 @@ static unsigned long schizo_iclr_offset(unsigned long ino)
|
||||
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)
|
||||
{
|
||||
unsigned long sync_reg = (unsigned long) _arg2;
|
||||
@ -372,17 +277,12 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
|
||||
struct ino_bucket *bucket;
|
||||
unsigned long imap, iclr;
|
||||
unsigned long imap_off, iclr_off;
|
||||
int pil, ign_fixup;
|
||||
int ign_fixup;
|
||||
|
||||
ino &= PCI_IRQ_INO;
|
||||
imap_off = schizo_imap_offset(ino);
|
||||
|
||||
/* Now build the IRQ bucket. */
|
||||
pil = schizo_ino_to_pil(pdev, ino);
|
||||
|
||||
if (PIL_RESERVED(pil))
|
||||
BUG();
|
||||
|
||||
imap = pbm->pbm_regs + imap_off;
|
||||
imap += 4;
|
||||
|
||||
@ -405,7 +305,7 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
|
||||
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;
|
||||
|
||||
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,
|
||||
unsigned int devino)
|
||||
{
|
||||
u32 devhandle = pbm->devhandle;
|
||||
int pil;
|
||||
|
||||
pil = 5;
|
||||
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);
|
||||
return sun4v_build_irq(devhandle, devino, IBF_PCI);
|
||||
}
|
||||
|
||||
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)
|
||||
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.
|
||||
* This should conform to both Sunfire/Wildfire server and Fusion
|
||||
* desktop designs.
|
||||
@ -812,21 +782,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
|
||||
struct sbus_iommu *iommu = sbus->iommu;
|
||||
unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
|
||||
unsigned long imap, iclr;
|
||||
int pil, 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();
|
||||
int sbus_level = 0;
|
||||
|
||||
imap = sysio_irq_offsets[ino];
|
||||
if (imap == ((unsigned long)-1)) {
|
||||
prom_printf("get_irq_translations: Bad SYSIO INO[%x] cpu[%d]\n",
|
||||
ino, pil);
|
||||
prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
|
||||
ino);
|
||||
prom_halt();
|
||||
}
|
||||
imap += reg_base;
|
||||
@ -860,7 +821,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
|
||||
|
||||
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. */
|
||||
|
@ -37,14 +37,14 @@ struct irq_desc {
|
||||
* line. Keep this in mind please.
|
||||
*/
|
||||
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
|
||||
* save space we only store the bits we need.
|
||||
*/
|
||||
/*0x00*/unsigned int irq_chain;
|
||||
|
||||
/* PIL to schedule this IVEC at. */
|
||||
/*0x04*/unsigned char pil;
|
||||
/* Virtual interrupt number assigned to this INO. */
|
||||
/*0x04*/unsigned char virt_irq;
|
||||
|
||||
/* If an IVEC arrives while irq_info is NULL, we
|
||||
* set this to notify request_irq() about the event.
|
||||
@ -95,7 +95,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS];
|
||||
|
||||
#define __irq_ino(irq) \
|
||||
(((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 __irq(bucket) ((unsigned int)(unsigned long)(bucket))
|
||||
|
||||
@ -105,8 +104,8 @@ extern struct ino_bucket ivector_table[NUM_IVECS];
|
||||
extern void disable_irq(unsigned int);
|
||||
#define disable_irq_nosync disable_irq
|
||||
extern void enable_irq(unsigned int);
|
||||
extern unsigned int build_irq(int pil, 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 build_irq(int inofixup, unsigned long iclr, unsigned long imap);
|
||||
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);
|
||||
|
||||
static __inline__ void set_softint(unsigned long bits)
|
||||
|
Loading…
Reference in New Issue
Block a user