/* linux/arch/arm/mach-msm/dma.c
 *
 * Copyright (C) 2007 Google, Inc.
 * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/pm_runtime.h>
#include <mach/dma.h>

#define MODULE_NAME "msm_dmov"

#define MSM_DMOV_CHANNEL_COUNT 16
#define MSM_DMOV_CRCI_COUNT 16

enum {
	CLK_DIS,
	CLK_TO_BE_DIS,
	CLK_EN
};

struct msm_dmov_ci_conf {
	int start;
	int end;
	int burst;
};

struct msm_dmov_crci_conf {
	int sd;
	int blk_size;
};

struct msm_dmov_chan_conf {
	int sd;
	int block;
	int priority;
};

struct msm_dmov_conf {
	void *base;
	struct msm_dmov_crci_conf *crci_conf;
	struct msm_dmov_chan_conf *chan_conf;
	int channel_active;
	int sd;
	size_t sd_size;
	struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
	struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
	struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
	struct mutex lock;
	spinlock_t list_lock;
	unsigned int irq;
	struct clk *clk;
	struct clk *pclk;
	struct clk *ebiclk;
	unsigned int clk_ctl;
	struct delayed_work work;
	struct workqueue_struct *cmd_wq;
};

static void msm_dmov_clock_work(struct work_struct *);

#ifdef CONFIG_ARCH_MSM8X60

#define DMOV_CHANNEL_DEFAULT_CONF { .sd = 1, .block = 0, .priority = 0 }
#define DMOV_CHANNEL_MODEM_CONF { .sd = 3, .block = 0, .priority = 0 }
#define DMOV_CHANNEL_CONF(secd, blk, pri) \
	{ .sd = secd, .block = blk, .priority = pri }

static struct msm_dmov_chan_conf adm0_chan_conf[] = {
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
};

static struct msm_dmov_chan_conf adm1_chan_conf[] = {
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_DEFAULT_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
	DMOV_CHANNEL_MODEM_CONF,
};

#define DMOV_CRCI_DEFAULT_CONF { .sd = 1, .blk_size = 0 }
#define DMOV_CRCI_CONF(secd, blk) { .sd = secd, .blk_size = blk }

static struct msm_dmov_crci_conf adm0_crci_conf[] = {
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_CONF(1, 4),
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
};

static struct msm_dmov_crci_conf adm1_crci_conf[] = {
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_CONF(1, 1),
	DMOV_CRCI_CONF(1, 1),
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_CONF(1, 1),
	DMOV_CRCI_CONF(1, 1),
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_DEFAULT_CONF,
	DMOV_CRCI_CONF(1, 1),
	DMOV_CRCI_DEFAULT_CONF,
};

static struct msm_dmov_conf dmov_conf[] = {
	{
		.crci_conf = adm0_crci_conf,
		.chan_conf = adm0_chan_conf,
		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
		.clk_ctl = CLK_DIS,
		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
				msm_dmov_clock_work),
	}, {
		.crci_conf = adm1_crci_conf,
		.chan_conf = adm1_chan_conf,
		.lock = __MUTEX_INITIALIZER(dmov_conf[1].lock),
		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
		.clk_ctl = CLK_DIS,
		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[1].work,
				msm_dmov_clock_work),
	}
};
#else
static struct msm_dmov_conf dmov_conf[] = {
	{
		.crci_conf = NULL,
		.chan_conf = NULL,
		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
		.clk_ctl = CLK_DIS,
		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
				msm_dmov_clock_work),
	}
};
#endif

#define MSM_DMOV_ID_COUNT (MSM_DMOV_CHANNEL_COUNT * ARRAY_SIZE(dmov_conf))
#define DMOV_REG(name, adm)    ((name) + (dmov_conf[adm].base) +\
	(dmov_conf[adm].sd * dmov_conf[adm].sd_size))
#define DMOV_ID_TO_ADM(id)   ((id) / MSM_DMOV_CHANNEL_COUNT)
#define DMOV_ID_TO_CHAN(id)   ((id) % MSM_DMOV_CHANNEL_COUNT)
#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)

#ifdef CONFIG_MSM_ADM3
#define DMOV_IRQ_TO_ADM(irq)   \
({ \
	typeof(irq) _irq = irq; \
	((_irq == INT_ADM1_MASTER) || (_irq == INT_ADM1_AARM)); \
})
#else
#define DMOV_IRQ_TO_ADM(irq) 0
#endif

enum {
	MSM_DMOV_PRINT_ERRORS = 1,
	MSM_DMOV_PRINT_IO = 2,
	MSM_DMOV_PRINT_FLOW = 4
};

unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;

#define MSM_DMOV_DPRINTF(mask, format, args...) \
	do { \
		if ((mask) & msm_dmov_print_mask) \
			printk(KERN_ERR format, args); \
	} while (0)
#define PRINT_ERROR(format, args...) \
	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
#define PRINT_IO(format, args...) \
	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
#define PRINT_FLOW(format, args...) \
	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);

static int msm_dmov_clk_on(int adm)
{
	int ret;

	ret = clk_prepare_enable(dmov_conf[adm].clk);
	if (ret)
		return ret;
	if (dmov_conf[adm].pclk) {
		ret = clk_prepare_enable(dmov_conf[adm].pclk);
		if (ret) {
			clk_disable_unprepare(dmov_conf[adm].clk);
			return ret;
		}
	}
	if (dmov_conf[adm].ebiclk) {
		ret = clk_prepare_enable(dmov_conf[adm].ebiclk);
		if (ret) {
			if (dmov_conf[adm].pclk)
				clk_disable_unprepare(dmov_conf[adm].pclk);
			clk_disable_unprepare(dmov_conf[adm].clk);
		}
	}
	return ret;
}

static void msm_dmov_clk_off(int adm)
{
	if (dmov_conf[adm].ebiclk)
		clk_disable_unprepare(dmov_conf[adm].ebiclk);
	if (dmov_conf[adm].pclk)
		clk_disable_unprepare(dmov_conf[adm].pclk);
	clk_disable_unprepare(dmov_conf[adm].clk);
}

static void msm_dmov_clock_work(struct work_struct *work)
{
	struct msm_dmov_conf *conf =
		container_of(to_delayed_work(work), struct msm_dmov_conf, work);
	int adm = DMOV_IRQ_TO_ADM(conf->irq);
	mutex_lock(&conf->lock);
	if (conf->clk_ctl == CLK_TO_BE_DIS) {
		BUG_ON(conf->channel_active);
		msm_dmov_clk_off(adm);
		conf->clk_ctl = CLK_DIS;
	}
	mutex_unlock(&conf->lock);
}

enum {
	NOFLUSH = 0,
	GRACEFUL,
	NONGRACEFUL,
};

/* Caller must hold the list lock */
static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
{
	struct msm_dmov_cmd *cmd;

	if (list_empty(&dmov_conf[adm].ready_commands[ch]))
		return NULL;

	cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
			 list);
	list_del(&cmd->list);
	if (cmd->exec_func)
		cmd->exec_func(cmd);
	list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
	if (!dmov_conf[adm].channel_active)
		enable_irq(dmov_conf[adm].irq);
	dmov_conf[adm].channel_active |= BIT(ch);
	PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
	writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));

	return cmd;
}

static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
{
	struct msm_dmov_cmd *cmd =
		container_of(work, struct msm_dmov_cmd, work);
	unsigned id = cmd->id;
	unsigned status;
	unsigned long flags;
	int adm = DMOV_ID_TO_ADM(id);
	int ch = DMOV_ID_TO_CHAN(id);

	mutex_lock(&dmov_conf[adm].lock);
	if (dmov_conf[adm].clk_ctl == CLK_DIS) {
		status = msm_dmov_clk_on(adm);
		if (status != 0)
			goto error;
	}
	dmov_conf[adm].clk_ctl = CLK_EN;

	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);

	cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
			 list);
	list_del(&cmd->list);
	list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
	status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
	if (status & DMOV_STATUS_CMD_PTR_RDY) {
		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
			id, status);
		cmd = start_ready_cmd(ch, adm);
		/*
		 * We added something to the ready list, and still hold the
		 * list lock. Thus, no need to check for cmd == NULL
		 */
		if (cmd->toflush) {
			int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
			writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
		}
	} else {
		cmd->toflush = 0;
		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
		    !list_empty(&dmov_conf[adm].ready_commands[ch]))
			PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
				"status %x\n", id, status);
		PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
		    "%x\n", id, status);
	}
	if (!dmov_conf[adm].channel_active) {
		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
		schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
	}
	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
error:
	mutex_unlock(&dmov_conf[adm].lock);
}

static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
{
	int adm = DMOV_ID_TO_ADM(id);
	int ch = DMOV_ID_TO_CHAN(id);
	unsigned long flags;
	cmd->id = id;
	cmd->toflush = 0;

	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
	list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
	queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
}

void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
{
	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
	__msm_dmov_enqueue_cmd_ext(id, cmd);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);

void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
	/* Disable callback function (for backwards compatibility) */
	cmd->exec_func = NULL;
	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
	__msm_dmov_enqueue_cmd_ext(id, cmd);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd);

void msm_dmov_flush(unsigned int id, int graceful)
{
	unsigned long irq_flags;
	int ch = DMOV_ID_TO_CHAN(id);
	int adm = DMOV_ID_TO_ADM(id);
	int flush = graceful ? DMOV_FLUSH_TYPE : 0;
	struct msm_dmov_cmd *cmd;

	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
	/* XXX not checking if flush cmd sent already */
	if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
		PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
		writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
	}
	list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
		cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
	/* spin_unlock_irqrestore has the necessary barrier */
	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
}
EXPORT_SYMBOL(msm_dmov_flush);

struct msm_dmov_exec_cmdptr_cmd {
	struct msm_dmov_cmd dmov_cmd;
	struct completion complete;
	unsigned id;
	unsigned int result;
	struct msm_dmov_errdata err;
};

static void
dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
			       unsigned int result,
			       struct msm_dmov_errdata *err)
{
	struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
	cmd->result = result;
	if (result != 0x80000002 && err)
		memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));

	complete(&cmd->complete);
}

int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
{
	struct msm_dmov_exec_cmdptr_cmd cmd;

	PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);

	cmd.dmov_cmd.cmdptr = cmdptr;
	cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
	cmd.dmov_cmd.exec_func = NULL;
	cmd.id = id;
	cmd.result = 0;
	INIT_WORK_ONSTACK(&cmd.dmov_cmd.work, msm_dmov_enqueue_cmd_ext_work);
	init_completion(&cmd.complete);

	__msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd);
	wait_for_completion_io(&cmd.complete);

	if (cmd.result != 0x80000002) {
		PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
		PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
			id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
		return -EIO;
	}
	PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
	return 0;
}
EXPORT_SYMBOL(msm_dmov_exec_cmd);

static void fill_errdata(struct msm_dmov_errdata *errdata, int ch, int adm)
{
	errdata->flush[0] = readl_relaxed(DMOV_REG(DMOV_FLUSH0(ch), adm));
	errdata->flush[1] = readl_relaxed(DMOV_REG(DMOV_FLUSH1(ch), adm));
	errdata->flush[2] = 0;
	errdata->flush[3] = readl_relaxed(DMOV_REG(DMOV_FLUSH3(ch), adm));
	errdata->flush[4] = readl_relaxed(DMOV_REG(DMOV_FLUSH4(ch), adm));
	errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
}

static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
{
	unsigned int int_status;
	unsigned int mask;
	unsigned int id;
	unsigned int ch;
	unsigned long irq_flags;
	unsigned int ch_status;
	unsigned int ch_result;
	unsigned int valid = 0;
	struct msm_dmov_cmd *cmd;
	int adm = DMOV_IRQ_TO_ADM(irq);

	mutex_lock(&dmov_conf[adm].lock);
	/* read and clear isr */
	int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
	PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);

	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
	while (int_status) {
		mask = int_status & -int_status;
		ch = fls(mask) - 1;
		id = DMOV_CHAN_ADM_TO_ID(ch, adm);
		PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
		int_status &= ~mask;
		ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
		if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
			PRINT_FLOW("msm_datamover_irq_handler id %d, "
				"result not valid %x\n", id, ch_status);
			continue;
		}
		do {
			valid = 1;
			ch_result = readl_relaxed(DMOV_REG(DMOV_RSLT(ch), adm));
			if (list_empty(&dmov_conf[adm].active_commands[ch])) {
				PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
					"with no active command, status %x, result %x\n",
					id, ch_status, ch_result);
				cmd = NULL;
			} else {
				cmd = list_entry(dmov_conf[adm].
					active_commands[ch].next, typeof(*cmd),
					list);
			}
			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
			if (ch_result & DMOV_RSLT_DONE) {
				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
					id, ch_status);
				PRINT_IO("msm_datamover_irq_handler id %d, got result "
					"for %p, result %x\n", id, cmd, ch_result);
				if (cmd) {
					list_del(&cmd->list);
					cmd->complete_func(cmd, ch_result, NULL);
				}
			}
			if (ch_result & DMOV_RSLT_FLUSH) {
				struct msm_dmov_errdata errdata;

				fill_errdata(&errdata, ch, adm);
				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
				PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
				if (cmd) {
					list_del(&cmd->list);
					cmd->complete_func(cmd, ch_result, &errdata);
				}
			}
			if (ch_result & DMOV_RSLT_ERROR) {
				struct msm_dmov_errdata errdata;

				fill_errdata(&errdata, ch, adm);

				PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
				PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
				if (cmd) {
					list_del(&cmd->list);
					cmd->complete_func(cmd, ch_result, &errdata);
				}
				/* this does not seem to work, once we get an error */
				/* the datamover will no longer accept commands */
				writel_relaxed(0, DMOV_REG(DMOV_FLUSH0(ch),
					       adm));
			}
			rmb();
			ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
						  adm));
			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
			if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
				start_ready_cmd(ch, adm);
		} while (ch_status & DMOV_STATUS_RSLT_VALID);
		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
		    list_empty(&dmov_conf[adm].ready_commands[ch]))
			dmov_conf[adm].channel_active &= ~(1U << ch);
		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
	}
	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);

	if (!dmov_conf[adm].channel_active && valid) {
		disable_irq_nosync(dmov_conf[adm].irq);
		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
		schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
	}

	mutex_unlock(&dmov_conf[adm].lock);
	return valid ? IRQ_HANDLED : IRQ_NONE;
}

static int msm_dmov_suspend_late(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	int adm = (pdev->id >= 0) ? pdev->id : 0;
	mutex_lock(&dmov_conf[adm].lock);
	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
		BUG_ON(dmov_conf[adm].channel_active);
		msm_dmov_clk_off(adm);
		dmov_conf[adm].clk_ctl = CLK_DIS;
	}
	mutex_unlock(&dmov_conf[adm].lock);
	return 0;
}

static int msm_dmov_runtime_suspend(struct device *dev)
{
	dev_dbg(dev, "pm_runtime: suspending...\n");
	return 0;
}

static int msm_dmov_runtime_resume(struct device *dev)
{
	dev_dbg(dev, "pm_runtime: resuming...\n");
	return 0;
}

static int msm_dmov_runtime_idle(struct device *dev)
{
	dev_dbg(dev, "pm_runtime: idling...\n");
	return 0;
}

static struct dev_pm_ops msm_dmov_dev_pm_ops = {
	.runtime_suspend = msm_dmov_runtime_suspend,
	.runtime_resume = msm_dmov_runtime_resume,
	.runtime_idle = msm_dmov_runtime_idle,
	.suspend = msm_dmov_suspend_late,
};

static int msm_dmov_init_clocks(struct platform_device *pdev)
{
	int adm = (pdev->id >= 0) ? pdev->id : 0;
	int ret;

	dmov_conf[adm].clk = clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(dmov_conf[adm].clk)) {
		printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
		dmov_conf[adm].clk = NULL;
		return -ENOENT;
	}

	dmov_conf[adm].pclk = clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(dmov_conf[adm].pclk)) {
		dmov_conf[adm].pclk = NULL;
		/* pclk not present on all SoCs, don't bail on failure */
	}

	dmov_conf[adm].ebiclk = clk_get(&pdev->dev, "mem_clk");
	if (IS_ERR(dmov_conf[adm].ebiclk)) {
		dmov_conf[adm].ebiclk = NULL;
		/* ebiclk not present on all SoCs, don't bail on failure */
	} else {
		ret = clk_set_rate(dmov_conf[adm].ebiclk, 27000000);
		if (ret)
			return -ENOENT;
	}

	return 0;
}

static void config_datamover(int adm)
{
#ifdef CONFIG_MSM_ADM3
	int i;
	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
		struct msm_dmov_chan_conf *chan_conf =
			dmov_conf[adm].chan_conf;
		unsigned conf;
		/* Only configure scorpion channels */
		if (chan_conf[i].sd <= 1) {
			conf = readl_relaxed(DMOV_REG(DMOV_CONF(i), adm));
			conf &= ~DMOV_CONF_SD(7);
			conf |= DMOV_CONF_SD(chan_conf[i].sd);
			writel_relaxed(conf | DMOV_CONF_SHADOW_EN,
			       DMOV_REG(DMOV_CONF(i), adm));
		}
	}
	for (i = 0; i < MSM_DMOV_CRCI_COUNT; i++) {
		struct msm_dmov_crci_conf *crci_conf =
			dmov_conf[adm].crci_conf;

		writel_relaxed(DMOV_CRCI_CTL_BLK_SZ(crci_conf[i].blk_size),
		       DMOV_REG(DMOV_CRCI_CTL(i), adm));
	}
#endif
}

static int msm_dmov_probe(struct platform_device *pdev)
{
	int adm = (pdev->id >= 0) ? pdev->id : 0;
	int i;
	int ret;
	struct msm_dmov_pdata *pdata = pdev->dev.platform_data;
	struct resource *irqres =
		platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	struct resource *mres =
		platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (pdata) {
		dmov_conf[adm].sd = pdata->sd;
		dmov_conf[adm].sd_size = pdata->sd_size;
	}
	if (!dmov_conf[adm].sd_size)
		return -ENXIO;

	if (!irqres || !irqres->start)
		return -ENXIO;
	dmov_conf[adm].irq = irqres->start;

	if (!mres || !mres->start)
		return -ENXIO;
	dmov_conf[adm].base = ioremap_nocache(mres->start, resource_size(mres));
	if (!dmov_conf[adm].base)
		return -ENOMEM;

	dmov_conf[adm].cmd_wq = alloc_ordered_workqueue("dmov%d_wq", 0, adm);
	if (!dmov_conf[adm].cmd_wq) {
		PRINT_ERROR("Couldn't allocate ADM%d workqueue.\n", adm);
		ret = -ENOMEM;
		goto out_map;
	}

	ret = request_threaded_irq(dmov_conf[adm].irq, NULL, msm_dmov_isr,
				   IRQF_ONESHOT, "msmdatamover", NULL);
	if (ret) {
		PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
			dmov_conf[adm].irq);
		goto out_wq;
	}
	disable_irq(dmov_conf[adm].irq);
	ret = msm_dmov_init_clocks(pdev);
	if (ret) {
		PRINT_ERROR("Requesting ADM%d clocks failed\n", adm);
		goto out_irq;
	}
	ret = msm_dmov_clk_on(adm);
	if (ret) {
		PRINT_ERROR("Enabling ADM%d clocks failed\n", adm);
		goto out_irq;
	}

	config_datamover(adm);
	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
		INIT_LIST_HEAD(&dmov_conf[adm].staged_commands[i]);
		INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
		INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);

		writel_relaxed(DMOV_RSLT_CONF_IRQ_EN
		     | DMOV_RSLT_CONF_FORCE_FLUSH_RSLT,
		     DMOV_REG(DMOV_RSLT_CONF(i), adm));
	}
	wmb();
	msm_dmov_clk_off(adm);
	return ret;
out_irq:
	free_irq(dmov_conf[adm].irq, NULL);
out_wq:
	destroy_workqueue(dmov_conf[adm].cmd_wq);
out_map:
	iounmap(dmov_conf[adm].base);
	return ret;
}

static struct platform_driver msm_dmov_driver = {
	.probe = msm_dmov_probe,
	.driver = {
		.name = MODULE_NAME,
		.owner = THIS_MODULE,
		.pm = &msm_dmov_dev_pm_ops,
	},
};

/* static int __init */
static int __init msm_init_datamover(void)
{
	int ret;
	ret = platform_driver_register(&msm_dmov_driver);
	if (ret)
		return ret;
	return 0;
}
arch_initcall(msm_init_datamover);
