X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fsparc%2Famd7930.c;h=55493340f467322582a4c5d9662a7d29acb3ef7b;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=2bd8e40b854114436c8e50afcbf42e73141e7815;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 2bd8e40b8..55493340f 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -46,7 +46,6 @@ #include #include #include -#include 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 *) ®_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);