mfd: rtsx: Add dma transfer function
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>
This commit is contained in:
parent
cd3de83f14
commit
8cd118308a
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue