Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[cascardo/linux.git] / drivers / dma / coh901318.c
index c340ca9..e4acd63 100644 (file)
@@ -266,7 +266,7 @@ static int dma_memcpy_channels[] = {
                        COH901318_CX_CTRL_DDMA_LEGACY | \
                        COH901318_CX_CTRL_PRDD_SOURCE)
 
-const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
+static const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
        {
                .number = U300_DMA_MSL_TX_0,
                .name = "MSL TX 0",
@@ -1280,6 +1280,7 @@ struct coh901318_desc {
 struct coh901318_base {
        struct device *dev;
        void __iomem *virtbase;
+       unsigned int irq;
        struct coh901318_pool pool;
        struct powersave pm;
        struct dma_device dma_slave;
@@ -1364,7 +1365,6 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
 }
 
 static const struct file_operations coh901318_debugfs_status_operations = {
-       .owner          = THIS_MODULE,
        .open           = simple_open,
        .read           = coh901318_debugfs_read,
        .llseek         = default_llseek,
@@ -2422,7 +2422,7 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
        enum dma_status ret;
 
        ret = dma_cookie_status(chan, cookie, txstate);
-       if (ret == DMA_COMPLETE)
+       if (ret == DMA_COMPLETE || !txstate)
                return ret;
 
        dma_set_residue(txstate, coh901318_get_bytes_left(chan));
@@ -2680,6 +2680,8 @@ static int __init coh901318_probe(struct platform_device *pdev)
        if (err)
                return err;
 
+       base->irq = irq;
+
        err = coh901318_pool_create(&base->pool, &pdev->dev,
                                    sizeof(struct coh901318_lli),
                                    32);
@@ -2755,11 +2757,31 @@ static int __init coh901318_probe(struct platform_device *pdev)
        coh901318_pool_destroy(&base->pool);
        return err;
 }
+static void coh901318_base_remove(struct coh901318_base *base, const int *pick_chans)
+{
+       int chans_i;
+       int i = 0;
+       struct coh901318_chan *cohc;
+
+       for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) {
+               for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) {
+                       cohc = &base->chans[i];
+
+                       tasklet_kill(&cohc->tasklet);
+               }
+       }
+
+}
 
 static int coh901318_remove(struct platform_device *pdev)
 {
        struct coh901318_base *base = platform_get_drvdata(pdev);
 
+       devm_free_irq(&pdev->dev, base->irq, base);
+
+       coh901318_base_remove(base, dma_slave_channels);
+       coh901318_base_remove(base, dma_memcpy_channels);
+
        of_dma_controller_free(pdev->dev.of_node);
        dma_async_device_unregister(&base->dma_memcpy);
        dma_async_device_unregister(&base->dma_slave);
@@ -2780,13 +2802,13 @@ static struct platform_driver coh901318_driver = {
        },
 };
 
-int __init coh901318_init(void)
+static int __init coh901318_init(void)
 {
        return platform_driver_probe(&coh901318_driver, coh901318_probe);
 }
 subsys_initcall(coh901318_init);
 
-void __exit coh901318_exit(void)
+static void __exit coh901318_exit(void)
 {
        platform_driver_unregister(&coh901318_driver);
 }