Commit 69b5c4f1 authored by David S. Miller's avatar David S. Miller

[SOUND] sparc: Port amd7930 to new SBUS device layer.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 576c352e
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/sbus.h> #include <asm/sbus.h>
#include <asm/prom.h>
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
...@@ -335,7 +336,6 @@ struct snd_amd7930 { ...@@ -335,7 +336,6 @@ struct snd_amd7930 {
int pgain; int pgain;
int mgain; int mgain;
struct sbus_dev *sdev;
unsigned int irq; unsigned int irq;
unsigned int regs_size; unsigned int regs_size;
struct snd_amd7930 *next; struct snd_amd7930 *next;
...@@ -946,11 +946,9 @@ static struct snd_device_ops snd_amd7930_dev_ops = { ...@@ -946,11 +946,9 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
}; };
static int __init snd_amd7930_create(struct snd_card *card, static int __init snd_amd7930_create(struct snd_card *card,
struct sbus_dev *sdev,
struct resource *rp, struct resource *rp,
unsigned int reg_size, unsigned int reg_size,
struct linux_prom_irqs *irq_prop, int irq, int dev,
int dev,
struct snd_amd7930 **ramd) struct snd_amd7930 **ramd)
{ {
unsigned long flags; unsigned long flags;
...@@ -964,7 +962,6 @@ static int __init snd_amd7930_create(struct snd_card *card, ...@@ -964,7 +962,6 @@ static int __init snd_amd7930_create(struct snd_card *card,
spin_lock_init(&amd->lock); spin_lock_init(&amd->lock);
amd->card = card; amd->card = card;
amd->sdev = sdev;
amd->regs_size = reg_size; amd->regs_size = reg_size;
amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930");
...@@ -975,15 +972,14 @@ static int __init snd_amd7930_create(struct snd_card *card, ...@@ -975,15 +972,14 @@ static int __init snd_amd7930_create(struct snd_card *card,
amd7930_idle(amd); amd7930_idle(amd);
if (request_irq(irq_prop->pri, snd_amd7930_interrupt, if (request_irq(irq, snd_amd7930_interrupt,
SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) { SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) {
snd_printk("amd7930-%d: Unable to grab IRQ %d\n", snd_printk("amd7930-%d: Unable to grab IRQ %d\n",
dev, dev, irq);
irq_prop->pri);
snd_amd7930_free(amd); snd_amd7930_free(amd);
return -EBUSY; return -EBUSY;
} }
amd->irq = irq_prop->pri; amd->irq = irq;
amd7930_enable_ints(amd); amd7930_enable_ints(amd);
...@@ -1017,47 +1013,21 @@ static int __init snd_amd7930_create(struct snd_card *card, ...@@ -1017,47 +1013,21 @@ static int __init snd_amd7930_create(struct snd_card *card,
return 0; return 0;
} }
static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) static int __init amd7930_attach_common(struct resource *rp, int irq)
{ {
static int dev; static int dev_num;
struct linux_prom_registers reg_prop;
struct linux_prom_irqs irq_prop;
struct resource res, *rp;
struct snd_card *card; struct snd_card *card;
struct snd_amd7930 *amd; struct snd_amd7930 *amd;
int err; int err;
if (dev >= SNDRV_CARDS) if (dev_num >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
if (!enable[dev]) { if (!enable[dev_num]) {
dev++; dev_num++;
return -ENOENT; return -ENOENT;
} }
err = prom_getproperty(prom_node, "intr", card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0);
(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) if (card == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -1067,10 +1037,11 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) ...@@ -1067,10 +1037,11 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
card->shortname, card->shortname,
rp->flags & 0xffL, rp->flags & 0xffL,
rp->start, rp->start,
irq_prop.pri); irq);
if ((err = snd_amd7930_create(card, sdev, rp, reg_prop.reg_size, if ((err = snd_amd7930_create(card, rp,
&irq_prop, dev, &amd)) < 0) (rp->end - rp->start) + 1,
irq, dev_num, &amd)) < 0)
goto out_err; goto out_err;
if ((err = snd_amd7930_pcm(amd)) < 0) if ((err = snd_amd7930_pcm(amd)) < 0)
...@@ -1085,7 +1056,8 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) ...@@ -1085,7 +1056,8 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
amd->next = amd7930_list; amd->next = amd7930_list;
amd7930_list = amd; amd7930_list = amd;
dev++; dev_num++;
return 0; return 0;
out_err: out_err:
...@@ -1093,29 +1065,71 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) ...@@ -1093,29 +1065,71 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
return err; return err;
} }
static int __init amd7930_init(void) 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_bus *sbus; struct sbus_dev *sdev = to_sbus_device(&dev->dev);
struct sbus_dev *sdev;
int node, found; return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
}
static struct of_device_id amd7930_match[] = {
{
.name = "audio",
},
{},
};
found = 0; 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;
/* Try to find the sun4c "audio" node first. */ /* Try to find the sun4c "audio" node first. */
node = prom_getchild(prom_root_node); dp = of_find_node_by_path("/");
node = prom_searchsiblings(node, "audio"); dp = dp->child;
if (node && amd7930_attach(node, NULL) == 0) while (dp) {
found++; if (!strcmp(dp->name, "audio"))
amd7930_obio_attach(dp);
/* Probe each SBUS for amd7930 chips. */ dp = dp->sibling;
for_all_sbusdev(sdev, sbus) {
if (!strcmp(sdev->prom_name, "audio")) {
if (amd7930_attach(sdev->prom_node, sdev) == 0)
found++;
}
} }
return (found > 0) ? 0 : -EIO; /* Probe each SBUS for amd7930 chips. */
return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
} }
static void __exit amd7930_exit(void) static void __exit amd7930_exit(void)
...@@ -1131,6 +1145,8 @@ static void __exit amd7930_exit(void) ...@@ -1131,6 +1145,8 @@ static void __exit amd7930_exit(void)
} }
amd7930_list = NULL; amd7930_list = NULL;
of_unregister_driver(&amd7930_sbus_driver);
} }
module_init(amd7930_init); module_init(amd7930_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment