Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: rtsx: Do retry when DMA transfer error

The request should be resent when DMA transfer error occurred.
For rts5227, the clock rate needs to be reduced when error occurred.

Signed-off-by: Steven Feng <steven_feng@realsil.com.cn>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Steven Feng and committed by
Lee Jones
87d28444 9b79ff10

+20 -2
+15 -2
drivers/mfd/rtsx_pcr.c
··· 30 30 #include <linux/platform_device.h> 31 31 #include <linux/mfd/core.h> 32 32 #include <linux/mfd/rtsx_pci.h> 33 + #include <linux/mmc/card.h> 33 34 #include <asm/unaligned.h> 34 35 35 36 #include "rtsx_pcr.h" ··· 453 452 } 454 453 455 454 spin_lock_irqsave(&pcr->lock, flags); 456 - if (pcr->trans_result == TRANS_RESULT_FAIL) 457 - err = -EINVAL; 455 + if (pcr->trans_result == TRANS_RESULT_FAIL) { 456 + err = -EILSEQ; 457 + if (pcr->dma_error_count < RTS_MAX_TIMES_FREQ_REDUCTION) 458 + pcr->dma_error_count++; 459 + } 460 + 458 461 else if (pcr->trans_result == TRANS_NO_DEVICE) 459 462 err = -ENODEV; 460 463 spin_unlock_irqrestore(&pcr->lock, flags); ··· 663 658 SD_CLK_DIVIDE_MASK, clk_divider); 664 659 if (err < 0) 665 660 return err; 661 + 662 + /* Reduce card clock by 20MHz each time a DMA transfer error occurs */ 663 + if (card_clock == UHS_SDR104_MAX_DTR && 664 + pcr->dma_error_count && 665 + PCI_PID(pcr) == RTS5227_DEVICE_ID) 666 + card_clock = UHS_SDR104_MAX_DTR - 667 + (pcr->dma_error_count * 20000000); 666 668 667 669 card_clock /= 1000000; 668 670 pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock); ··· 906 894 pcr->card_removed |= SD_EXIST; 907 895 pcr->card_inserted &= ~SD_EXIST; 908 896 } 897 + pcr->dma_error_count = 0; 909 898 } 910 899 911 900 if (int_reg & MS_INT) {
+5
include/linux/mfd/rtsx_pci.h
··· 850 850 851 851 #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) 852 852 853 + #define RTS5227_DEVICE_ID 0x5227 854 + #define RTS_MAX_TIMES_FREQ_REDUCTION 8 855 + 853 856 struct rtsx_pcr; 854 857 855 858 struct pcr_handle { ··· 960 957 961 958 int num_slots; 962 959 struct rtsx_slot *slots; 960 + 961 + u8 dma_error_count; 963 962 }; 964 963 965 964 #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))