- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / sound / soc / au1x / dbdma2.c
index 594c6c5..19e4d37 100644 (file)
@@ -2,7 +2,7 @@
  * Au12x0/Au1550 PSC ALSA ASoC audio support.
  *
  * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
- *     Manuel Lauss <mano@roarinelk.homelinux.net>
+ *     Manuel Lauss <manuel.lauss@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -333,6 +333,30 @@ static int au1xpsc_pcm_new(struct snd_card *card,
 
 static int au1xpsc_pcm_probe(struct platform_device *pdev)
 {
+       if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
+               return -ENODEV;
+
+       return 0;
+}
+
+static int au1xpsc_pcm_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+/* au1xpsc audio platform */
+struct snd_soc_platform au1xpsc_soc_platform = {
+       .name           = "au1xpsc-pcm-dbdma",
+       .probe          = au1xpsc_pcm_probe,
+       .remove         = au1xpsc_pcm_remove,
+       .pcm_ops        = &au1xpsc_pcm_ops,
+       .pcm_new        = au1xpsc_pcm_new,
+       .pcm_free       = au1xpsc_pcm_free_dma_buffers,
+};
+EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
+
+static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
+{
        struct resource *r;
        int ret;
 
@@ -365,7 +389,9 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
        }
        (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
 
-       return 0;
+       ret = snd_soc_register_platform(&au1xpsc_soc_platform);
+       if (!ret)
+               return ret;
 
 out2:
        kfree(au1xpsc_audio_pcmdma[PCM_RX]);
@@ -376,10 +402,12 @@ out1:
        return ret;
 }
 
-static int au1xpsc_pcm_remove(struct platform_device *pdev)
+static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
 {
        int i;
 
+       snd_soc_unregister_platform(&au1xpsc_soc_platform);
+
        for (i = 0; i < 2; i++) {
                if (au1xpsc_audio_pcmdma[i]) {
                        au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
@@ -391,32 +419,81 @@ static int au1xpsc_pcm_remove(struct platform_device *pdev)
        return 0;
 }
 
-/* au1xpsc audio platform */
-struct snd_soc_platform au1xpsc_soc_platform = {
-       .name           = "au1xpsc-pcm-dbdma",
-       .probe          = au1xpsc_pcm_probe,
-       .remove         = au1xpsc_pcm_remove,
-       .pcm_ops        = &au1xpsc_pcm_ops,
-       .pcm_new        = au1xpsc_pcm_new,
-       .pcm_free       = au1xpsc_pcm_free_dma_buffers,
+static struct platform_driver au1xpsc_pcm_driver = {
+       .driver = {
+               .name   = "au1xpsc-pcm",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = au1xpsc_pcm_drvprobe,
+       .remove         = __devexit_p(au1xpsc_pcm_drvremove),
 };
-EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
 
-static int __init au1xpsc_audio_dbdma_init(void)
+static int __init au1xpsc_audio_dbdma_load(void)
 {
        au1xpsc_audio_pcmdma[PCM_TX] = NULL;
        au1xpsc_audio_pcmdma[PCM_RX] = NULL;
-       return snd_soc_register_platform(&au1xpsc_soc_platform);
+       return platform_driver_register(&au1xpsc_pcm_driver);
 }
 
-static void __exit au1xpsc_audio_dbdma_exit(void)
+static void __exit au1xpsc_audio_dbdma_unload(void)
 {
-       snd_soc_unregister_platform(&au1xpsc_soc_platform);
+       platform_driver_unregister(&au1xpsc_pcm_driver);
 }
 
-module_init(au1xpsc_audio_dbdma_init);
-module_exit(au1xpsc_audio_dbdma_exit);
+module_init(au1xpsc_audio_dbdma_load);
+module_exit(au1xpsc_audio_dbdma_unload);
+
+
+struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
+{
+       struct resource *res, *r;
+       struct platform_device *pd;
+       int id[2];
+       int ret;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!r)
+               return NULL;
+       id[0] = r->start;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!r)
+               return NULL;
+       id[1] = r->start;
+
+       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+       if (!res)
+               return NULL;
+
+       res[0].start = res[0].end = id[0];
+       res[1].start = res[1].end = id[1];
+       res[0].flags = res[1].flags = IORESOURCE_DMA;
+
+       pd = platform_device_alloc("au1xpsc-pcm", -1);
+       if (!pd)
+               goto out;
+
+       pd->resource = res;
+       pd->num_resources = 2;
+
+       ret = platform_device_add(pd);
+       if (!ret)
+               return pd;
+
+       platform_device_put(pd);
+out:
+       kfree(res);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
+
+void au1xpsc_pcm_destroy(struct platform_device *dmapd)
+{
+       if (dmapd)
+               platform_device_unregister(dmapd);
+}
+EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
+MODULE_AUTHOR("Manuel Lauss");