From patchwork Tue Jan 21 07:20:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yong Mao X-Patchwork-Id: 11343153 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C542109A for ; Tue, 21 Jan 2020 07:21:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2CE0B21734 for ; Tue, 21 Jan 2020 07:21:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="G6GJ0WK0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728931AbgAUHVu (ORCPT ); Tue, 21 Jan 2020 02:21:50 -0500 Received: from mailgw01.mediatek.com ([210.61.82.183]:12752 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725789AbgAUHVu (ORCPT ); Tue, 21 Jan 2020 02:21:50 -0500 X-UUID: 7f0d56b122ea46fb82bc2fb160158317-20200121 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=RTFuTKew6Bbm3rHXc1VuNfPD8aZnX6svfZSE96XCyyo=; b=G6GJ0WK0KJLZHBZHmKZEHKQeb4uL81/0+KuDml2kO3lqqls2rmeHT7qjXZCGRjvPPCKCT4yuve7e7RtrIj8s2Q1HHudI6Ir3vgdTqIpCLhM00xmyz7Tl5FAXsFJv1b42jxHrTD3hk6bWY/Wiub4o/g5n7iu2LLiTtMvEajDytCg=; X-UUID: 7f0d56b122ea46fb82bc2fb160158317-20200121 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1503164164; Tue, 21 Jan 2020 15:21:47 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Tue, 21 Jan 2020 15:21:06 +0800 Received: from localhost.localdomain (10.17.3.153) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Tue, 21 Jan 2020 15:19:25 +0800 From: Yong Mao To: Ulf Hansson CC: Chaotian Jing , Matthias Brugger , , , , , , yong mao Subject: [PATCH] mmc: mediatek: fix SDIO irq issue Date: Tue, 21 Jan 2020 15:20:58 +0800 Message-ID: <1579591258-30940-2-git-send-email-yong.mao@mediatek.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1579591258-30940-1-git-send-email-yong.mao@mediatek.com> References: <1579591258-30940-1-git-send-email-yong.mao@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: yong mao Host controller may lost interrupt in some specail case. Add SDIO irq recheck mechanism to make sure all interrupts can be processed immediately. Signed-off-by: Yong Mao Tested-by: Hsin-Yi Wang --- drivers/mmc/host/mtk-sd.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 7726dcf..18a1b86 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -128,6 +128,7 @@ #define MSDC_PS_CDSTS (0x1 << 1) /* R */ #define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */ #define MSDC_PS_DAT (0xff << 16) /* R */ +#define MSDC_PS_DATA1 (0x1 << 17) /* R */ #define MSDC_PS_CMD (0x1 << 24) /* R */ #define MSDC_PS_WP (0x1 << 31) /* R */ @@ -361,6 +362,7 @@ struct msdc_save_para { struct mtk_mmc_compatible { u8 clk_div_bits; + bool recheck_sdio_irq; bool hs400_tune; /* only used for MT8173 */ u32 pad_tune_reg; bool async_fifo; @@ -436,6 +438,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt8135_compat = { .clk_div_bits = 8, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE, .async_fifo = false, @@ -448,6 +451,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt8173_compat = { .clk_div_bits = 8, + .recheck_sdio_irq = true, .hs400_tune = true, .pad_tune_reg = MSDC_PAD_TUNE, .async_fifo = false, @@ -460,6 +464,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt8183_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -472,6 +477,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt2701_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -484,6 +490,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt2712_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -496,6 +503,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt7622_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -508,6 +516,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt8516_compat = { .clk_div_bits = 12, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE0, .async_fifo = true, @@ -518,6 +527,7 @@ struct msdc_host { static const struct mtk_mmc_compatible mt7620_compat = { .clk_div_bits = 8, + .recheck_sdio_irq = false, .hs400_tune = false, .pad_tune_reg = MSDC_PAD_TUNE, .async_fifo = false, @@ -1007,6 +1017,30 @@ static int msdc_auto_cmd_done(struct msdc_host *host, int events, return cmd->error; } +/** + * msdc_recheck_sdio_irq - recheck whether the SDIO irq is lost + * + * Host controller may lost interrupt in some special case. + * Add SDIO irq recheck mechanism to make sure all interrupts + * can be processed immediately + * + */ +static void msdc_recheck_sdio_irq(struct msdc_host *host) +{ + u32 reg_int, reg_inten, reg_ps; + + if ((host->mmc->caps & MMC_CAP_SDIO_IRQ)) { + reg_inten = readl(host->base + MSDC_INTEN); + if (reg_inten & MSDC_INTEN_SDIOIRQ) { + reg_int = readl(host->base + MSDC_INT); + reg_ps = readl(host->base + MSDC_PS); + if (!((reg_int & MSDC_INT_SDIOIRQ) || + (reg_ps & MSDC_PS_DATA1))) + sdio_signal_irq(host->mmc); + } + } +} + static void msdc_track_cmd_data(struct msdc_host *host, struct mmc_command *cmd, struct mmc_data *data) { @@ -1035,6 +1069,8 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) if (host->error) msdc_reset_hw(host); mmc_request_done(host->mmc, mrq); + if (host->dev_comp->recheck_sdio_irq) + msdc_recheck_sdio_irq(host); } /* returns true if command is fully handled; returns false otherwise */ @@ -1393,6 +1429,8 @@ static void __msdc_enable_sdio_irq(struct msdc_host *host, int enb) if (enb) { sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ); sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); + if (host->dev_comp->recheck_sdio_irq) + msdc_recheck_sdio_irq(host); } else { sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ); sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);