]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/sunhme.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / sunhme.c
index 7a72a3112f0ad13722eb0d26e5f970fab1d31216..4e9bd380a5c2ea2b50661627e439da2a9bc2712e 100644 (file)
@@ -2543,25 +2543,36 @@ static struct quattro * __devinit quattro_sbus_find(struct of_device *child)
 }
 
 /* After all quattro cards have been probed, we call these functions
- * to register the IRQ handlers.
+ * to register the IRQ handlers for the cards that have been
+ * successfully probed and skip the cards that failed to initialize
  */
-static void __init quattro_sbus_register_irqs(void)
+static int __init quattro_sbus_register_irqs(void)
 {
        struct quattro *qp;
 
        for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
                struct of_device *op = qp->quattro_dev;
-               int err;
+               int err, qfe_slot, skip = 0;
+
+               for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+                       if (!qp->happy_meals[qfe_slot])
+                               skip = 1;
+               }
+               if (skip)
+                       continue;
 
                err = request_irq(op->irqs[0],
                                  quattro_sbus_interrupt,
                                  IRQF_SHARED, "Quattro",
                                  qp);
                if (err != 0) {
-                       printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err);
-                       panic("QFE request irq");
+                       printk(KERN_ERR "Quattro HME: IRQ registration "
+                              "error %d.\n", err);
+                       return err;
                }
        }
+
+       return 0;
 }
 
 static void quattro_sbus_free_irqs(void)
@@ -2570,6 +2581,14 @@ static void quattro_sbus_free_irqs(void)
 
        for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
                struct of_device *op = qp->quattro_dev;
+               int qfe_slot, skip = 0;
+
+               for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+                       if (!qp->happy_meals[qfe_slot])
+                               skip = 1;
+               }
+               if (skip)
+                       continue;
 
                free_irq(op->irqs[0], qp);
        }
@@ -2629,6 +2648,12 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
        int i, qfe_slot = -1;
        int err = -ENODEV;
 
+       sbus_dp = to_of_device(op->dev.parent)->node;
+
+       /* We can match PCI devices too, do not accept those here. */
+       if (strcmp(sbus_dp->name, "sbus"))
+               return err;
+
        if (is_qfe) {
                qp = quattro_sbus_find(op);
                if (qp == NULL)
@@ -2734,10 +2759,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
        if (qp != NULL)
                hp->happy_flags |= HFLAG_QUATTRO;
 
-       sbus_dp = to_of_device(op->dev.parent)->node;
-       if (is_qfe)
-               sbus_dp = to_of_device(op->dev.parent->parent)->node;
-
        /* Get the supported DVMA burst sizes from our Happy SBUS. */
        hp->happy_bursts = of_getintprop_default(sbus_dp,
                                                 "burst-sizes", 0x00);
@@ -2824,6 +2845,9 @@ err_out_iounmap:
        if (hp->tcvregs)
                of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
 
+       if (qp)
+               qp->happy_meals[qfe_slot] = NULL;
+
 err_out_free_netdev:
        free_netdev(dev);
 
@@ -3281,7 +3305,7 @@ static int __init happy_meal_sbus_init(void)
 
        err = of_register_driver(&hme_sbus_driver, &of_bus_type);
        if (!err)
-               quattro_sbus_register_irqs();
+               err = quattro_sbus_register_irqs();
 
        return err;
 }