diff mbox

[2/2] mmc: rtsx: Revert "mmc: rtsx: add support for pre_req and post_req"

Message ID 6a8f18cad47244e849adf8a731c621932fa777e0.1398735435.git.micky_ching@realsil.com.cn (mailing list archive)
State New, archived
Headers show

Commit Message

micky_ching@realsil.com.cn April 29, 2014, 1:54 a.m. UTC
From: Micky Ching <micky_ching@realsil.com.cn>

This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.

commit <mmc: rtsx: add support for pre_req and post_req> did use
mutex_unlock() in tasklet, but mutex_unlock() can't used in
tasklet(atomic context). The driver need use mutex to avoid concurrency,
so we can't use tasklet here, the patch need to be removed.

The spinlock host->lock and pcr->lock may deadlock, one way to solve the
deadlock is remove host->lock in sd_isr_done_transfer(), but if using
workqueue the we can avoid using the spinlock and also avoid the problem.

Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
---
 drivers/mfd/rtsx_pcr.c            |  132 ++++--------
 drivers/mmc/host/rtsx_pci_sdmmc.c |  418 ++++++-------------------------------
 include/linux/mfd/rtsx_common.h   |    1 -
 include/linux/mfd/rtsx_pci.h      |    6 -
 4 files changed, 109 insertions(+), 448 deletions(-)

Comments

Ulf Hansson April 29, 2014, 7:36 a.m. UTC | #1
On 29 April 2014 03:54,  <micky_ching@realsil.com.cn> wrote:
> From: Micky Ching <micky_ching@realsil.com.cn>
>
> This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.
>
> commit <mmc: rtsx: add support for pre_req and post_req> did use
> mutex_unlock() in tasklet, but mutex_unlock() can't used in
> tasklet(atomic context). The driver need use mutex to avoid concurrency,
> so we can't use tasklet here, the patch need to be removed.
>
> The spinlock host->lock and pcr->lock may deadlock, one way to solve the
> deadlock is remove host->lock in sd_isr_done_transfer(), but if using
> workqueue the we can avoid using the spinlock and also avoid the problem.
>
> Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>

Acked-by: Ulf Hansson <ulf.hansson@linaro.org>

> ---
>  drivers/mfd/rtsx_pcr.c            |  132 ++++--------
>  drivers/mmc/host/rtsx_pci_sdmmc.c |  418 ++++++-------------------------------
>  include/linux/mfd/rtsx_common.h   |    1 -
>  include/linux/mfd/rtsx_pci.h      |    6 -
>  4 files changed, 109 insertions(+), 448 deletions(-)
>
> diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
> index c9de3d5..1d15735 100644
> --- a/drivers/mfd/rtsx_pcr.c
> +++ b/drivers/mfd/rtsx_pcr.c
> @@ -338,28 +338,58 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
>                 int num_sg, bool read, int timeout)
>  {
>         struct completion trans_done;
> -       int err = 0, count;
> +       u8 dir;
> +       int err = 0, i, count;
>         long timeleft;
>         unsigned long flags;
> +       struct scatterlist *sg;
> +       enum dma_data_direction dma_dir;
> +       u32 val;
> +       dma_addr_t addr;
> +       unsigned int len;
> +
> +       dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
> +
> +       /* don't transfer data during abort processing */
> +       if (pcr->remove_pci)
> +               return -EINVAL;
> +
> +       if ((sglist == NULL) || (num_sg <= 0))
> +               return -EINVAL;
>
> -       count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
> +       if (read) {
> +               dir = DEVICE_TO_HOST;
> +               dma_dir = DMA_FROM_DEVICE;
> +       } else {
> +               dir = HOST_TO_DEVICE;
> +               dma_dir = DMA_TO_DEVICE;
> +       }
> +
> +       count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
>         if (count < 1) {
>                 dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
>                 return -EINVAL;
>         }
>         dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
>
> +       val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
> +       pcr->sgi = 0;
> +       for_each_sg(sglist, sg, count, i) {
> +               addr = sg_dma_address(sg);
> +               len = sg_dma_len(sg);
> +               rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
> +       }
>
>         spin_lock_irqsave(&pcr->lock, flags);
>
>         pcr->done = &trans_done;
>         pcr->trans_result = TRANS_NOT_READY;
>         init_completion(&trans_done);
> +       rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
> +       rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
>
>         spin_unlock_irqrestore(&pcr->lock, flags);
>
> -       rtsx_pci_dma_transfer(pcr, sglist, count, read);
> -
>         timeleft = wait_for_completion_interruptible_timeout(
>                         &trans_done, msecs_to_jiffies(timeout));
>         if (timeleft <= 0) {
> @@ -383,7 +413,7 @@ out:
>         pcr->done = NULL;
>         spin_unlock_irqrestore(&pcr->lock, flags);
>
> -       rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
> +       dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
>
>         if ((err < 0) && (err != -ENODEV))
>                 rtsx_pci_stop_cmd(pcr);
> @@ -395,73 +425,6 @@ out:
>  }
>  EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
>
> -int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int num_sg, bool read)
> -{
> -       enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
> -
> -       if (pcr->remove_pci)
> -               return -EINVAL;
> -
> -       if ((sglist == NULL) || num_sg < 1)
> -               return -EINVAL;
> -
> -       return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
> -}
> -EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
> -
> -int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int num_sg, bool read)
> -{
> -       enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
> -
> -       if (pcr->remove_pci)
> -               return -EINVAL;
> -
> -       if (sglist == NULL || num_sg < 1)
> -               return -EINVAL;
> -
> -       dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
> -       return num_sg;
> -}
> -EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
> -
> -int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int sg_count, bool read)
> -{
> -       struct scatterlist *sg;
> -       dma_addr_t addr;
> -       unsigned int len;
> -       int i;
> -       u32 val;
> -       u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
> -       unsigned long flags;
> -
> -       if (pcr->remove_pci)
> -               return -EINVAL;
> -
> -       if ((sglist == NULL) || (sg_count < 1))
> -               return -EINVAL;
> -
> -       val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
> -       pcr->sgi = 0;
> -       for_each_sg(sglist, sg, sg_count, i) {
> -               addr = sg_dma_address(sg);
> -               len = sg_dma_len(sg);
> -               rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1);
> -       }
> -
> -       spin_lock_irqsave(&pcr->lock, flags);
> -
> -       rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
> -       rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
> -
> -       spin_unlock_irqrestore(&pcr->lock, flags);
> -
> -       return 0;
> -}
> -EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer);
> -
>  int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
>  {
>         int err;
> @@ -873,8 +836,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
>         int_reg = rtsx_pci_readl(pcr, RTSX_BIPR);
>         /* Clear interrupt flag */
>         rtsx_pci_writel(pcr, RTSX_BIPR, int_reg);
> -       dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg);
> -
>         if ((int_reg & pcr->bier) == 0) {
>                 spin_unlock(&pcr->lock);
>                 return IRQ_NONE;
> @@ -905,28 +866,17 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
>         }
>
>         if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
> -               if (int_reg & (TRANS_FAIL_INT | DELINK_INT))
> +               if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
>                         pcr->trans_result = TRANS_RESULT_FAIL;
> -               else if (int_reg & TRANS_OK_INT)
> +                       if (pcr->done)
> +                               complete(pcr->done);
> +               } else if (int_reg & TRANS_OK_INT) {
>                         pcr->trans_result = TRANS_RESULT_OK;
> -
> -               if (pcr->done)
> -                       complete(pcr->done);
> -
> -               if (int_reg & SD_EXIST) {
> -                       struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
> -                       if (slot && slot->done_transfer)
> -                               slot->done_transfer(slot->p_dev);
> -               }
> -
> -               if (int_reg & MS_EXIST) {
> -                       struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
> -                       if (slot && slot->done_transfer)
> -                               slot->done_transfer(slot->p_dev);
> +                       if (pcr->done)
> +                               complete(pcr->done);
>                 }
>         }
>
> -
>         if (pcr->card_inserted || pcr->card_removed)
>                 schedule_delayed_work(&pcr->carddet_work,
>                                 msecs_to_jiffies(200));
> diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
> index 76cfdcc..0d51964 100644
> --- a/drivers/mmc/host/rtsx_pci_sdmmc.c
> +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
> @@ -31,28 +31,14 @@
>  #include <linux/mfd/rtsx_pci.h>
>  #include <asm/unaligned.h>
>
> -struct realtek_next {
> -       unsigned int    sg_count;
> -       s32             cookie;
> -};
> -
>  struct realtek_pci_sdmmc {
>         struct platform_device  *pdev;
>         struct rtsx_pcr         *pcr;
>         struct mmc_host         *mmc;
>         struct mmc_request      *mrq;
> -       struct mmc_command      *cmd;
> -       struct mmc_data         *data;
> -
> -       spinlock_t              lock;
> -       struct timer_list       timer;
> -       struct tasklet_struct   cmd_tasklet;
> -       struct tasklet_struct   data_tasklet;
> -       struct tasklet_struct   finish_tasklet;
> -
> -       u8                      rsp_type;
> -       u8                      rsp_len;
> -       int                     sg_count;
> +
> +       struct mutex            host_mutex;
> +
>         u8                      ssc_depth;
>         unsigned int            clock;
>         bool                    vpclk;
> @@ -62,13 +48,8 @@ struct realtek_pci_sdmmc {
>         int                     power_state;
>  #define SDMMC_POWER_ON         1
>  #define SDMMC_POWER_OFF                0
> -
> -       struct realtek_next     next_data;
>  };
>
> -static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
> -               struct mmc_request *mrq);
> -
>  static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
>  {
>         return &(host->pdev->dev);
> @@ -105,95 +86,6 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
>  #define sd_print_debug_regs(host)
>  #endif /* DEBUG */
>
> -static void sd_isr_done_transfer(struct platform_device *pdev)
> -{
> -       struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
> -
> -       spin_lock(&host->lock);
> -       if (host->cmd)
> -               tasklet_schedule(&host->cmd_tasklet);
> -       if (host->data)
> -               tasklet_schedule(&host->data_tasklet);
> -       spin_unlock(&host->lock);
> -}
> -
> -static void sd_request_timeout(unsigned long host_addr)
> -{
> -       struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
> -       unsigned long flags;
> -
> -       spin_lock_irqsave(&host->lock, flags);
> -
> -       if (!host->mrq) {
> -               dev_err(sdmmc_dev(host), "error: no request exist\n");
> -               goto out;
> -       }
> -
> -       if (host->cmd)
> -               host->cmd->error = -ETIMEDOUT;
> -       if (host->data)
> -               host->data->error = -ETIMEDOUT;
> -
> -       dev_dbg(sdmmc_dev(host), "timeout for request\n");
> -
> -out:
> -       tasklet_schedule(&host->finish_tasklet);
> -       spin_unlock_irqrestore(&host->lock, flags);
> -}
> -
> -static void sd_finish_request(unsigned long host_addr)
> -{
> -       struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
> -       struct rtsx_pcr *pcr = host->pcr;
> -       struct mmc_request *mrq;
> -       struct mmc_command *cmd;
> -       struct mmc_data *data;
> -       unsigned long flags;
> -       bool any_error;
> -
> -       spin_lock_irqsave(&host->lock, flags);
> -
> -       del_timer(&host->timer);
> -       mrq = host->mrq;
> -       if (!mrq) {
> -               dev_err(sdmmc_dev(host), "error: no request need finish\n");
> -               goto out;
> -       }
> -
> -       cmd = mrq->cmd;
> -       data = mrq->data;
> -
> -       any_error = (mrq->sbc && mrq->sbc->error) ||
> -               (mrq->stop && mrq->stop->error) ||
> -               (cmd && cmd->error) || (data && data->error);
> -
> -       if (any_error) {
> -               rtsx_pci_stop_cmd(pcr);
> -               sd_clear_error(host);
> -       }
> -
> -       if (data) {
> -               if (any_error)
> -                       data->bytes_xfered = 0;
> -               else
> -                       data->bytes_xfered = data->blocks * data->blksz;
> -
> -               if (!data->host_cookie)
> -                       rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len,
> -                                       data->flags & MMC_DATA_READ);
> -
> -       }
> -
> -       host->mrq = NULL;
> -       host->cmd = NULL;
> -       host->data = NULL;
> -
> -out:
> -       spin_unlock_irqrestore(&host->lock, flags);
> -       mutex_unlock(&pcr->pcr_mutex);
> -       mmc_request_done(host->mmc, mrq);
> -}
> -
>  static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
>                 u8 *buf, int buf_len, int timeout)
>  {
> @@ -311,7 +203,8 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
>         return 0;
>  }
>
> -static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
> +static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
> +               struct mmc_command *cmd)
>  {
>         struct rtsx_pcr *pcr = host->pcr;
>         u8 cmd_idx = (u8)cmd->opcode;
> @@ -319,14 +212,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
>         int err = 0;
>         int timeout = 100;
>         int i;
> +       u8 *ptr;
> +       int stat_idx = 0;
>         u8 rsp_type;
>         int rsp_len = 5;
> -       unsigned long flags;
> -
> -       if (host->cmd)
> -               dev_err(sdmmc_dev(host), "error: cmd already exist\n");
> -
> -       host->cmd = cmd;
> +       bool clock_toggled = false;
>
>         dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
>                         __func__, cmd_idx, arg);
> @@ -364,8 +254,6 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
>                 err = -EINVAL;
>                 goto out;
>         }
> -       host->rsp_type = rsp_type;
> -       host->rsp_len = rsp_len;
>
>         if (rsp_type == SD_RSP_TYPE_R1b)
>                 timeout = 3000;
> @@ -375,6 +263,8 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
>                                 0xFF, SD_CLK_TOGGLE_EN);
>                 if (err < 0)
>                         goto out;
> +
> +               clock_toggled = true;
>         }
>
>         rtsx_pci_init_cmd(pcr);
> @@ -398,60 +288,25 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
>                 /* Read data from ping-pong buffer */
>                 for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
>                         rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
> +               stat_idx = 16;
>         } else if (rsp_type != SD_RSP_TYPE_R0) {
>                 /* Read data from SD_CMDx registers */
>                 for (i = SD_CMD0; i <= SD_CMD4; i++)
>                         rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
> +               stat_idx = 5;
>         }
>
>         rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0);
>
> -       mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout));
> -
> -       spin_lock_irqsave(&pcr->lock, flags);
> -       pcr->trans_result = TRANS_NOT_READY;
> -       rtsx_pci_send_cmd_no_wait(pcr);
> -       spin_unlock_irqrestore(&pcr->lock, flags);
> -
> -       return;
> -
> -out:
> -       cmd->error = err;
> -       tasklet_schedule(&host->finish_tasklet);
> -}
> -
> -static void sd_get_rsp(unsigned long host_addr)
> -{
> -       struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
> -       struct rtsx_pcr *pcr = host->pcr;
> -       struct mmc_command *cmd;
> -       int i, err = 0, stat_idx;
> -       u8 *ptr, rsp_type;
> -       unsigned long flags;
> -
> -       spin_lock_irqsave(&host->lock, flags);
> -
> -       cmd = host->cmd;
> -       host->cmd = NULL;
> -
> -       if (!cmd) {
> -               dev_err(sdmmc_dev(host), "error: cmd not exist\n");
> +       err = rtsx_pci_send_cmd(pcr, timeout);
> +       if (err < 0) {
> +               sd_print_debug_regs(host);
> +               sd_clear_error(host);
> +               dev_dbg(sdmmc_dev(host),
> +                       "rtsx_pci_send_cmd error (err = %d)\n", err);
>                 goto out;
>         }
>
> -       spin_lock(&pcr->lock);
> -       if (pcr->trans_result == TRANS_NO_DEVICE)
> -               err = -ENODEV;
> -       else if (pcr->trans_result != TRANS_RESULT_OK)
> -               err = -EINVAL;
> -       spin_unlock(&pcr->lock);
> -
> -       if (err < 0)
> -               goto out;
> -
> -       rsp_type = host->rsp_type;
> -       stat_idx = host->rsp_len;
> -
>         if (rsp_type == SD_RSP_TYPE_R0) {
>                 err = 0;
>                 goto out;
> @@ -488,106 +343,26 @@ static void sd_get_rsp(unsigned long host_addr)
>                                 cmd->resp[0]);
>         }
>
> -       if (cmd == host->mrq->sbc) {
> -               sd_send_cmd(host, host->mrq->cmd);
> -               spin_unlock_irqrestore(&host->lock, flags);
> -               return;
> -       }
> -
> -       if (cmd == host->mrq->stop)
> -               goto out;
> -
> -       if (cmd->data) {
> -               sd_start_multi_rw(host, host->mrq);
> -               spin_unlock_irqrestore(&host->lock, flags);
> -               return;
> -       }
> -
>  out:
>         cmd->error = err;
>
> -       tasklet_schedule(&host->finish_tasklet);
> -       spin_unlock_irqrestore(&host->lock, flags);
> -}
> -
> -static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host,
> -                       struct mmc_data *data, struct realtek_next *next)
> -{
> -       struct rtsx_pcr *pcr = host->pcr;
> -       int read = data->flags & MMC_DATA_READ;
> -       int sg_count = 0;
> -
> -       if (!next && data->host_cookie &&
> -               data->host_cookie != host->next_data.cookie) {
> -               dev_err(sdmmc_dev(host),
> -                       "error: invalid cookie data[%d] host[%d]\n",
> -                       data->host_cookie, host->next_data.cookie);
> -               data->host_cookie = 0;
> -       }
> -
> -       if (next || (!next && data->host_cookie != host->next_data.cookie))
> -               sg_count = rtsx_pci_dma_map_sg(pcr,
> -                               data->sg, data->sg_len, read);
> -       else
> -               sg_count = host->next_data.sg_count;
> -
> -       if (next) {
> -               next->sg_count = sg_count;
> -               if (++next->cookie < 0)
> -                       next->cookie = 1;
> -               data->host_cookie = next->cookie;
> -       }
> -
> -       return sg_count;
> -}
> -
> -static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
> -               bool is_first_req)
> -{
> -       struct realtek_pci_sdmmc *host = mmc_priv(mmc);
> -       struct mmc_data *data = mrq->data;
> -
> -       if (data->host_cookie) {
> -               dev_err(sdmmc_dev(host),
> -                       "error: descard already cookie data[%d]\n",
> -                       data->host_cookie);
> -               data->host_cookie = 0;
> -       }
> -
> -       dev_dbg(sdmmc_dev(host), "dma sg prepared: %d\n",
> -               sd_pre_dma_transfer(host, data, &host->next_data));
> -}
> -
> -static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
> -               int err)
> -{
> -       struct realtek_pci_sdmmc *host = mmc_priv(mmc);
> -       struct rtsx_pcr *pcr = host->pcr;
> -       struct mmc_data *data = mrq->data;
> -       int read = data->flags & MMC_DATA_READ;
> -
> -       rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read);
> -       data->host_cookie = 0;
> +       if (err && clock_toggled)
> +               rtsx_pci_write_register(pcr, SD_BUS_STAT,
> +                               SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
>  }
>
> -static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
> -               struct mmc_request *mrq)
> +static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
>  {
>         struct rtsx_pcr *pcr = host->pcr;
>         struct mmc_host *mmc = host->mmc;
>         struct mmc_card *card = mmc->card;
>         struct mmc_data *data = mrq->data;
>         int uhs = mmc_card_uhs(card);
> -       int read = data->flags & MMC_DATA_READ;
> +       int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
>         u8 cfg2, trans_mode;
>         int err;
>         size_t data_len = data->blksz * data->blocks;
>
> -       if (host->data)
> -               dev_err(sdmmc_dev(host), "error: data already exist\n");
> -
> -       host->data = data;
> -
>         if (read) {
>                 cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
>                         SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0;
> @@ -638,54 +413,15 @@ static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
>         rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
>                         SD_TRANSFER_END, SD_TRANSFER_END);
>
> -       mod_timer(&host->timer, jiffies + 10 * HZ);
>         rtsx_pci_send_cmd_no_wait(pcr);
>
> -       err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read);
> -       if (err < 0) {
> -               data->error = err;
> -               tasklet_schedule(&host->finish_tasklet);
> -       }
> -       return 0;
> -}
> -
> -static void sd_finish_multi_rw(unsigned long host_addr)
> -{
> -       struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
> -       struct rtsx_pcr *pcr = host->pcr;
> -       struct mmc_data *data;
> -       int err = 0;
> -       unsigned long flags;
> -
> -       spin_lock_irqsave(&host->lock, flags);
> -
> -       if (!host->data) {
> -               dev_err(sdmmc_dev(host), "error: no data exist\n");
> -               goto out;
> -       }
> -
> -       data = host->data;
> -       host->data = NULL;
> -
> -       if (pcr->trans_result == TRANS_NO_DEVICE)
> -               err = -ENODEV;
> -       else if (pcr->trans_result != TRANS_RESULT_OK)
> -               err = -EINVAL;
> -
> +       err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000);
>         if (err < 0) {
> -               data->error = err;
> -               goto out;
> -       }
> -
> -       if (!host->mrq->sbc && data->stop) {
> -               sd_send_cmd(host, data->stop);
> -               spin_unlock_irqrestore(&host->lock, flags);
> -               return;
> +               sd_clear_error(host);
> +               return err;
>         }
>
> -out:
> -       tasklet_schedule(&host->finish_tasklet);
> -       spin_unlock_irqrestore(&host->lock, flags);
> +       return 0;
>  }
>
>  static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host)
> @@ -904,13 +640,6 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
>         return 0;
>  }
>
> -static inline bool sd_use_muti_rw(struct mmc_command *cmd)
> -{
> -       return mmc_op_multi(cmd->opcode) ||
> -               (cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
> -               (cmd->opcode == MMC_WRITE_BLOCK);
> -}
> -
>  static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  {
>         struct realtek_pci_sdmmc *host = mmc_priv(mmc);
> @@ -919,14 +648,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>         struct mmc_data *data = mrq->data;
>         unsigned int data_size = 0;
>         int err;
> -       unsigned long flags;
> -
> -       mutex_lock(&pcr->pcr_mutex);
> -       spin_lock_irqsave(&host->lock, flags);
> -
> -       if (host->mrq)
> -               dev_err(sdmmc_dev(host), "error: request already exist\n");
> -       host->mrq = mrq;
>
>         if (host->eject) {
>                 cmd->error = -ENOMEDIUM;
> @@ -939,6 +660,8 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>                 goto finish;
>         }
>
> +       mutex_lock(&pcr->pcr_mutex);
> +
>         rtsx_pci_start_run(pcr);
>
>         rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
> @@ -947,28 +670,46 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>         rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
>                         CARD_SHARE_MASK, CARD_SHARE_48_SD);
>
> +       mutex_lock(&host->host_mutex);
> +       host->mrq = mrq;
> +       mutex_unlock(&host->host_mutex);
> +
>         if (mrq->data)
>                 data_size = data->blocks * data->blksz;
>
> -       if (sd_use_muti_rw(cmd))
> -               host->sg_count = sd_pre_dma_transfer(host, data, NULL);
> +       if (!data_size || mmc_op_multi(cmd->opcode) ||
> +                       (cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
> +                       (cmd->opcode == MMC_WRITE_BLOCK)) {
> +               sd_send_cmd_get_rsp(host, cmd);
>
> -       if (!data_size || sd_use_muti_rw(cmd)) {
> -               if (mrq->sbc)
> -                       sd_send_cmd(host, mrq->sbc);
> -               else
> -                       sd_send_cmd(host, cmd);
> -               spin_unlock_irqrestore(&host->lock, flags);
> +               if (!cmd->error && data_size) {
> +                       sd_rw_multi(host, mrq);
> +
> +                       if (mmc_op_multi(cmd->opcode) && mrq->stop)
> +                               sd_send_cmd_get_rsp(host, mrq->stop);
> +               }
>         } else {
> -               spin_unlock_irqrestore(&host->lock, flags);
>                 sd_normal_rw(host, mrq);
> -               tasklet_schedule(&host->finish_tasklet);
>         }
> -       return;
> +
> +       if (mrq->data) {
> +               if (cmd->error || data->error)
> +                       data->bytes_xfered = 0;
> +               else
> +                       data->bytes_xfered = data->blocks * data->blksz;
> +       }
> +
> +       mutex_unlock(&pcr->pcr_mutex);
>
>  finish:
> -       tasklet_schedule(&host->finish_tasklet);
> -       spin_unlock_irqrestore(&host->lock, flags);
> +       if (cmd->error)
> +               dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
> +
> +       mutex_lock(&host->host_mutex);
> +       host->mrq = NULL;
> +       mutex_unlock(&host->host_mutex);
> +
> +       mmc_request_done(mmc, mrq);
>  }
>
>  static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
> @@ -1405,8 +1146,6 @@ out:
>  }
>
>  static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
> -       .pre_req = sdmmc_pre_req,
> -       .post_req = sdmmc_post_req,
>         .request = sdmmc_request,
>         .set_ios = sdmmc_set_ios,
>         .get_ro = sdmmc_get_ro,
> @@ -1470,7 +1209,6 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
>         struct realtek_pci_sdmmc *host;
>         struct rtsx_pcr *pcr;
>         struct pcr_handle *handle = pdev->dev.platform_data;
> -       unsigned long host_addr;
>
>         if (!handle)
>                 return -ENXIO;
> @@ -1494,15 +1232,8 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
>         pcr->slots[RTSX_SD_CARD].p_dev = pdev;
>         pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
>
> -       host_addr = (unsigned long)host;
> -       host->next_data.cookie = 1;
> -       setup_timer(&host->timer, sd_request_timeout, host_addr);
> -       tasklet_init(&host->cmd_tasklet, sd_get_rsp, host_addr);
> -       tasklet_init(&host->data_tasklet, sd_finish_multi_rw, host_addr);
> -       tasklet_init(&host->finish_tasklet, sd_finish_request, host_addr);
> -       spin_lock_init(&host->lock);
> +       mutex_init(&host->host_mutex);
>
> -       pcr->slots[RTSX_SD_CARD].done_transfer = sd_isr_done_transfer;
>         realtek_init_host(host);
>
>         mmc_add_host(mmc);
> @@ -1515,8 +1246,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
>         struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
>         struct rtsx_pcr *pcr;
>         struct mmc_host *mmc;
> -       struct mmc_request *mrq;
> -       unsigned long flags;
>
>         if (!host)
>                 return 0;
> @@ -1524,33 +1253,22 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
>         pcr = host->pcr;
>         pcr->slots[RTSX_SD_CARD].p_dev = NULL;
>         pcr->slots[RTSX_SD_CARD].card_event = NULL;
> -       pcr->slots[RTSX_SD_CARD].done_transfer = NULL;
>         mmc = host->mmc;
> -       mrq = host->mrq;
>
> -       spin_lock_irqsave(&host->lock, flags);
> +       mutex_lock(&host->host_mutex);
>         if (host->mrq) {
>                 dev_dbg(&(pdev->dev),
>                         "%s: Controller removed during transfer\n",
>                         mmc_hostname(mmc));
>
> -               if (mrq->sbc)
> -                       mrq->sbc->error = -ENOMEDIUM;
> -               if (mrq->cmd)
> -                       mrq->cmd->error = -ENOMEDIUM;
> -               if (mrq->stop)
> -                       mrq->stop->error = -ENOMEDIUM;
> -               if (mrq->data)
> -                       mrq->data->error = -ENOMEDIUM;
> +               rtsx_pci_complete_unfinished_transfer(pcr);
>
> -               tasklet_schedule(&host->finish_tasklet);
> +               host->mrq->cmd->error = -ENOMEDIUM;
> +               if (host->mrq->stop)
> +                       host->mrq->stop->error = -ENOMEDIUM;
> +               mmc_request_done(mmc, host->mrq);
>         }
> -       spin_unlock_irqrestore(&host->lock, flags);
> -
> -       del_timer_sync(&host->timer);
> -       tasklet_kill(&host->cmd_tasklet);
> -       tasklet_kill(&host->data_tasklet);
> -       tasklet_kill(&host->finish_tasklet);
> +       mutex_unlock(&host->host_mutex);
>
>         mmc_remove_host(mmc);
>         host->eject = true;
> diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h
> index 7c36cc5..443176e 100644
> --- a/include/linux/mfd/rtsx_common.h
> +++ b/include/linux/mfd/rtsx_common.h
> @@ -45,7 +45,6 @@ struct platform_device;
>  struct rtsx_slot {
>         struct platform_device  *p_dev;
>         void                    (*card_event)(struct platform_device *p_dev);
> -       void                    (*done_transfer)(struct platform_device *p_dev);
>  };
>
>  #endif
> diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
> index 8d6bbd6..a383597 100644
> --- a/include/linux/mfd/rtsx_pci.h
> +++ b/include/linux/mfd/rtsx_pci.h
> @@ -943,12 +943,6 @@ void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr);
>  int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout);
>  int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
>                 int num_sg, bool read, int timeout);
> -int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int num_sg, bool read);
> -int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int num_sg, bool read);
> -int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
> -               int sg_count, bool read);
>  int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
>  int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
>  int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card);
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson May 5, 2014, 9:31 a.m. UTC | #2
On 29 April 2014 09:36, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 29 April 2014 03:54,  <micky_ching@realsil.com.cn> wrote:
>> From: Micky Ching <micky_ching@realsil.com.cn>
>>
>> This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.
>>
>> commit <mmc: rtsx: add support for pre_req and post_req> did use
>> mutex_unlock() in tasklet, but mutex_unlock() can't used in
>> tasklet(atomic context). The driver need use mutex to avoid concurrency,
>> so we can't use tasklet here, the patch need to be removed.
>>
>> The spinlock host->lock and pcr->lock may deadlock, one way to solve the
>> deadlock is remove host->lock in sd_isr_done_transfer(), but if using
>> workqueue the we can avoid using the spinlock and also avoid the problem.
>>
>> Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
>
> Acked-by: Ulf Hansson <ulf.hansson@linaro.org>

Hi Lee,

Would you mind to pick this up and send it for 3.15 fixes?

The other revert "[PATCH 1/2] mmc: rtsx: Revert "mmc: rtsx: modify
error handle and remove smatch warnings", needs to go through the mmc
tree.

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
micky_ching@realsil.com.cn May 8, 2014, 5:54 a.m. UTC | #3
Hi Lee

Sorry for previous email, only [PATCH 2/2] mmc: rtsx: Revert "mmc: rtsx: 
add support for pre_reqand post_req"
if need for 3.15 fix.

Best Regards.
micky.
On 04/29/2014 03:36 PM, Ulf Hansson wrote:
> On 29 April 2014 03:54,<micky_ching@realsil.com.cn>  wrote:
>> >From: Micky Ching<micky_ching@realsil.com.cn>
>> >
>> >This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.
>> >
>> >commit <mmc: rtsx: add support for pre_req and post_req> did use
>> >mutex_unlock() in tasklet, but mutex_unlock() can't used in
>> >tasklet(atomic context). The driver need use mutex to avoid concurrency,
>> >so we can't use tasklet here, the patch need to be removed.
>> >
>> >The spinlock host->lock and pcr->lock may deadlock, one way to solve the
>> >deadlock is remove host->lock in sd_isr_done_transfer(), but if using
>> >workqueue the we can avoid using the spinlock and also avoid the problem.
>> >
>> >Signed-off-by: Micky Ching<micky_ching@realsil.com.cn>
> Acked-by: Ulf Hansson<ulf.hansson@linaro.org>
>

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lee Jones May 8, 2014, 7:53 a.m. UTC | #4
> >> This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.
> >>
> >> commit <mmc: rtsx: add support for pre_req and post_req> did use
> >> mutex_unlock() in tasklet, but mutex_unlock() can't used in
> >> tasklet(atomic context). The driver need use mutex to avoid concurrency,
> >> so we can't use tasklet here, the patch need to be removed.
> >>
> >> The spinlock host->lock and pcr->lock may deadlock, one way to solve the
> >> deadlock is remove host->lock in sd_isr_done_transfer(), but if using
> >> workqueue the we can avoid using the spinlock and also avoid the problem.
> >>
> >> Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
> >
> > Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
> 
> Hi Lee,
> 
> Would you mind to pick this up and send it for 3.15 fixes?
> 
> The other revert "[PATCH 1/2] mmc: rtsx: Revert "mmc: rtsx: modify
> error handle and remove smatch warnings", needs to go through the mmc
> tree.

Sent.
diff mbox

Patch

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index c9de3d5..1d15735 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -338,28 +338,58 @@  int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
 		int num_sg, bool read, int timeout)
 {
 	struct completion trans_done;
-	int err = 0, count;
+	u8 dir;
+	int err = 0, i, count;
 	long timeleft;
 	unsigned long flags;
+	struct scatterlist *sg;
+	enum dma_data_direction dma_dir;
+	u32 val;
+	dma_addr_t addr;
+	unsigned int len;
+
+	dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+
+	/* don't transfer data during abort processing */
+	if (pcr->remove_pci)
+		return -EINVAL;
+
+	if ((sglist == NULL) || (num_sg <= 0))
+		return -EINVAL;
 
-	count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
+	if (read) {
+		dir = DEVICE_TO_HOST;
+		dma_dir = DMA_FROM_DEVICE;
+	} else {
+		dir = HOST_TO_DEVICE;
+		dma_dir = DMA_TO_DEVICE;
+	}
+
+	count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
 	if (count < 1) {
 		dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
 		return -EINVAL;
 	}
 	dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
 
+	val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
+	pcr->sgi = 0;
+	for_each_sg(sglist, sg, count, i) {
+		addr = sg_dma_address(sg);
+		len = sg_dma_len(sg);
+		rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
+	}
 
 	spin_lock_irqsave(&pcr->lock, flags);
 
 	pcr->done = &trans_done;
 	pcr->trans_result = TRANS_NOT_READY;
 	init_completion(&trans_done);
+	rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
+	rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
 
 	spin_unlock_irqrestore(&pcr->lock, flags);
 
-	rtsx_pci_dma_transfer(pcr, sglist, count, read);
-
 	timeleft = wait_for_completion_interruptible_timeout(
 			&trans_done, msecs_to_jiffies(timeout));
 	if (timeleft <= 0) {
@@ -383,7 +413,7 @@  out:
 	pcr->done = NULL;
 	spin_unlock_irqrestore(&pcr->lock, flags);
 
-	rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
+	dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
 
 	if ((err < 0) && (err != -ENODEV))
 		rtsx_pci_stop_cmd(pcr);
@@ -395,73 +425,6 @@  out:
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
 
-int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int num_sg, bool read)
-{
-	enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-	if (pcr->remove_pci)
-		return -EINVAL;
-
-	if ((sglist == NULL) || num_sg < 1)
-		return -EINVAL;
-
-	return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
-
-int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int num_sg, bool read)
-{
-	enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-	if (pcr->remove_pci)
-		return -EINVAL;
-
-	if (sglist == NULL || num_sg < 1)
-		return -EINVAL;
-
-	dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
-	return num_sg;
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
-
-int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int sg_count, bool read)
-{
-	struct scatterlist *sg;
-	dma_addr_t addr;
-	unsigned int len;
-	int i;
-	u32 val;
-	u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
-	unsigned long flags;
-
-	if (pcr->remove_pci)
-		return -EINVAL;
-
-	if ((sglist == NULL) || (sg_count < 1))
-		return -EINVAL;
-
-	val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
-	pcr->sgi = 0;
-	for_each_sg(sglist, sg, sg_count, i) {
-		addr = sg_dma_address(sg);
-		len = sg_dma_len(sg);
-		rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1);
-	}
-
-	spin_lock_irqsave(&pcr->lock, flags);
-
-	rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
-	rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
-
-	spin_unlock_irqrestore(&pcr->lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer);
-
 int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
 {
 	int err;
@@ -873,8 +836,6 @@  static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
 	int_reg = rtsx_pci_readl(pcr, RTSX_BIPR);
 	/* Clear interrupt flag */
 	rtsx_pci_writel(pcr, RTSX_BIPR, int_reg);
-	dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg);
-
 	if ((int_reg & pcr->bier) == 0) {
 		spin_unlock(&pcr->lock);
 		return IRQ_NONE;
@@ -905,28 +866,17 @@  static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
 	}
 
 	if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
-		if (int_reg & (TRANS_FAIL_INT | DELINK_INT))
+		if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
 			pcr->trans_result = TRANS_RESULT_FAIL;
-		else if (int_reg & TRANS_OK_INT)
+			if (pcr->done)
+				complete(pcr->done);
+		} else if (int_reg & TRANS_OK_INT) {
 			pcr->trans_result = TRANS_RESULT_OK;
-
-		if (pcr->done)
-			complete(pcr->done);
-
-		if (int_reg & SD_EXIST) {
-			struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
-			if (slot && slot->done_transfer)
-				slot->done_transfer(slot->p_dev);
-		}
-
-		if (int_reg & MS_EXIST) {
-			struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
-			if (slot && slot->done_transfer)
-				slot->done_transfer(slot->p_dev);
+			if (pcr->done)
+				complete(pcr->done);
 		}
 	}
 
-
 	if (pcr->card_inserted || pcr->card_removed)
 		schedule_delayed_work(&pcr->carddet_work,
 				msecs_to_jiffies(200));
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 76cfdcc..0d51964 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -31,28 +31,14 @@ 
 #include <linux/mfd/rtsx_pci.h>
 #include <asm/unaligned.h>
 
-struct realtek_next {
-	unsigned int	sg_count;
-	s32		cookie;
-};
-
 struct realtek_pci_sdmmc {
 	struct platform_device	*pdev;
 	struct rtsx_pcr		*pcr;
 	struct mmc_host		*mmc;
 	struct mmc_request	*mrq;
-	struct mmc_command	*cmd;
-	struct mmc_data		*data;
-
-	spinlock_t		lock;
-	struct timer_list	timer;
-	struct tasklet_struct	cmd_tasklet;
-	struct tasklet_struct	data_tasklet;
-	struct tasklet_struct	finish_tasklet;
-
-	u8			rsp_type;
-	u8			rsp_len;
-	int			sg_count;
+
+	struct mutex		host_mutex;
+
 	u8			ssc_depth;
 	unsigned int		clock;
 	bool			vpclk;
@@ -62,13 +48,8 @@  struct realtek_pci_sdmmc {
 	int			power_state;
 #define SDMMC_POWER_ON		1
 #define SDMMC_POWER_OFF		0
-
-	struct realtek_next	next_data;
 };
 
-static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
-		struct mmc_request *mrq);
-
 static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
 {
 	return &(host->pdev->dev);
@@ -105,95 +86,6 @@  static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
-static void sd_isr_done_transfer(struct platform_device *pdev)
-{
-	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
-
-	spin_lock(&host->lock);
-	if (host->cmd)
-		tasklet_schedule(&host->cmd_tasklet);
-	if (host->data)
-		tasklet_schedule(&host->data_tasklet);
-	spin_unlock(&host->lock);
-}
-
-static void sd_request_timeout(unsigned long host_addr)
-{
-	struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	if (!host->mrq) {
-		dev_err(sdmmc_dev(host), "error: no request exist\n");
-		goto out;
-	}
-
-	if (host->cmd)
-		host->cmd->error = -ETIMEDOUT;
-	if (host->data)
-		host->data->error = -ETIMEDOUT;
-
-	dev_dbg(sdmmc_dev(host), "timeout for request\n");
-
-out:
-	tasklet_schedule(&host->finish_tasklet);
-	spin_unlock_irqrestore(&host->lock, flags);
-}
-
-static void sd_finish_request(unsigned long host_addr)
-{
-	struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
-	struct rtsx_pcr *pcr = host->pcr;
-	struct mmc_request *mrq;
-	struct mmc_command *cmd;
-	struct mmc_data *data;
-	unsigned long flags;
-	bool any_error;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	del_timer(&host->timer);
-	mrq = host->mrq;
-	if (!mrq) {
-		dev_err(sdmmc_dev(host), "error: no request need finish\n");
-		goto out;
-	}
-
-	cmd = mrq->cmd;
-	data = mrq->data;
-
-	any_error = (mrq->sbc && mrq->sbc->error) ||
-		(mrq->stop && mrq->stop->error) ||
-		(cmd && cmd->error) || (data && data->error);
-
-	if (any_error) {
-		rtsx_pci_stop_cmd(pcr);
-		sd_clear_error(host);
-	}
-
-	if (data) {
-		if (any_error)
-			data->bytes_xfered = 0;
-		else
-			data->bytes_xfered = data->blocks * data->blksz;
-
-		if (!data->host_cookie)
-			rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len,
-					data->flags & MMC_DATA_READ);
-
-	}
-
-	host->mrq = NULL;
-	host->cmd = NULL;
-	host->data = NULL;
-
-out:
-	spin_unlock_irqrestore(&host->lock, flags);
-	mutex_unlock(&pcr->pcr_mutex);
-	mmc_request_done(host->mmc, mrq);
-}
-
 static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
 		u8 *buf, int buf_len, int timeout)
 {
@@ -311,7 +203,8 @@  static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
 	return 0;
 }
 
-static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
+static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
+		struct mmc_command *cmd)
 {
 	struct rtsx_pcr *pcr = host->pcr;
 	u8 cmd_idx = (u8)cmd->opcode;
@@ -319,14 +212,11 @@  static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
 	int err = 0;
 	int timeout = 100;
 	int i;
+	u8 *ptr;
+	int stat_idx = 0;
 	u8 rsp_type;
 	int rsp_len = 5;
-	unsigned long flags;
-
-	if (host->cmd)
-		dev_err(sdmmc_dev(host), "error: cmd already exist\n");
-
-	host->cmd = cmd;
+	bool clock_toggled = false;
 
 	dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
 			__func__, cmd_idx, arg);
@@ -364,8 +254,6 @@  static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
 		err = -EINVAL;
 		goto out;
 	}
-	host->rsp_type = rsp_type;
-	host->rsp_len = rsp_len;
 
 	if (rsp_type == SD_RSP_TYPE_R1b)
 		timeout = 3000;
@@ -375,6 +263,8 @@  static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
 				0xFF, SD_CLK_TOGGLE_EN);
 		if (err < 0)
 			goto out;
+
+		clock_toggled = true;
 	}
 
 	rtsx_pci_init_cmd(pcr);
@@ -398,60 +288,25 @@  static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd)
 		/* Read data from ping-pong buffer */
 		for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
 			rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+		stat_idx = 16;
 	} else if (rsp_type != SD_RSP_TYPE_R0) {
 		/* Read data from SD_CMDx registers */
 		for (i = SD_CMD0; i <= SD_CMD4; i++)
 			rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
+		stat_idx = 5;
 	}
 
 	rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0);
 
-	mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout));
-
-	spin_lock_irqsave(&pcr->lock, flags);
-	pcr->trans_result = TRANS_NOT_READY;
-	rtsx_pci_send_cmd_no_wait(pcr);
-	spin_unlock_irqrestore(&pcr->lock, flags);
-
-	return;
-
-out:
-	cmd->error = err;
-	tasklet_schedule(&host->finish_tasklet);
-}
-
-static void sd_get_rsp(unsigned long host_addr)
-{
-	struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
-	struct rtsx_pcr *pcr = host->pcr;
-	struct mmc_command *cmd;
-	int i, err = 0, stat_idx;
-	u8 *ptr, rsp_type;
-	unsigned long flags;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	cmd = host->cmd;
-	host->cmd = NULL;
-
-	if (!cmd) {
-		dev_err(sdmmc_dev(host), "error: cmd not exist\n");
+	err = rtsx_pci_send_cmd(pcr, timeout);
+	if (err < 0) {
+		sd_print_debug_regs(host);
+		sd_clear_error(host);
+		dev_dbg(sdmmc_dev(host),
+			"rtsx_pci_send_cmd error (err = %d)\n", err);
 		goto out;
 	}
 
-	spin_lock(&pcr->lock);
-	if (pcr->trans_result == TRANS_NO_DEVICE)
-		err = -ENODEV;
-	else if (pcr->trans_result != TRANS_RESULT_OK)
-		err = -EINVAL;
-	spin_unlock(&pcr->lock);
-
-	if (err < 0)
-		goto out;
-
-	rsp_type = host->rsp_type;
-	stat_idx = host->rsp_len;
-
 	if (rsp_type == SD_RSP_TYPE_R0) {
 		err = 0;
 		goto out;
@@ -488,106 +343,26 @@  static void sd_get_rsp(unsigned long host_addr)
 				cmd->resp[0]);
 	}
 
-	if (cmd == host->mrq->sbc) {
-		sd_send_cmd(host, host->mrq->cmd);
-		spin_unlock_irqrestore(&host->lock, flags);
-		return;
-	}
-
-	if (cmd == host->mrq->stop)
-		goto out;
-
-	if (cmd->data) {
-		sd_start_multi_rw(host, host->mrq);
-		spin_unlock_irqrestore(&host->lock, flags);
-		return;
-	}
-
 out:
 	cmd->error = err;
 
-	tasklet_schedule(&host->finish_tasklet);
-	spin_unlock_irqrestore(&host->lock, flags);
-}
-
-static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host,
-			struct mmc_data *data, struct realtek_next *next)
-{
-	struct rtsx_pcr *pcr = host->pcr;
-	int read = data->flags & MMC_DATA_READ;
-	int sg_count = 0;
-
-	if (!next && data->host_cookie &&
-		data->host_cookie != host->next_data.cookie) {
-		dev_err(sdmmc_dev(host),
-			"error: invalid cookie data[%d] host[%d]\n",
-			data->host_cookie, host->next_data.cookie);
-		data->host_cookie = 0;
-	}
-
-	if (next || (!next && data->host_cookie != host->next_data.cookie))
-		sg_count = rtsx_pci_dma_map_sg(pcr,
-				data->sg, data->sg_len, read);
-	else
-		sg_count = host->next_data.sg_count;
-
-	if (next) {
-		next->sg_count = sg_count;
-		if (++next->cookie < 0)
-			next->cookie = 1;
-		data->host_cookie = next->cookie;
-	}
-
-	return sg_count;
-}
-
-static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
-		bool is_first_req)
-{
-	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
-	struct mmc_data *data = mrq->data;
-
-	if (data->host_cookie) {
-		dev_err(sdmmc_dev(host),
-			"error: descard already cookie data[%d]\n",
-			data->host_cookie);
-		data->host_cookie = 0;
-	}
-
-	dev_dbg(sdmmc_dev(host), "dma sg prepared: %d\n",
-		sd_pre_dma_transfer(host, data, &host->next_data));
-}
-
-static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
-		int err)
-{
-	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
-	struct rtsx_pcr *pcr = host->pcr;
-	struct mmc_data *data = mrq->data;
-	int read = data->flags & MMC_DATA_READ;
-
-	rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read);
-	data->host_cookie = 0;
+	if (err && clock_toggled)
+		rtsx_pci_write_register(pcr, SD_BUS_STAT,
+				SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 }
 
-static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
-		struct mmc_request *mrq)
+static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
 {
 	struct rtsx_pcr *pcr = host->pcr;
 	struct mmc_host *mmc = host->mmc;
 	struct mmc_card *card = mmc->card;
 	struct mmc_data *data = mrq->data;
 	int uhs = mmc_card_uhs(card);
-	int read = data->flags & MMC_DATA_READ;
+	int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
 	u8 cfg2, trans_mode;
 	int err;
 	size_t data_len = data->blksz * data->blocks;
 
-	if (host->data)
-		dev_err(sdmmc_dev(host), "error: data already exist\n");
-
-	host->data = data;
-
 	if (read) {
 		cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
 			SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0;
@@ -638,54 +413,15 @@  static int sd_start_multi_rw(struct realtek_pci_sdmmc *host,
 	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
 			SD_TRANSFER_END, SD_TRANSFER_END);
 
-	mod_timer(&host->timer, jiffies + 10 * HZ);
 	rtsx_pci_send_cmd_no_wait(pcr);
 
-	err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read);
-	if (err < 0) {
-		data->error = err;
-		tasklet_schedule(&host->finish_tasklet);
-	}
-	return 0;
-}
-
-static void sd_finish_multi_rw(unsigned long host_addr)
-{
-	struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr;
-	struct rtsx_pcr *pcr = host->pcr;
-	struct mmc_data *data;
-	int err = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	if (!host->data) {
-		dev_err(sdmmc_dev(host), "error: no data exist\n");
-		goto out;
-	}
-
-	data = host->data;
-	host->data = NULL;
-
-	if (pcr->trans_result == TRANS_NO_DEVICE)
-		err = -ENODEV;
-	else if (pcr->trans_result != TRANS_RESULT_OK)
-		err = -EINVAL;
-
+	err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000);
 	if (err < 0) {
-		data->error = err;
-		goto out;
-	}
-
-	if (!host->mrq->sbc && data->stop) {
-		sd_send_cmd(host, data->stop);
-		spin_unlock_irqrestore(&host->lock, flags);
-		return;
+		sd_clear_error(host);
+		return err;
 	}
 
-out:
-	tasklet_schedule(&host->finish_tasklet);
-	spin_unlock_irqrestore(&host->lock, flags);
+	return 0;
 }
 
 static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host)
@@ -904,13 +640,6 @@  static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
 	return 0;
 }
 
-static inline bool sd_use_muti_rw(struct mmc_command *cmd)
-{
-	return mmc_op_multi(cmd->opcode) ||
-		(cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
-		(cmd->opcode == MMC_WRITE_BLOCK);
-}
-
 static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
@@ -919,14 +648,6 @@  static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	struct mmc_data *data = mrq->data;
 	unsigned int data_size = 0;
 	int err;
-	unsigned long flags;
-
-	mutex_lock(&pcr->pcr_mutex);
-	spin_lock_irqsave(&host->lock, flags);
-
-	if (host->mrq)
-		dev_err(sdmmc_dev(host), "error: request already exist\n");
-	host->mrq = mrq;
 
 	if (host->eject) {
 		cmd->error = -ENOMEDIUM;
@@ -939,6 +660,8 @@  static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		goto finish;
 	}
 
+	mutex_lock(&pcr->pcr_mutex);
+
 	rtsx_pci_start_run(pcr);
 
 	rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
@@ -947,28 +670,46 @@  static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
 			CARD_SHARE_MASK, CARD_SHARE_48_SD);
 
+	mutex_lock(&host->host_mutex);
+	host->mrq = mrq;
+	mutex_unlock(&host->host_mutex);
+
 	if (mrq->data)
 		data_size = data->blocks * data->blksz;
 
-	if (sd_use_muti_rw(cmd))
-		host->sg_count = sd_pre_dma_transfer(host, data, NULL);
+	if (!data_size || mmc_op_multi(cmd->opcode) ||
+			(cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
+			(cmd->opcode == MMC_WRITE_BLOCK)) {
+		sd_send_cmd_get_rsp(host, cmd);
 
-	if (!data_size || sd_use_muti_rw(cmd)) {
-		if (mrq->sbc)
-			sd_send_cmd(host, mrq->sbc);
-		else
-			sd_send_cmd(host, cmd);
-		spin_unlock_irqrestore(&host->lock, flags);
+		if (!cmd->error && data_size) {
+			sd_rw_multi(host, mrq);
+
+			if (mmc_op_multi(cmd->opcode) && mrq->stop)
+				sd_send_cmd_get_rsp(host, mrq->stop);
+		}
 	} else {
-		spin_unlock_irqrestore(&host->lock, flags);
 		sd_normal_rw(host, mrq);
-		tasklet_schedule(&host->finish_tasklet);
 	}
-	return;
+
+	if (mrq->data) {
+		if (cmd->error || data->error)
+			data->bytes_xfered = 0;
+		else
+			data->bytes_xfered = data->blocks * data->blksz;
+	}
+
+	mutex_unlock(&pcr->pcr_mutex);
 
 finish:
-	tasklet_schedule(&host->finish_tasklet);
-	spin_unlock_irqrestore(&host->lock, flags);
+	if (cmd->error)
+		dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
+
+	mutex_lock(&host->host_mutex);
+	host->mrq = NULL;
+	mutex_unlock(&host->host_mutex);
+
+	mmc_request_done(mmc, mrq);
 }
 
 static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
@@ -1405,8 +1146,6 @@  out:
 }
 
 static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
-	.pre_req = sdmmc_pre_req,
-	.post_req = sdmmc_post_req,
 	.request = sdmmc_request,
 	.set_ios = sdmmc_set_ios,
 	.get_ro = sdmmc_get_ro,
@@ -1470,7 +1209,6 @@  static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
 	struct realtek_pci_sdmmc *host;
 	struct rtsx_pcr *pcr;
 	struct pcr_handle *handle = pdev->dev.platform_data;
-	unsigned long host_addr;
 
 	if (!handle)
 		return -ENXIO;
@@ -1494,15 +1232,8 @@  static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
 	pcr->slots[RTSX_SD_CARD].p_dev = pdev;
 	pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
 
-	host_addr = (unsigned long)host;
-	host->next_data.cookie = 1;
-	setup_timer(&host->timer, sd_request_timeout, host_addr);
-	tasklet_init(&host->cmd_tasklet, sd_get_rsp, host_addr);
-	tasklet_init(&host->data_tasklet, sd_finish_multi_rw, host_addr);
-	tasklet_init(&host->finish_tasklet, sd_finish_request, host_addr);
-	spin_lock_init(&host->lock);
+	mutex_init(&host->host_mutex);
 
-	pcr->slots[RTSX_SD_CARD].done_transfer = sd_isr_done_transfer;
 	realtek_init_host(host);
 
 	mmc_add_host(mmc);
@@ -1515,8 +1246,6 @@  static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
 	struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
 	struct rtsx_pcr *pcr;
 	struct mmc_host *mmc;
-	struct mmc_request *mrq;
-	unsigned long flags;
 
 	if (!host)
 		return 0;
@@ -1524,33 +1253,22 @@  static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
 	pcr = host->pcr;
 	pcr->slots[RTSX_SD_CARD].p_dev = NULL;
 	pcr->slots[RTSX_SD_CARD].card_event = NULL;
-	pcr->slots[RTSX_SD_CARD].done_transfer = NULL;
 	mmc = host->mmc;
-	mrq = host->mrq;
 
-	spin_lock_irqsave(&host->lock, flags);
+	mutex_lock(&host->host_mutex);
 	if (host->mrq) {
 		dev_dbg(&(pdev->dev),
 			"%s: Controller removed during transfer\n",
 			mmc_hostname(mmc));
 
-		if (mrq->sbc)
-			mrq->sbc->error = -ENOMEDIUM;
-		if (mrq->cmd)
-			mrq->cmd->error = -ENOMEDIUM;
-		if (mrq->stop)
-			mrq->stop->error = -ENOMEDIUM;
-		if (mrq->data)
-			mrq->data->error = -ENOMEDIUM;
+		rtsx_pci_complete_unfinished_transfer(pcr);
 
-		tasklet_schedule(&host->finish_tasklet);
+		host->mrq->cmd->error = -ENOMEDIUM;
+		if (host->mrq->stop)
+			host->mrq->stop->error = -ENOMEDIUM;
+		mmc_request_done(mmc, host->mrq);
 	}
-	spin_unlock_irqrestore(&host->lock, flags);
-
-	del_timer_sync(&host->timer);
-	tasklet_kill(&host->cmd_tasklet);
-	tasklet_kill(&host->data_tasklet);
-	tasklet_kill(&host->finish_tasklet);
+	mutex_unlock(&host->host_mutex);
 
 	mmc_remove_host(mmc);
 	host->eject = true;
diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h
index 7c36cc5..443176e 100644
--- a/include/linux/mfd/rtsx_common.h
+++ b/include/linux/mfd/rtsx_common.h
@@ -45,7 +45,6 @@  struct platform_device;
 struct rtsx_slot {
 	struct platform_device	*p_dev;
 	void			(*card_event)(struct platform_device *p_dev);
-	void			(*done_transfer)(struct platform_device *p_dev);
 };
 
 #endif
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 8d6bbd6..a383597 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -943,12 +943,6 @@  void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr);
 int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout);
 int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
 		int num_sg, bool read, int timeout);
-int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int num_sg, bool read);
-int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int num_sg, bool read);
-int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-		int sg_count, bool read);
 int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
 int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
 int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card);