[SPARC64]: Program IRQ registers correctly on sun4v.
Need to use hypervisor calls instead of direct register accesses. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@ -152,7 +152,10 @@ void enable_irq(unsigned int irq)
|
|||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
|
||||||
if (tlb_type == hypervisor) {
|
if (tlb_type == hypervisor) {
|
||||||
/* XXX SUN4V: implement me... XXX */
|
int cpu = hard_smp_processor_id();
|
||||||
|
|
||||||
|
sun4v_intr_settarget(irq, cpu);
|
||||||
|
sun4v_intr_setenabled(irq, HV_INTR_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
||||||
unsigned long ver;
|
unsigned long ver;
|
||||||
@ -210,16 +213,20 @@ void disable_irq(unsigned int irq)
|
|||||||
|
|
||||||
imap = bucket->imap;
|
imap = bucket->imap;
|
||||||
if (imap != 0UL) {
|
if (imap != 0UL) {
|
||||||
u32 tmp;
|
if (tlb_type == hypervisor) {
|
||||||
|
sun4v_intr_setenabled(irq, HV_INTR_DISABLED);
|
||||||
|
} else {
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
/* NOTE: We do not want to futz with the IRQ clear registers
|
/* NOTE: We do not want to futz with the IRQ clear registers
|
||||||
* and move the state to IDLE, the SCSI code does call
|
* and move the state to IDLE, the SCSI code does call
|
||||||
* disable_irq() to assure atomicity in the queue cmd
|
* disable_irq() to assure atomicity in the queue cmd
|
||||||
* SCSI adapter driver code. Thus we'd lose interrupts.
|
* SCSI adapter driver code. Thus we'd lose interrupts.
|
||||||
*/
|
*/
|
||||||
tmp = upa_readl(imap);
|
tmp = upa_readl(imap);
|
||||||
tmp &= ~IMAP_VALID;
|
tmp &= ~IMAP_VALID;
|
||||||
upa_writel(tmp, imap);
|
upa_writel(tmp, imap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +264,8 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long
|
|||||||
return __irq(&pil0_dummy_bucket);
|
return __irq(&pil0_dummy_bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 %d %016lx %016lx\n",
|
||||||
@ -633,10 +642,16 @@ static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bp->pil != 0) {
|
if (bp->pil != 0) {
|
||||||
upa_writel(ICLR_IDLE, bp->iclr);
|
if (tlb_type == hypervisor) {
|
||||||
/* Test and add entropy */
|
unsigned int irq = __irq(bp);
|
||||||
if (random & SA_SAMPLE_RANDOM)
|
|
||||||
add_interrupt_randomness(irq);
|
sun4v_intr_setstate(irq, HV_INTR_STATE_IDLE);
|
||||||
|
} else {
|
||||||
|
upa_writel(ICLR_IDLE, bp->iclr);
|
||||||
|
/* Test and add entropy */
|
||||||
|
if (random & SA_SAMPLE_RANDOM)
|
||||||
|
add_interrupt_randomness(irq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
bp->flags &= ~IBF_INPROGRESS;
|
bp->flags &= ~IBF_INPROGRESS;
|
||||||
@ -769,24 +784,32 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
|
|||||||
{
|
{
|
||||||
struct ino_bucket *bucket = get_ino_in_irqaction(p) + ivector_table;
|
struct ino_bucket *bucket = get_ino_in_irqaction(p) + ivector_table;
|
||||||
unsigned long imap = bucket->imap;
|
unsigned long imap = bucket->imap;
|
||||||
unsigned int tid;
|
|
||||||
|
|
||||||
while (!cpu_online(goal_cpu)) {
|
while (!cpu_online(goal_cpu)) {
|
||||||
if (++goal_cpu >= NR_CPUS)
|
if (++goal_cpu >= NR_CPUS)
|
||||||
goal_cpu = 0;
|
goal_cpu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
if (tlb_type == hypervisor) {
|
||||||
tid = goal_cpu << 26;
|
unsigned int irq = __irq(bucket);
|
||||||
tid &= IMAP_AID_SAFARI;
|
|
||||||
} else if (this_is_starfire == 0) {
|
sun4v_intr_settarget(irq, goal_cpu);
|
||||||
tid = goal_cpu << 26;
|
sun4v_intr_setenabled(irq, HV_INTR_ENABLED);
|
||||||
tid &= IMAP_TID_UPA;
|
|
||||||
} else {
|
} else {
|
||||||
tid = (starfire_translate(imap, goal_cpu) << 26);
|
unsigned int tid;
|
||||||
tid &= IMAP_TID_UPA;
|
|
||||||
|
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
||||||
|
tid = goal_cpu << 26;
|
||||||
|
tid &= IMAP_AID_SAFARI;
|
||||||
|
} else if (this_is_starfire == 0) {
|
||||||
|
tid = goal_cpu << 26;
|
||||||
|
tid &= IMAP_TID_UPA;
|
||||||
|
} else {
|
||||||
|
tid = (starfire_translate(imap, goal_cpu) << 26);
|
||||||
|
tid &= IMAP_TID_UPA;
|
||||||
|
}
|
||||||
|
upa_writel(tid | IMAP_VALID, imap);
|
||||||
}
|
}
|
||||||
upa_writel(tid | IMAP_VALID, imap);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (++goal_cpu >= NR_CPUS)
|
if (++goal_cpu >= NR_CPUS)
|
||||||
|
Reference in New Issue
Block a user