From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965324AbdEWCAN (ORCPT ); Mon, 22 May 2017 22:00:13 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:35951 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965186AbdEWCAL (ORCPT ); Mon, 22 May 2017 22:00:11 -0400 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.59 with qID v4N207Se027041, This message is accepted by code: ctaloc0852 From: To: CC: , Steven Feng Subject: [PATCH v5] mfd:rtsx: do retry when DMA transfer error Date: Tue, 23 May 2017 10:00:05 +0800 Message-ID: <1495504805-5627-1-git-send-email-steven_feng@realsil.com.cn> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [172.29.40.137] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Steven Feng 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 --- drivers/mfd/rtsx_pcr.c | 17 +++++++++++++++-- include/linux/mfd/rtsx_pci.h | 5 +++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 98029ee..ca2738c 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "rtsx_pcr.h" @@ -452,8 +453,12 @@ int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, } spin_lock_irqsave(&pcr->lock, flags); - if (pcr->trans_result == TRANS_RESULT_FAIL) - err = -EINVAL; + if (pcr->trans_result == TRANS_RESULT_FAIL) { + err = -EILSEQ; + if (pcr->dma_error_count < RTS_MAX_TIMES_FREQ_REDUCTION) + pcr->dma_error_count++; + } + else if (pcr->trans_result == TRANS_NO_DEVICE) err = -ENODEV; spin_unlock_irqrestore(&pcr->lock, flags); @@ -659,6 +664,13 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, if (err < 0) return err; + /*Reduce MMC card clock by 20MHz each time a DMA transfer error occurs*/ + if (card_clock == UHS_SDR104_MAX_DTR && + pcr->dma_error_count && + PCI_PID(pcr) == RTS5227_DEVICE_ID) + card_clock = UHS_SDR104_MAX_DTR - + (pcr->dma_error_count * 20000000); + card_clock /= 1000000; pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock); @@ -894,6 +906,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) pcr->card_removed |= SD_EXIST; pcr->card_inserted &= ~SD_EXIST; } + pcr->dma_error_count = 0; } if (int_reg & MS_INT) { diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 7eb7cba..116816f 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h @@ -850,6 +850,9 @@ #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) +#define RTS5227_DEVICE_ID 0x5227 +#define RTS_MAX_TIMES_FREQ_REDUCTION 8 + struct rtsx_pcr; struct pcr_handle { @@ -957,6 +960,8 @@ struct rtsx_pcr { int num_slots; struct rtsx_slot *slots; + + u8 dma_error_count; }; #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) -- 1.9.1