aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/dma.c
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2009-06-25 20:03:14 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-05-12 12:14:14 -0400
commitc5541079da3cd19626410d59455d3e0f34d65943 (patch)
tree46239df471eb9ddb8d942d94e457d932cb630e60 /arch/arm/mach-msm/dma.c
parenta6407dd7b89f0de39d315eee64ad59dd68187b38 (diff)
[ARM] msm: dma: Enable dma clock while dma is active
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Diffstat (limited to 'arch/arm/mach-msm/dma.c')
-rw-r--r--arch/arm/mach-msm/dma.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 09c0c0f9729..e80cad46892 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -13,6 +13,8 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/clk.h>
17#include <linux/err.h>
16#include <linux/io.h> 18#include <linux/io.h>
17#include <linux/interrupt.h> 19#include <linux/interrupt.h>
18#include <mach/dma.h> 20#include <mach/dma.h>
@@ -26,6 +28,7 @@ enum {
26}; 28};
27 29
28static DEFINE_SPINLOCK(msm_dmov_lock); 30static DEFINE_SPINLOCK(msm_dmov_lock);
31static struct clk *msm_dmov_clk;
29static unsigned int channel_active; 32static unsigned int channel_active;
30static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; 33static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
31static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; 34static 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 unsigned int status; 57 unsigned int status;
55 58
56 spin_lock_irqsave(&msm_dmov_lock, irq_flags); 59 spin_lock_irqsave(&msm_dmov_lock, irq_flags);
60 if (!channel_active)
61 clk_enable(msm_dmov_clk);
57 status = readl(DMOV_STATUS(id)); 62 status = readl(DMOV_STATUS(id));
58 if (list_empty(&ready_commands[id]) && 63 if (list_empty(&ready_commands[id]) &&
59 (status & DMOV_STATUS_CMD_PTR_RDY)) { 64 (status & DMOV_STATUS_CMD_PTR_RDY)) {
@@ -70,6 +75,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
70 channel_active |= 1U << id; 75 channel_active |= 1U << id;
71 writel(cmd->cmdptr, DMOV_CMD_PTR(id)); 76 writel(cmd->cmdptr, DMOV_CMD_PTR(id));
72 } else { 77 } else {
78 if (!channel_active)
79 clk_disable(msm_dmov_clk);
73 if (list_empty(&active_commands[id])) 80 if (list_empty(&active_commands[id]))
74 PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); 81 PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
75 82
@@ -219,8 +226,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
219 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); 226 PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
220 } 227 }
221 228
222 if (!channel_active) 229 if (!channel_active) {
223 disable_irq_nosync(INT_ADM_AARM); 230 disable_irq_nosync(INT_ADM_AARM);
231 clk_disable(msm_dmov_clk);
232 }
224 233
225 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); 234 spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
226 return IRQ_HANDLED; 235 return IRQ_HANDLED;
@@ -230,11 +239,17 @@ static int __init msm_init_datamover(void)
230{ 239{
231 int i; 240 int i;
232 int ret; 241 int ret;
242 struct clk *clk;
243
233 for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { 244 for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
234 INIT_LIST_HEAD(&ready_commands[i]); 245 INIT_LIST_HEAD(&ready_commands[i]);
235 INIT_LIST_HEAD(&active_commands[i]); 246 INIT_LIST_HEAD(&active_commands[i]);
236 writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); 247 writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
237 } 248 }
249 clk = clk_get(NULL, "adm_clk");
250 if (IS_ERR(clk))
251 return PTR_ERR(clk);
252 msm_dmov_clk = clk;
238 ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); 253 ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
239 if (ret) 254 if (ret)
240 return ret; 255 return ret;