mfd: rtsx: Add dma transfer function
authorMicky Ching <micky_ching@realsil.com.cn>
Fri, 6 Jun 2014 07:05:44 +0000 (15:05 +0800)
committerLee Jones <lee.jones@linaro.org>
Wed, 9 Jul 2014 13:14:58 +0000 (14:14 +0100)
rtsx driver using a single function for transfer data, dma map/unmap are
placed in one fix function. We need map/unmap dma in different place(for
mmc async driver), so add three function for dma map, dma transfer and
dma unmap.

Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
drivers/mfd/rtsx_pcr.c
include/linux/mfd/rtsx_pci.h

index 1d15735f9ef930ed18e384b1c63b7deb1fd42981..d01b8c24923104287ed84927038cb51576a4f7d6 100644 (file)
@@ -337,40 +337,64 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
 int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
                int num_sg, bool read, int timeout)
 {
-       struct completion trans_done;
-       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;
+       int err = 0, count;
 
        dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+       count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
+       if (count < 1)
+               return -EINVAL;
+       dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
+
+       err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout);
+
+       rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
+
+       return err;
+}
+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;
 
-       /* don't transfer data during abort processing */
        if (pcr->remove_pci)
                return -EINVAL;
 
        if ((sglist == NULL) || (num_sg <= 0))
                return -EINVAL;
 
-       if (read) {
-               dir = DEVICE_TO_HOST;
-               dma_dir = DMA_FROM_DEVICE;
-       } else {
-               dir = HOST_TO_DEVICE;
-               dma_dir = DMA_TO_DEVICE;
-       }
+       return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
 
-       count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
-       if (count < 1) {
-               dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
+void 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;
+
+       dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
+
+int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+               int count, bool read, int timeout)
+{
+       struct completion trans_done;
+       struct scatterlist *sg;
+       dma_addr_t addr;
+       long timeleft;
+       unsigned long flags;
+       unsigned int len;
+       int i, err = 0;
+       u32 val;
+       u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
+
+       if (pcr->remove_pci)
+               return -ENODEV;
+
+       if ((sglist == NULL) || (count < 1))
                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;
@@ -400,12 +424,10 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
        }
 
        spin_lock_irqsave(&pcr->lock, flags);
-
        if (pcr->trans_result == TRANS_RESULT_FAIL)
                err = -EINVAL;
        else if (pcr->trans_result == TRANS_NO_DEVICE)
                err = -ENODEV;
-
        spin_unlock_irqrestore(&pcr->lock, flags);
 
 out:
@@ -413,8 +435,6 @@ out:
        pcr->done = NULL;
        spin_unlock_irqrestore(&pcr->lock, flags);
 
-       dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
-
        if ((err < 0) && (err != -ENODEV))
                rtsx_pci_stop_cmd(pcr);
 
@@ -423,7 +443,7 @@ out:
 
        return err;
 }
-EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer);
 
 int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
 {
index a3835976f7c639e8f24e17cf2df6dc495f07fae4..74346d5e789900b360b262f2bc92757996d87825 100644 (file)
@@ -943,6 +943,12 @@ 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);
+void 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 count, bool read, int timeout);
 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);