[ARM] msm: dma: Enable dma clock while dma is active
Signed-off-by: Arve Hjønnevåg <arve@android.com>
This commit is contained in:
parent
a6407dd7b8
commit
c5541079da
1 changed files with 16 additions and 1 deletions
|
@ -13,6 +13,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/err.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <mach/dma.h>
|
#include <mach/dma.h>
|
||||||
|
@ -26,6 +28,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(msm_dmov_lock);
|
static DEFINE_SPINLOCK(msm_dmov_lock);
|
||||||
|
static struct clk *msm_dmov_clk;
|
||||||
static unsigned int channel_active;
|
static unsigned int channel_active;
|
||||||
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
|
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
|
||||||
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
|
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
|
||||||
|
@ -54,6 +57,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
spin_lock_irqsave(&msm_dmov_lock, irq_flags);
|
spin_lock_irqsave(&msm_dmov_lock, irq_flags);
|
||||||
|
if (!channel_active)
|
||||||
|
clk_enable(msm_dmov_clk);
|
||||||
status = readl(DMOV_STATUS(id));
|
status = readl(DMOV_STATUS(id));
|
||||||
if (list_empty(&ready_commands[id]) &&
|
if (list_empty(&ready_commands[id]) &&
|
||||||
(status & DMOV_STATUS_CMD_PTR_RDY)) {
|
(status & DMOV_STATUS_CMD_PTR_RDY)) {
|
||||||
|
@ -70,6 +75,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
|
||||||
channel_active |= 1U << id;
|
channel_active |= 1U << id;
|
||||||
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
|
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
|
||||||
} else {
|
} else {
|
||||||
|
if (!channel_active)
|
||||||
|
clk_disable(msm_dmov_clk);
|
||||||
if (list_empty(&active_commands[id]))
|
if (list_empty(&active_commands[id]))
|
||||||
PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
|
PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
|
||||||
|
|
||||||
|
@ -219,8 +226,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
|
||||||
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
|
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel_active)
|
if (!channel_active) {
|
||||||
disable_irq_nosync(INT_ADM_AARM);
|
disable_irq_nosync(INT_ADM_AARM);
|
||||||
|
clk_disable(msm_dmov_clk);
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
|
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -230,11 +239,17 @@ static int __init msm_init_datamover(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
|
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
|
||||||
INIT_LIST_HEAD(&ready_commands[i]);
|
INIT_LIST_HEAD(&ready_commands[i]);
|
||||||
INIT_LIST_HEAD(&active_commands[i]);
|
INIT_LIST_HEAD(&active_commands[i]);
|
||||||
writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
|
writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
|
||||||
}
|
}
|
||||||
|
clk = clk_get(NULL, "adm_clk");
|
||||||
|
if (IS_ERR(clk))
|
||||||
|
return PTR_ERR(clk);
|
||||||
|
msm_dmov_clk = clk;
|
||||||
ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
|
ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue