aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicky Ching <micky_ching@realsil.com.cn>2014-06-06 03:05:44 -0400
committerLee Jones <lee.jones@linaro.org>2014-07-09 09:14:58 -0400
commit8cd118308a8649c649533a0133af0ce731d223bb (patch)
treed133d73fcded3bac7b0b73f63617dc79b4591353
parentcd3de83f147601356395b57a8673e9c5ff1e59d1 (diff)
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>
-rw-r--r--drivers/mfd/rtsx_pcr.c76
-rw-r--r--include/linux/mfd/rtsx_pci.h6
2 files changed, 54 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,
337int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, 337int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
338 int num_sg, bool read, int timeout) 338 int num_sg, bool read, int timeout)
339{ 339{
340 struct completion trans_done; 340 int err = 0, count;
341 u8 dir;
342 int err = 0, i, count;
343 long timeleft;
344 unsigned long flags;
345 struct scatterlist *sg;
346 enum dma_data_direction dma_dir;
347 u32 val;
348 dma_addr_t addr;
349 unsigned int len;
350 341
351 dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); 342 dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
343 count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
344 if (count < 1)
345 return -EINVAL;
346 dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
347
348 err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout);
349
350 rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
351
352 return err;
353}
354EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
355
356int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
357 int num_sg, bool read)
358{
359 enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
352 360
353 /* don't transfer data during abort processing */
354 if (pcr->remove_pci) 361 if (pcr->remove_pci)
355 return -EINVAL; 362 return -EINVAL;
356 363
357 if ((sglist == NULL) || (num_sg <= 0)) 364 if ((sglist == NULL) || (num_sg <= 0))
358 return -EINVAL; 365 return -EINVAL;
359 366
360 if (read) { 367 return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
361 dir = DEVICE_TO_HOST; 368}
362 dma_dir = DMA_FROM_DEVICE; 369EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
363 } else {
364 dir = HOST_TO_DEVICE;
365 dma_dir = DMA_TO_DEVICE;
366 }
367 370
368 count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); 371void rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
369 if (count < 1) { 372 int num_sg, bool read)
370 dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); 373{
374 enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
375
376 dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
377}
378EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
379
380int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
381 int count, bool read, int timeout)
382{
383 struct completion trans_done;
384 struct scatterlist *sg;
385 dma_addr_t addr;
386 long timeleft;
387 unsigned long flags;
388 unsigned int len;
389 int i, err = 0;
390 u32 val;
391 u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
392
393 if (pcr->remove_pci)
394 return -ENODEV;
395
396 if ((sglist == NULL) || (count < 1))
371 return -EINVAL; 397 return -EINVAL;
372 }
373 dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
374 398
375 val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; 399 val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
376 pcr->sgi = 0; 400 pcr->sgi = 0;
@@ -400,12 +424,10 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
400 } 424 }
401 425
402 spin_lock_irqsave(&pcr->lock, flags); 426 spin_lock_irqsave(&pcr->lock, flags);
403
404 if (pcr->trans_result == TRANS_RESULT_FAIL) 427 if (pcr->trans_result == TRANS_RESULT_FAIL)
405 err = -EINVAL; 428 err = -EINVAL;
406 else if (pcr->trans_result == TRANS_NO_DEVICE) 429 else if (pcr->trans_result == TRANS_NO_DEVICE)
407 err = -ENODEV; 430 err = -ENODEV;
408
409 spin_unlock_irqrestore(&pcr->lock, flags); 431 spin_unlock_irqrestore(&pcr->lock, flags);
410 432
411out: 433out:
@@ -413,8 +435,6 @@ out:
413 pcr->done = NULL; 435 pcr->done = NULL;
414 spin_unlock_irqrestore(&pcr->lock, flags); 436 spin_unlock_irqrestore(&pcr->lock, flags);
415 437
416 dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
417
418 if ((err < 0) && (err != -ENODEV)) 438 if ((err < 0) && (err != -ENODEV))
419 rtsx_pci_stop_cmd(pcr); 439 rtsx_pci_stop_cmd(pcr);
420 440
@@ -423,7 +443,7 @@ out:
423 443
424 return err; 444 return err;
425} 445}
426EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); 446EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer);
427 447
428int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) 448int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
429{ 449{
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index a3835976f7c6..74346d5e7899 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -943,6 +943,12 @@ void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr);
943int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); 943int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout);
944int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, 944int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
945 int num_sg, bool read, int timeout); 945 int num_sg, bool read, int timeout);
946int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
947 int num_sg, bool read);
948void rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
949 int num_sg, bool read);
950int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
951 int count, bool read, int timeout);
946int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); 952int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
947int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); 953int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len);
948int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); 954int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card);