unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 {
        struct irq_handler_data *data;
-       struct ino_bucket *bucket;
        unsigned long hv_err, cookie;
+       struct ino_bucket *bucket;
+       struct irq_desc *desc;
        unsigned int virt_irq;
 
        bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
        if (unlikely(!data))
                return 0;
 
+       /* In order to make the LDC channel startup sequence easier,
+        * especially wrt. locking, we do not let request_irq() enable
+        * the interrupt.
+        */
+       desc = irq_desc + virt_irq;
+       desc->status |= IRQ_NOAUTOEN;
+
        set_irq_chip_data(virt_irq, data);
 
        /* Catch accidental accesses to these things.  IMAP/ICLR handling
 
 /* ldc.c: Logical Domain Channel link-layer protocol driver.
  *
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/kernel.h>
 
 #define DRV_MODULE_NAME                "ldc"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.0"
-#define DRV_MODULE_RELDATE     "June 25, 2007"
+#define DRV_MODULE_VERSION     "1.1"
+#define DRV_MODULE_RELDATE     "July 22, 2008"
 
 static char version[] __devinitdata =
        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
        unsigned long hv_err, flags;
        int err = -EINVAL;
 
-       spin_lock_irqsave(&lp->lock, flags);
-
-       if (!name)
-               goto out_err;
-
-       if (lp->state != LDC_STATE_INIT)
-               goto out_err;
+       if (!name ||
+           (lp->state != LDC_STATE_INIT))
+               return -EINVAL;
 
        snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
        snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
                          IRQF_SAMPLE_RANDOM | IRQF_SHARED,
                          lp->rx_irq_name, lp);
        if (err)
-               goto out_err;
+               return err;
 
        err = request_irq(lp->cfg.tx_irq, ldc_tx,
                          IRQF_SAMPLE_RANDOM | IRQF_SHARED,
                          lp->tx_irq_name, lp);
-       if (err)
-               goto out_free_rx_irq;
+       if (err) {
+               free_irq(lp->cfg.rx_irq, lp);
+               return err;
+       }
+
 
+       spin_lock_irqsave(&lp->lock, flags);
+
+       enable_irq(lp->cfg.rx_irq);
+       enable_irq(lp->cfg.tx_irq);
 
        lp->flags |= LDC_FLAG_REGISTERED_IRQS;
 
        err = -ENODEV;
        hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0);
        if (hv_err)
-               goto out_free_tx_irq;
+               goto out_free_irqs;
 
        hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries);
        if (hv_err)
-               goto out_free_tx_irq;
+               goto out_free_irqs;
 
        hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0);
        if (hv_err)
 out_unmap_tx:
        sun4v_ldc_tx_qconf(lp->id, 0, 0);
 
-out_free_tx_irq:
+out_free_irqs:
        lp->flags &= ~LDC_FLAG_REGISTERED_IRQS;
        free_irq(lp->cfg.tx_irq, lp);
-
-out_free_rx_irq:
        free_irq(lp->cfg.rx_irq, lp);
 
-out_err:
        spin_unlock_irqrestore(&lp->lock, flags);
 
        return err;