summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-11-09 09:47:59 -0700
committerVinod Koul <vinod.koul@intel.com>2016-11-14 10:57:32 +0530
commit098de42ad6708866501a00155ba85350bc0b29e5 (patch)
tree862b74e2285f3ffe175e6b4138564d980223d505
parent12f5908080bdccca2cb2f7ad850cb360c92f481a (diff)
dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected
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>
-rw-r--r--drivers/dma/cppi41.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index 6ed99d926358..3d2d8b5a6c91 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -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)