/* Realtek USB Memstick Card Interface driver
 *
 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author:
 *   Roger Tseng <rogerable@realtek.com>
 */

#include <linux/module.h>
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/memstick.h>
#include <linux/kthread.h>
#include <linux/rtsx_usb.h>
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <asm/unaligned.h>

struct rtsx_usb_ms {
	struct platform_device	*pdev;
	struct rtsx_ucr	*ucr;
	struct memstick_host	*msh;
	struct memstick_request	*req;

	struct mutex		host_mutex;
	struct work_struct	handle_req;

	struct task_struct	*detect_ms;
	struct completion	detect_ms_exit;

	u8			ssc_depth;
	unsigned int		clock;
	int			power_mode;
	unsigned char           ifmode;
	bool			eject;
};

static inline struct device *ms_dev(struct rtsx_usb_ms *host)
{
	return &(host->pdev->dev);
}

static inline void ms_clear_error(struct rtsx_usb_ms *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	rtsx_usb_ep0_write_register(ucr, CARD_STOP,
				  MS_STOP | MS_CLR_ERR,
				  MS_STOP | MS_CLR_ERR);

	rtsx_usb_clear_dma_err(ucr);
	rtsx_usb_clear_fsm_err(ucr);
}

#ifdef DEBUG

static void ms_print_debug_regs(struct rtsx_usb_ms *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	u16 i;
	u8 *ptr;

	/* Print MS host internal registers */
	rtsx_usb_init_cmd(ucr);

	/* MS_CFG to MS_INT_REG */
	for (i = 0xFD40; i <= 0xFD44; i++)
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0);

	/* CARD_SHARE_MODE to CARD_GPIO */
	for (i = 0xFD51; i <= 0xFD56; i++)
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0);

	/* CARD_PULL_CTLx */
	for (i = 0xFD60; i <= 0xFD65; i++)
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0);

	/* CARD_DATA_SOURCE, CARD_SELECT, CARD_CLK_EN, CARD_PWR_CTL */
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_DATA_SOURCE, 0, 0);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_SELECT, 0, 0);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_CLK_EN, 0, 0);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_PWR_CTL, 0, 0);

	rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	rtsx_usb_get_rsp(ucr, 21, 100);

	ptr = ucr->rsp_buf;
	for (i = 0xFD40; i <= 0xFD44; i++)
		dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
	for (i = 0xFD51; i <= 0xFD56; i++)
		dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
	for (i = 0xFD60; i <= 0xFD65; i++)
		dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));

	dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_DATA_SOURCE, *(ptr++));
	dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_SELECT, *(ptr++));
	dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_CLK_EN, *(ptr++));
	dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_PWR_CTL, *(ptr++));
}

#else

static void ms_print_debug_regs(struct rtsx_usb_ms *host)
{
}

#endif

static int ms_pull_ctl_disable_lqfp48(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int ms_pull_ctl_disable_qfn24(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int ms_pull_ctl_enable_lqfp48(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int ms_pull_ctl_enable_qfn24(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int ms_power_on(struct rtsx_usb_ms *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;

	dev_dbg(ms_dev(host), "%s\n", __func__);

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SHARE_MODE,
			CARD_SHARE_MASK, CARD_SHARE_MS);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN,
			MS_CLK_EN, MS_CLK_EN);
	err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
	if (err < 0)
		return err;

	if (CHECK_PKG(ucr, LQFP48))
		err = ms_pull_ctl_enable_lqfp48(ucr);
	else
		err = ms_pull_ctl_enable_qfn24(ucr);
	if (err < 0)
		return err;

	err = rtsx_usb_write_register(ucr, CARD_PWR_CTL,
			POWER_MASK, PARTIAL_POWER_ON);
	if (err)
		return err;

	usleep_range(800, 1000);

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
			POWER_MASK, POWER_ON);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE,
			MS_OUTPUT_EN, MS_OUTPUT_EN);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int ms_power_off(struct rtsx_usb_ms *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;

	dev_dbg(ms_dev(host), "%s\n", __func__);

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0);

	err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
	if (err < 0)
		return err;

	if (CHECK_PKG(ucr, LQFP48))
		return ms_pull_ctl_disable_lqfp48(ucr);

	return ms_pull_ctl_disable_qfn24(ucr);
}

static int ms_transfer_data(struct rtsx_usb_ms *host, unsigned char data_dir,
		u8 tpc, u8 cfg, struct scatterlist *sg)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	unsigned int length = sg->length;
	u16 sec_cnt = (u16)(length / 512);
	u8 trans_mode, dma_dir, flag;
	unsigned int pipe;
	struct memstick_dev *card = host->msh->card;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
			__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
			length);

	if (data_dir == READ) {
		flag = MODE_CDIR;
		dma_dir = DMA_DIR_FROM_CARD;
		if (card->id.type != MEMSTICK_TYPE_PRO)
			trans_mode = MS_TM_NORMAL_READ;
		else
			trans_mode = MS_TM_AUTO_READ;
		pipe = usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN);
	} else {
		flag = MODE_CDOR;
		dma_dir = DMA_DIR_TO_CARD;
		if (card->id.type != MEMSTICK_TYPE_PRO)
			trans_mode = MS_TM_NORMAL_WRITE;
		else
			trans_mode = MS_TM_AUTO_WRITE;
		pipe = usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT);
	}

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	if (card->id.type == MEMSTICK_TYPE_PRO) {
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
				0xFF, (u8)(sec_cnt >> 8));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
				0xFF, (u8)sec_cnt);
	}
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC3,
			0xFF, (u8)(length >> 24));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC2,
			0xFF, (u8)(length >> 16));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC1,
			0xFF, (u8)(length >> 8));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC0, 0xFF,
			(u8)length);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_CTL,
			0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, RING_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | trans_mode);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);

	err = rtsx_usb_send_cmd(ucr, flag | STAGE_MS_STATUS, 100);
	if (err)
		return err;

	err = rtsx_usb_transfer_data(ucr, pipe, sg, length,
			1, NULL, 10000);
	if (err)
		goto err_out;

	err = rtsx_usb_get_rsp(ucr, 3, 15000);
	if (err)
		goto err_out;

	if (ucr->rsp_buf[0] & MS_TRANSFER_ERR ||
	    ucr->rsp_buf[1] & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
		err = -EIO;
		goto err_out;
	}
	return 0;
err_out:
	ms_clear_error(host);
	return err;
}

static int ms_write_bytes(struct rtsx_usb_ms *host, u8 tpc,
		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err, i;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);

	rtsx_usb_init_cmd(ucr);

	for (i = 0; i < cnt; i++)
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, data[i]);

	if (cnt % 2)
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, 0xFF);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);

	err = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	if (err)
		return err;

	err = rtsx_usb_get_rsp(ucr, 2, 5000);
	if (err || (ucr->rsp_buf[0] & MS_TRANSFER_ERR)) {
		u8 val;

		rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, &val);
		dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);

		if (int_reg)
			*int_reg = val & 0x0F;

		ms_print_debug_regs(host);

		ms_clear_error(host);

		if (!(tpc & 0x08)) {
			if (val & MS_CRC16_ERR)
				return -EIO;
		} else {
			if (!(val & 0x80)) {
				if (val & (MS_INT_ERR | MS_INT_CMDNK))
					return -EIO;
			}
		}

		return -ETIMEDOUT;
	}

	if (int_reg)
		*int_reg = ucr->rsp_buf[1] & 0x0F;

	return 0;
}

static int ms_read_bytes(struct rtsx_usb_ms *host, u8 tpc,
		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err, i;
	u8 *ptr;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);
	for (i = 0; i < cnt - 1; i++)
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
	if (cnt % 2)
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0);
	else
		rtsx_usb_add_cmd(ucr, READ_REG_CMD,
				PPBUF_BASE2 + cnt - 1, 0, 0);

	rtsx_usb_add_cmd(ucr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);

	err = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	if (err)
		return err;

	err = rtsx_usb_get_rsp(ucr, cnt + 2, 5000);
	if (err || (ucr->rsp_buf[0] & MS_TRANSFER_ERR)) {
		u8 val;

		rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, &val);
		dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);

		if (int_reg && (host->ifmode != MEMSTICK_SERIAL))
			*int_reg = val & 0x0F;

		ms_print_debug_regs(host);

		ms_clear_error(host);

		if (!(tpc & 0x08)) {
			if (val & MS_CRC16_ERR)
				return -EIO;
		} else {
			if (!(val & 0x80)) {
				if (val & (MS_INT_ERR | MS_INT_CMDNK))
					return -EIO;
			}
		}

		return -ETIMEDOUT;
	}

	ptr = ucr->rsp_buf + 1;
	for (i = 0; i < cnt; i++)
		data[i] = *ptr++;


	if (int_reg && (host->ifmode != MEMSTICK_SERIAL))
		*int_reg = *ptr & 0x0F;

	return 0;
}

static int rtsx_usb_ms_issue_cmd(struct rtsx_usb_ms *host)
{
	struct memstick_request *req = host->req;
	int err = 0;
	u8 cfg = 0, int_reg;

	dev_dbg(ms_dev(host), "%s\n", __func__);

	if (req->need_card_int) {
		if (host->ifmode != MEMSTICK_SERIAL)
			cfg = WAIT_INT;
	}

	if (req->long_data) {
		err = ms_transfer_data(host, req->data_dir,
				req->tpc, cfg, &(req->sg));
	} else {
		if (req->data_dir == READ)
			err = ms_read_bytes(host, req->tpc, cfg,
					req->data_len, req->data, &int_reg);
		else
			err = ms_write_bytes(host, req->tpc, cfg,
					req->data_len, req->data, &int_reg);
	}
	if (err < 0)
		return err;

	if (req->need_card_int) {
		if (host->ifmode == MEMSTICK_SERIAL) {
			err = ms_read_bytes(host, MS_TPC_GET_INT,
					NO_WAIT_INT, 1, &req->int_reg, NULL);
			if (err < 0)
				return err;
		} else {

			if (int_reg & MS_INT_CMDNK)
				req->int_reg |= MEMSTICK_INT_CMDNAK;
			if (int_reg & MS_INT_BREQ)
				req->int_reg |= MEMSTICK_INT_BREQ;
			if (int_reg & MS_INT_ERR)
				req->int_reg |= MEMSTICK_INT_ERR;
			if (int_reg & MS_INT_CED)
				req->int_reg |= MEMSTICK_INT_CED;
		}
		dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", req->int_reg);
	}

	return 0;
}

static void rtsx_usb_ms_handle_req(struct work_struct *work)
{
	struct rtsx_usb_ms *host = container_of(work,
			struct rtsx_usb_ms, handle_req);
	struct rtsx_ucr *ucr = host->ucr;
	struct memstick_host *msh = host->msh;
	int rc;

	if (!host->req) {
		pm_runtime_get_sync(ms_dev(host));
		do {
			rc = memstick_next_req(msh, &host->req);
			dev_dbg(ms_dev(host), "next req %d\n", rc);

			if (!rc) {
				mutex_lock(&ucr->dev_mutex);

				if (rtsx_usb_card_exclusive_check(ucr,
							RTSX_USB_MS_CARD))
					host->req->error = -EIO;
				else
					host->req->error =
						rtsx_usb_ms_issue_cmd(host);

				mutex_unlock(&ucr->dev_mutex);

				dev_dbg(ms_dev(host), "req result %d\n",
						host->req->error);
			}
		} while (!rc);
		pm_runtime_put(ms_dev(host));
	}

}

static void rtsx_usb_ms_request(struct memstick_host *msh)
{
	struct rtsx_usb_ms *host = memstick_priv(msh);

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	if (!host->eject)
		schedule_work(&host->handle_req);
}

static int rtsx_usb_ms_set_param(struct memstick_host *msh,
		enum memstick_param param, int value)
{
	struct rtsx_usb_ms *host = memstick_priv(msh);
	struct rtsx_ucr *ucr = host->ucr;
	unsigned int clock = 0;
	u8 ssc_depth = 0;
	int err;

	dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
			__func__, param, value);

	pm_runtime_get_sync(ms_dev(host));
	mutex_lock(&ucr->dev_mutex);

	err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_MS_CARD);
	if (err)
		goto out;

	switch (param) {
	case MEMSTICK_POWER:
		if (value == host->power_mode)
			break;

		if (value == MEMSTICK_POWER_ON) {
			pm_runtime_get_sync(ms_dev(host));
			err = ms_power_on(host);
		} else if (value == MEMSTICK_POWER_OFF) {
			err = ms_power_off(host);
			if (host->msh->card)
				pm_runtime_put_noidle(ms_dev(host));
			else
				pm_runtime_put(ms_dev(host));
		} else
			err = -EINVAL;
		if (!err)
			host->power_mode = value;
		break;

	case MEMSTICK_INTERFACE:
		if (value == MEMSTICK_SERIAL) {
			clock = 19000000;
			ssc_depth = SSC_DEPTH_512K;
			err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A,
				       MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
			if (err < 0)
				break;
		} else if (value == MEMSTICK_PAR4) {
			clock = 39000000;
			ssc_depth = SSC_DEPTH_1M;

			err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A,
					MS_BUS_WIDTH_4 | PUSH_TIME_ODD |
					MS_NO_CHECK_INT);
			if (err < 0)
				break;
		} else {
			err = -EINVAL;
			break;
		}

		err = rtsx_usb_switch_clock(ucr, clock,
				ssc_depth, false, true, false);
		if (err < 0) {
			dev_dbg(ms_dev(host), "switch clock failed\n");
			break;
		}

		host->ssc_depth = ssc_depth;
		host->clock = clock;
		host->ifmode = value;
		break;
	default:
		err = -EINVAL;
		break;
	}
out:
	mutex_unlock(&ucr->dev_mutex);
	pm_runtime_put(ms_dev(host));

	/* power-on delay */
	if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON)
		usleep_range(10000, 12000);

	dev_dbg(ms_dev(host), "%s: return = %d\n", __func__, err);
	return err;
}

#ifdef CONFIG_PM_SLEEP
static int rtsx_usb_ms_suspend(struct device *dev)
{
	struct rtsx_usb_ms *host = dev_get_drvdata(dev);
	struct memstick_host *msh = host->msh;

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	memstick_suspend_host(msh);
	return 0;
}

static int rtsx_usb_ms_resume(struct device *dev)
{
	struct rtsx_usb_ms *host = dev_get_drvdata(dev);
	struct memstick_host *msh = host->msh;

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	memstick_resume_host(msh);
	return 0;
}
#endif /* CONFIG_PM_SLEEP */

/*
 * Thread function of ms card slot detection. The thread starts right after
 * successful host addition. It stops while the driver removal function sets
 * host->eject true.
 */
static int rtsx_usb_detect_ms_card(void *__host)
{
	struct rtsx_usb_ms *host = (struct rtsx_usb_ms *)__host;
	struct rtsx_ucr *ucr = host->ucr;
	u8 val = 0;
	int err;

	for (;;) {
		pm_runtime_get_sync(ms_dev(host));
		mutex_lock(&ucr->dev_mutex);

		/* Check pending MS card changes */
		err = rtsx_usb_read_register(ucr, CARD_INT_PEND, &val);
		if (err) {
			mutex_unlock(&ucr->dev_mutex);
			goto poll_again;
		}

		/* Clear the pending */
		rtsx_usb_write_register(ucr, CARD_INT_PEND,
				XD_INT | MS_INT | SD_INT,
				XD_INT | MS_INT | SD_INT);

		mutex_unlock(&ucr->dev_mutex);

		if (val & MS_INT) {
			dev_dbg(ms_dev(host), "MS slot change detected\n");
			memstick_detect_change(host->msh);
		}

poll_again:
		pm_runtime_put(ms_dev(host));
		if (host->eject)
			break;

		schedule_timeout_idle(HZ);
	}

	complete(&host->detect_ms_exit);
	return 0;
}

static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)
{
	struct memstick_host *msh;
	struct rtsx_usb_ms *host;
	struct rtsx_ucr *ucr;
	int err;

	ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent));
	if (!ucr)
		return -ENXIO;

	dev_dbg(&(pdev->dev),
			"Realtek USB Memstick controller found\n");

	msh = memstick_alloc_host(sizeof(*host), &pdev->dev);
	if (!msh)
		return -ENOMEM;

	host = memstick_priv(msh);
	host->ucr = ucr;
	host->msh = msh;
	host->pdev = pdev;
	host->power_mode = MEMSTICK_POWER_OFF;
	platform_set_drvdata(pdev, host);

	mutex_init(&host->host_mutex);
	INIT_WORK(&host->handle_req, rtsx_usb_ms_handle_req);

	init_completion(&host->detect_ms_exit);
	host->detect_ms = kthread_create(rtsx_usb_detect_ms_card, host,
			"rtsx_usb_ms_%d", pdev->id);
	if (IS_ERR(host->detect_ms)) {
		dev_dbg(&(pdev->dev),
				"Unable to create polling thread.\n");
		err = PTR_ERR(host->detect_ms);
		goto err_out;
	}

	msh->request = rtsx_usb_ms_request;
	msh->set_param = rtsx_usb_ms_set_param;
	msh->caps = MEMSTICK_CAP_PAR4;

	pm_runtime_enable(&pdev->dev);
	err = memstick_add_host(msh);
	if (err)
		goto err_out;

	wake_up_process(host->detect_ms);
	return 0;
err_out:
	memstick_free_host(msh);
	return err;
}

static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
{
	struct rtsx_usb_ms *host = platform_get_drvdata(pdev);
	struct memstick_host *msh;
	int err;

	msh = host->msh;
	host->eject = true;
	cancel_work_sync(&host->handle_req);

	mutex_lock(&host->host_mutex);
	if (host->req) {
		dev_dbg(&(pdev->dev),
			"%s: Controller removed during transfer\n",
			dev_name(&msh->dev));
		host->req->error = -ENOMEDIUM;
		do {
			err = memstick_next_req(msh, &host->req);
			if (!err)
				host->req->error = -ENOMEDIUM;
		} while (!err);
	}
	mutex_unlock(&host->host_mutex);

	wait_for_completion(&host->detect_ms_exit);
	memstick_remove_host(msh);
	memstick_free_host(msh);

	/* Balance possible unbalanced usage count
	 * e.g. unconditional module removal
	 */
	if (pm_runtime_active(ms_dev(host)))
		pm_runtime_put(ms_dev(host));

	pm_runtime_disable(&pdev->dev);
	platform_set_drvdata(pdev, NULL);

	dev_dbg(&(pdev->dev),
		": Realtek USB Memstick controller has been removed\n");

	return 0;
}

static SIMPLE_DEV_PM_OPS(rtsx_usb_ms_pm_ops,
		rtsx_usb_ms_suspend, rtsx_usb_ms_resume);

static struct platform_device_id rtsx_usb_ms_ids[] = {
	{
		.name = "rtsx_usb_ms",
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, rtsx_usb_ms_ids);

static struct platform_driver rtsx_usb_ms_driver = {
	.probe		= rtsx_usb_ms_drv_probe,
	.remove		= rtsx_usb_ms_drv_remove,
	.id_table       = rtsx_usb_ms_ids,
	.driver		= {
		.name	= "rtsx_usb_ms",
		.pm	= &rtsx_usb_ms_pm_ops,
	},
};
module_platform_driver(rtsx_usb_ms_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>");
MODULE_DESCRIPTION("Realtek USB Memstick Card Host Driver");
