dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected
authorTony Lindgren <tony@atomide.com>
Wed, 9 Nov 2016 16:47:59 +0000 (09:47 -0700)
committerVinod Koul <vinod.koul@intel.com>
Mon, 14 Nov 2016 05:27:32 +0000 (10:57 +0530)
On am335x with musb host we can end up with unpaired pm runtime calls
if a hub with no devices is connected and disconnected.

This is because of the conditional pm runtime calls which are always
a bad idea. Let's fix the issue by making them unconditional and
paired in each function.

Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support")
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/cppi41.c

index 6ed99d9263583282e34881110d3fe2fa7b77f637..3d2d8b5a6c91f275196e5d1914c95c0fb10b6775 100644 (file)
@@ -318,6 +318,11 @@ static irqreturn_t cppi41_irq(int irq, void *data)
                while (val) {
                        u32 desc, len;
 
+                       status = pm_runtime_get(cdd->ddev.dev);
+                       if (status < 0)
+                               dev_err(cdd->ddev.dev, "%s pm runtime get: %i\n",
+                                       __func__, status);
+
                        q_num = __fls(val);
                        val &= ~(1 << q_num);
                        q_num += 32 * i;
@@ -338,7 +343,6 @@ static irqreturn_t cppi41_irq(int irq, void *data)
                        dma_cookie_complete(&c->txd);
                        dmaengine_desc_get_callback_invoke(&c->txd, NULL);
 
-                       /* Paired with cppi41_dma_issue_pending */
                        pm_runtime_mark_last_busy(cdd->ddev.dev);
                        pm_runtime_put_autosuspend(cdd->ddev.dev);
                }
@@ -460,7 +464,6 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan)
        struct cppi41_dd *cdd = c->cdd;
        int error;
 
-       /* PM runtime paired with dmaengine_desc_get_callback_invoke */
        error = pm_runtime_get(cdd->ddev.dev);
        if ((error != -EINPROGRESS) && error < 0) {
                dev_err(cdd->ddev.dev, "Failed to pm_runtime_get: %i\n",
@@ -473,6 +476,9 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan)
                push_desc_queue(c);
        else
                pending_desc(c);
+
+       pm_runtime_mark_last_busy(cdd->ddev.dev);
+       pm_runtime_put_autosuspend(cdd->ddev.dev);
 }
 
 static u32 get_host_pd0(u32 length)