@@ -1,3 +1,4 @@
+#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
@@ -155,6 +156,7 @@ struct cppi41_dd {
unsigned int dma_tdfdq;
bool is_suspended;
+ atomic_t push_descs;
};
#define FIST_COMPLETION_QUEUE 93
@@ -321,13 +323,8 @@ static irqreturn_t cppi41_irq(int irq, void *data)
u32 desc, len;
int error;
- error = pm_runtime_get(cdd->ddev.dev);
- if ((error != -EINPROGRESS) && (error < 0))
- dev_err(cdd->ddev.dev, "%s pm runtime get: %i\n",
- __func__, error);
-
/* This warning should never trigger */
- WARN_ON(cdd->is_suspended);
+ WARN(cdd->is_suspended, "=== push_descs %d\n", atomic_read(&cdd->push_descs));
q_num = __fls(val);
val &= ~(1 << q_num);
@@ -351,6 +348,7 @@ static irqreturn_t cppi41_irq(int irq, void *data)
pm_runtime_mark_last_busy(cdd->ddev.dev);
pm_runtime_put_autosuspend(cdd->ddev.dev);
+ atomic_dec(&cdd->push_descs);
}
}
return IRQ_HANDLED;
@@ -460,6 +458,7 @@ static void push_desc_queue(struct cppi41_channel *c)
reg = (sizeof(struct cppi41_desc) - 24) / 4;
reg |= desc_phys;
cppi_writel(reg, cdd->qmgr_mem + QMGR_QUEUE_D(c->q_num));
+ atomic_inc(&cdd->push_descs);
}
/*
@@ -500,7 +499,6 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan)
spin_unlock_irqrestore(&cdd->lock, flags);
pm_runtime_mark_last_busy(cdd->ddev.dev);
- pm_runtime_put_autosuspend(cdd->ddev.dev);
}
static u32 get_host_pd0(u32 length)
@@ -1163,12 +1161,17 @@ static int __maybe_unused cppi41_runtime_suspend(struct device *dev)
{
struct cppi41_dd *cdd = dev_get_drvdata(dev);
unsigned long flags;
+ int x;
spin_lock_irqsave(&cdd->lock, flags);
cdd->is_suspended = true;
WARN_ON(!list_empty(&cdd->pending));
+ x = atomic_read(&cdd->push_descs);
+ WARN(x, "=== push_descs %d", x);
+
spin_unlock_irqrestore(&cdd->lock, flags);
+
return 0;
}