linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / sound / sparc / amd7930.c
index 2bd8e40..5549334 100644 (file)
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/sbus.h>
-#include <asm/prom.h>
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
@@ -336,6 +335,7 @@ struct snd_amd7930 {
        int                     pgain;
        int                     mgain;
 
+       struct sbus_dev         *sdev;
        unsigned int            irq;
        unsigned int            regs_size;
        struct snd_amd7930      *next;
@@ -946,9 +946,11 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
 };
 
 static int __init snd_amd7930_create(struct snd_card *card,
+                                    struct sbus_dev *sdev,
                                     struct resource *rp,
                                     unsigned int reg_size,
-                                    int irq, int dev,
+                                    struct linux_prom_irqs *irq_prop,
+                                    int dev,
                                     struct snd_amd7930 **ramd)
 {
        unsigned long flags;
@@ -962,6 +964,7 @@ static int __init snd_amd7930_create(struct snd_card *card,
 
        spin_lock_init(&amd->lock);
        amd->card = card;
+       amd->sdev = sdev;
        amd->regs_size = reg_size;
 
        amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930");
@@ -972,14 +975,15 @@ static int __init snd_amd7930_create(struct snd_card *card,
 
        amd7930_idle(amd);
 
-       if (request_irq(irq, snd_amd7930_interrupt,
-                       IRQF_DISABLED | IRQF_SHARED, "amd7930", amd)) {
-               snd_printk("amd7930-%d: Unable to grab IRQ %d\n",
-                          dev, irq);
+       if (request_irq(irq_prop->pri, snd_amd7930_interrupt,
+                       SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) {
+               snd_printk("amd7930-%d: Unable to grab IRQ %s\n",
+                          dev,
+                          __irq_itoa(irq_prop->pri));
                snd_amd7930_free(amd);
                return -EBUSY;
        }
-       amd->irq = irq;
+       amd->irq = irq_prop->pri;
 
        amd7930_enable_ints(amd);
 
@@ -1013,35 +1017,60 @@ static int __init snd_amd7930_create(struct snd_card *card,
        return 0;
 }
 
-static int __init amd7930_attach_common(struct resource *rp, int irq)
+static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
 {
-       static int dev_num;
+       static int dev;
+       struct linux_prom_registers reg_prop;
+       struct linux_prom_irqs irq_prop;
+       struct resource res, *rp;
        struct snd_card *card;
        struct snd_amd7930 *amd;
        int err;
 
-       if (dev_num >= SNDRV_CARDS)
+       if (dev >= SNDRV_CARDS)
                return -ENODEV;
-       if (!enable[dev_num]) {
-               dev_num++;
+       if (!enable[dev]) {
+               dev++;
                return -ENOENT;
        }
 
-       card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0);
+       err = prom_getproperty(prom_node, "intr",
+                              (char *) &irq_prop, sizeof(irq_prop));
+       if (err < 0) {
+               snd_printk("amd7930-%d: Firmware node lacks IRQ property.\n", dev);
+               return -ENODEV;
+       }
+
+       err = prom_getproperty(prom_node, "reg",
+                              (char *) &reg_prop, sizeof(reg_prop));
+       if (err < 0) {
+               snd_printk("amd7930-%d: Firmware node lacks register property.\n", dev);
+               return -ENODEV;
+       }
+
+       if (sdev) {
+               rp = &sdev->resource[0];
+       } else {
+               rp = &res;
+               rp->start = reg_prop.phys_addr;
+               rp->end = rp->start + reg_prop.reg_size - 1;
+               rp->flags = IORESOURCE_IO | (reg_prop.which_io & 0xff);
+       }
+
+       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
        if (card == NULL)
                return -ENOMEM;
 
        strcpy(card->driver, "AMD7930");
        strcpy(card->shortname, "Sun AMD7930");
-       sprintf(card->longname, "%s at 0x%02lx:0x%08Lx, irq %d",
+       sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %s",
                card->shortname,
                rp->flags & 0xffL,
-               (unsigned long long)rp->start,
-               irq);
+               rp->start,
+               __irq_itoa(irq_prop.pri));
 
-       if ((err = snd_amd7930_create(card, rp,
-                                     (rp->end - rp->start) + 1,
-                                     irq, dev_num, &amd)) < 0)
+       if ((err = snd_amd7930_create(card, sdev, rp, reg_prop.reg_size,
+                                         &irq_prop, dev, &amd)) < 0)
                goto out_err;
 
        if ((err = snd_amd7930_pcm(amd)) < 0)
@@ -1056,8 +1085,7 @@ static int __init amd7930_attach_common(struct resource *rp, int irq)
        amd->next = amd7930_list;
        amd7930_list = amd;
 
-       dev_num++;
-
+       dev++;
        return 0;
 
 out_err:
@@ -1065,71 +1093,29 @@ out_err:
        return err;
 }
 
-static int __init amd7930_obio_attach(struct device_node *dp)
-{
-       struct linux_prom_registers *regs;
-       struct linux_prom_irqs *irqp;
-       struct resource res, *rp;
-       int len;
-
-       irqp = of_get_property(dp, "intr", &len);
-       if (!irqp) {
-               snd_printk("%s: Firmware node lacks IRQ property.\n",
-                          dp->full_name);
-               return -ENODEV;
-       }
-
-       regs = of_get_property(dp, "reg", &len);
-       if (!regs) {
-               snd_printk("%s: Firmware node lacks register property.\n",
-                          dp->full_name);
-               return -ENODEV;
-       }
-
-       rp = &res;
-       rp->start = regs->phys_addr;
-       rp->end = rp->start + regs->reg_size - 1;
-       rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
-
-       return amd7930_attach_common(rp, irqp->pri);
-}
-
-static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-       return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
-}
-
-static struct of_device_id amd7930_match[] = {
-       {
-               .name = "audio",
-       },
-       {},
-};
-
-static struct of_platform_driver amd7930_sbus_driver = {
-       .name           = "audio",
-       .match_table    = amd7930_match,
-       .probe          = amd7930_sbus_probe,
-};
-
 static int __init amd7930_init(void)
 {
-       struct device_node *dp;
+       struct sbus_bus *sbus;
+       struct sbus_dev *sdev;
+       int node, found;
+
+       found = 0;
 
        /* Try to find the sun4c "audio" node first. */
-       dp = of_find_node_by_path("/");
-       dp = dp->child;
-       while (dp) {
-               if (!strcmp(dp->name, "audio"))
-                       amd7930_obio_attach(dp);
+       node = prom_getchild(prom_root_node);
+       node = prom_searchsiblings(node, "audio");
+       if (node && amd7930_attach(node, NULL) == 0)
+               found++;
 
-               dp = dp->sibling;
+       /* Probe each SBUS for amd7930 chips. */
+       for_all_sbusdev(sdev, sbus) {
+               if (!strcmp(sdev->prom_name, "audio")) {
+                       if (amd7930_attach(sdev->prom_node, sdev) == 0)
+                               found++;
+               }
        }
 
-       /* Probe each SBUS for amd7930 chips. */
-       return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
+       return (found > 0) ? 0 : -EIO;
 }
 
 static void __exit amd7930_exit(void)
@@ -1145,8 +1131,6 @@ static void __exit amd7930_exit(void)
        }
 
        amd7930_list = NULL;
-
-       of_unregister_driver(&amd7930_sbus_driver);
 }
 
 module_init(amd7930_init);