[SPARC64]: Use sun4v VIRQ interfaces as intended.
[deliverable/linux.git] / arch / sparc64 / kernel / irq.c
index 5a92851296c03fd4ef0414e7c19462a2b60b9346..4e9537c967785b1e8d117ba7b50096f857f4ef58 100644 (file)
@@ -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)
This page took 0.026071 seconds and 5 git commands to generate.