diff options
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 132 |
1 files changed, 41 insertions, 91 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index c9de3d598ea5..1d15735f9ef9 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, | |||
338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
339 | { | 339 | { |
340 | struct completion trans_done; | 340 | struct completion trans_done; |
341 | int err = 0, count; | 341 | u8 dir; |
342 | int err = 0, i, count; | ||
342 | long timeleft; | 343 | long timeleft; |
343 | unsigned long flags; | 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 | |||
351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | ||
352 | |||
353 | /* don't transfer data during abort processing */ | ||
354 | if (pcr->remove_pci) | ||
355 | return -EINVAL; | ||
356 | |||
357 | if ((sglist == NULL) || (num_sg <= 0)) | ||
358 | return -EINVAL; | ||
344 | 359 | ||
345 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); | 360 | if (read) { |
361 | dir = DEVICE_TO_HOST; | ||
362 | dma_dir = DMA_FROM_DEVICE; | ||
363 | } else { | ||
364 | dir = HOST_TO_DEVICE; | ||
365 | dma_dir = DMA_TO_DEVICE; | ||
366 | } | ||
367 | |||
368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
346 | if (count < 1) { | 369 | if (count < 1) { |
347 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); |
348 | return -EINVAL; | 371 | return -EINVAL; |
349 | } | 372 | } |
350 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | 373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); |
351 | 374 | ||
375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
376 | pcr->sgi = 0; | ||
377 | for_each_sg(sglist, sg, count, i) { | ||
378 | addr = sg_dma_address(sg); | ||
379 | len = sg_dma_len(sg); | ||
380 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); | ||
381 | } | ||
352 | 382 | ||
353 | spin_lock_irqsave(&pcr->lock, flags); | 383 | spin_lock_irqsave(&pcr->lock, flags); |
354 | 384 | ||
355 | pcr->done = &trans_done; | 385 | pcr->done = &trans_done; |
356 | pcr->trans_result = TRANS_NOT_READY; | 386 | pcr->trans_result = TRANS_NOT_READY; |
357 | init_completion(&trans_done); | 387 | init_completion(&trans_done); |
388 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
389 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
358 | 390 | ||
359 | spin_unlock_irqrestore(&pcr->lock, flags); | 391 | spin_unlock_irqrestore(&pcr->lock, flags); |
360 | 392 | ||
361 | rtsx_pci_dma_transfer(pcr, sglist, count, read); | ||
362 | |||
363 | timeleft = wait_for_completion_interruptible_timeout( | 393 | timeleft = wait_for_completion_interruptible_timeout( |
364 | &trans_done, msecs_to_jiffies(timeout)); | 394 | &trans_done, msecs_to_jiffies(timeout)); |
365 | if (timeleft <= 0) { | 395 | if (timeleft <= 0) { |
@@ -383,7 +413,7 @@ out: | |||
383 | pcr->done = NULL; | 413 | pcr->done = NULL; |
384 | spin_unlock_irqrestore(&pcr->lock, flags); | 414 | spin_unlock_irqrestore(&pcr->lock, flags); |
385 | 415 | ||
386 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); | 416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); |
387 | 417 | ||
388 | if ((err < 0) && (err != -ENODEV)) | 418 | if ((err < 0) && (err != -ENODEV)) |
389 | rtsx_pci_stop_cmd(pcr); | 419 | rtsx_pci_stop_cmd(pcr); |
@@ -395,73 +425,6 @@ out: | |||
395 | } | 425 | } |
396 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); |
397 | 427 | ||
398 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
399 | int num_sg, bool read) | ||
400 | { | ||
401 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
402 | |||
403 | if (pcr->remove_pci) | ||
404 | return -EINVAL; | ||
405 | |||
406 | if ((sglist == NULL) || num_sg < 1) | ||
407 | return -EINVAL; | ||
408 | |||
409 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
410 | } | ||
411 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); | ||
412 | |||
413 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
414 | int num_sg, bool read) | ||
415 | { | ||
416 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
417 | |||
418 | if (pcr->remove_pci) | ||
419 | return -EINVAL; | ||
420 | |||
421 | if (sglist == NULL || num_sg < 1) | ||
422 | return -EINVAL; | ||
423 | |||
424 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
425 | return num_sg; | ||
426 | } | ||
427 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
428 | |||
429 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
430 | int sg_count, bool read) | ||
431 | { | ||
432 | struct scatterlist *sg; | ||
433 | dma_addr_t addr; | ||
434 | unsigned int len; | ||
435 | int i; | ||
436 | u32 val; | ||
437 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
438 | unsigned long flags; | ||
439 | |||
440 | if (pcr->remove_pci) | ||
441 | return -EINVAL; | ||
442 | |||
443 | if ((sglist == NULL) || (sg_count < 1)) | ||
444 | return -EINVAL; | ||
445 | |||
446 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
447 | pcr->sgi = 0; | ||
448 | for_each_sg(sglist, sg, sg_count, i) { | ||
449 | addr = sg_dma_address(sg); | ||
450 | len = sg_dma_len(sg); | ||
451 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1); | ||
452 | } | ||
453 | |||
454 | spin_lock_irqsave(&pcr->lock, flags); | ||
455 | |||
456 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
457 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
458 | |||
459 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); | ||
464 | |||
465 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
466 | { | 429 | { |
467 | int err; | 430 | int err; |
@@ -873,8 +836,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
873 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); | 836 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); |
874 | /* Clear interrupt flag */ | 837 | /* Clear interrupt flag */ |
875 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); | 838 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); |
876 | dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg); | ||
877 | |||
878 | if ((int_reg & pcr->bier) == 0) { | 839 | if ((int_reg & pcr->bier) == 0) { |
879 | spin_unlock(&pcr->lock); | 840 | spin_unlock(&pcr->lock); |
880 | return IRQ_NONE; | 841 | return IRQ_NONE; |
@@ -905,28 +866,17 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
905 | } | 866 | } |
906 | 867 | ||
907 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 868 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
908 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) | 869 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { |
909 | pcr->trans_result = TRANS_RESULT_FAIL; | 870 | pcr->trans_result = TRANS_RESULT_FAIL; |
910 | else if (int_reg & TRANS_OK_INT) | 871 | if (pcr->done) |
872 | complete(pcr->done); | ||
873 | } else if (int_reg & TRANS_OK_INT) { | ||
911 | pcr->trans_result = TRANS_RESULT_OK; | 874 | pcr->trans_result = TRANS_RESULT_OK; |
912 | 875 | if (pcr->done) | |
913 | if (pcr->done) | 876 | complete(pcr->done); |
914 | complete(pcr->done); | ||
915 | |||
916 | if (int_reg & SD_EXIST) { | ||
917 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
918 | if (slot && slot->done_transfer) | ||
919 | slot->done_transfer(slot->p_dev); | ||
920 | } | ||
921 | |||
922 | if (int_reg & MS_EXIST) { | ||
923 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
924 | if (slot && slot->done_transfer) | ||
925 | slot->done_transfer(slot->p_dev); | ||
926 | } | 877 | } |
927 | } | 878 | } |
928 | 879 | ||
929 | |||
930 | if (pcr->card_inserted || pcr->card_removed) | 880 | if (pcr->card_inserted || pcr->card_removed) |
931 | schedule_delayed_work(&pcr->carddet_work, | 881 | schedule_delayed_work(&pcr->carddet_work, |
932 | msecs_to_jiffies(200)); | 882 | msecs_to_jiffies(200)); |