Commit c5541079 authored by Arve Hjønnevåg's avatar Arve Hjønnevåg Committed by Daniel Walker

[ARM] msm: dma: Enable dma clock while dma is active

Signed-off-by: default avatarArve Hjønnevåg <arve@android.com>
parent a6407dd7
...@@ -13,6 +13,8 @@ ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment