diff options
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
| -rw-r--r-- | drivers/mfd/rtsx_pcr.c | 76 | 
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 1d15735f9ef9..d01b8c249231 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -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)  {  |