SNDRV_PCM_RATE_CONTINUOUS)
struct dma_object {
- struct list_head list;
struct snd_soc_platform_driver dai;
dma_addr_t ssi_stx_phys;
dma_addr_t ssi_srx_phys;
}
}
-/* List of DMA nodes that we've probed */
-static LIST_HEAD(dma_list);
-
/**
* find_ssi_node -- returns the SSI node that points to his DMA channel node
*
dma->channel = of_iomap(np, 0);
dma->irq = irq_of_parse_and_map(np, 0);
- list_add(&dma->list, &dma_list);
+
+ dev_set_drvdata(&of_dev->dev, dma);
return 0;
}
static int __devexit fsl_soc_dma_remove(struct of_device *of_dev)
{
- struct list_head *n, *ptr;
- struct dma_object *dma;
+ struct dma_object *dma = dev_get_drvdata(&of_dev->dev);
- list_for_each_safe(ptr, n, &dma_list) {
- dma = list_entry(ptr, struct dma_object, list);
- list_del_init(ptr);
-
- snd_soc_unregister_platform(&of_dev->dev);
- iounmap(dma->channel);
- irq_dispose_mapping(dma->irq);
- kfree(dma);
- }
+ snd_soc_unregister_platform(&of_dev->dev);
+ iounmap(dma->channel);
+ irq_dispose_mapping(dma->irq);
+ kfree(dma);
return 0;
}
{
struct fsl_ssi_private *ssi_private;
int ret = 0;
- struct device_attribute *dev_attr;
+ struct device_attribute *dev_attr = NULL;
struct device_node *np = of_dev->dev.of_node;
const char *p, *sprop;
struct resource res;
if (ret) {
dev_err(&of_dev->dev, "could not create sysfs %s file\n",
ssi_private->dev_attr.attr.name);
- kfree(ssi_private);
- return ret;
+ goto error;
}
/* Register with ASoC */
dev_set_drvdata(&of_dev->dev, ssi_private);
ret = snd_soc_register_dai(&of_dev->dev, &ssi_private->cpu_dai_drv);
- if (ret != 0) {
+ if (ret) {
dev_err(&of_dev->dev, "failed to register DAI: %d\n", ret);
- kfree(ssi_private);
- return ret;
+ goto error;
}
/* Trigger the machine driver's probe function. The platform driver
if (IS_ERR(ssi_private->pdev)) {
ret = PTR_ERR(ssi_private->pdev);
dev_err(&of_dev->dev, "failed to register platform: %d\n", ret);
- kfree(ssi_private);
- return ret;
+ goto error;
}
return 0;
+
+error:
+ snd_soc_unregister_dai(&of_dev->dev);
+ dev_set_drvdata(&of_dev->dev, NULL);
+ if (dev_attr)
+ device_remove_file(&of_dev->dev, dev_attr);
+ irq_dispose_mapping(ssi_private->irq);
+ iounmap(ssi_private->ssi);
+ kfree(ssi_private);
+
+ return ret;
}
-/**
- * fsl_ssi_destroy_dai: destroy the snd_soc_dai object
- *
- * This function undoes the operations of fsl_ssi_probe()
- */
static int fsl_ssi_remove(struct of_device *of_dev)
{
struct fsl_ssi_private *ssi_private = dev_get_drvdata(&of_dev->dev);