From f1024d00f50e9348f6c3848745e5402aa3f17143 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 13 Oct 2007 21:51:37 -0700 Subject: [PATCH] --- yaml --- r: 68631 b: refs/heads/master c: b80e6998120eecec00781658bc43702494117ea8 h: refs/heads/master i: 68629: a52ecb49a867483f68a68a5b6b52f152da2146cf 68627: 999f470a42c7dcbdae0fca469902cb1508bf21b4 68623: 9a813082fc1dee16f6d93ec6340defe21de15e29 v: v3 --- [refs] | 2 +- trunk/arch/sparc64/kernel/irq.c | 37 ++++++++++++++++++-------- trunk/arch/sparc64/kernel/sun4v_ivec.S | 6 ++++- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index 4974ef23308b..7751bae0cb61 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 10397e4069bbcc8219537e7c1e0d6a6935432156 +refs/heads/master: b80e6998120eecec00781658bc43702494117ea8 diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index 5a92851296c0..4e9537c96778 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -643,27 +643,42 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { - unsigned long sysino, hv_err; - unsigned int virq; + struct irq_handler_data *data; + struct ino_bucket *bucket; + unsigned long hv_err, cookie; + + bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); + if (unlikely(!bucket)) + return 0; + + bucket->virt_irq = virt_irq_alloc(__irq(bucket)); + set_irq_chip(bucket->virt_irq, &sun4v_virq); - BUG_ON(devhandle & devino); + data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + if (unlikely(!data)) + return 0; - sysino = devhandle | devino; - BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); + set_irq_chip_data(bucket->virt_irq, data); - hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); + /* Catch accidental accesses to these things. IMAP/ICLR handling + * is done by hypervisor calls on sun4v platforms, not by direct + * register accesses. + */ + data->imap = ~0UL; + data->iclr = ~0UL; + + cookie = ~__pa(bucket); + hv_err = sun4v_vintr_set_cookie(devhandle, devino, cookie); if (hv_err) { prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " "err=%lu\n", devhandle, devino, hv_err); prom_halt(); } - virq = sun4v_build_common(sysino, &sun4v_virq); - - virt_to_real_irq_table[virq].dev_handle = devhandle; - virt_to_real_irq_table[virq].dev_ino = devino; + virt_to_real_irq_table[bucket->virt_irq].dev_handle = devhandle; + virt_to_real_irq_table[bucket->virt_irq].dev_ino = devino; - return virq; + return bucket->virt_irq; } void ack_bad_irq(unsigned int virt_irq) diff --git a/trunk/arch/sparc64/kernel/sun4v_ivec.S b/trunk/arch/sparc64/kernel/sun4v_ivec.S index 16d306445912..e2f8e1b4882a 100644 --- a/trunk/arch/sparc64/kernel/sun4v_ivec.S +++ b/trunk/arch/sparc64/kernel/sun4v_ivec.S @@ -98,13 +98,17 @@ sun4v_dev_mondo: TRAP_LOAD_IRQ_WORK_PA(%g1, %g4) + /* For VIRQs, cookie is encoded as ~bucket_phys_addr */ + brlz,pt %g3, 1f + xnor %g3, %g0, %g4 + /* Get __pa(&ivector_table[IVEC]) into %g4. */ sethi %hi(ivector_table_pa), %g4 ldx [%g4 + %lo(ivector_table_pa)], %g4 sllx %g3, 4, %g3 add %g4, %g3, %g4 - ldx [%g1], %g2 +1: ldx [%g1], %g2 stxa %g2, [%g4] ASI_PHYS_USE_EC stx %g4, [%g1]