From nobody Sun Feb 8 15:58:50 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A9D8345741; Thu, 22 Jan 2026 08:48:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769071692; cv=none; b=pzewSGXd0sPlET/k75sD47OS5Tp3+vuxcGVaGFMewuolRT/wXla5iyukHxAmLS0zk7OuO/+ZwKHBj3TSl3xtvcdU+lH/CyoTkdf8Yus1W19uRg8x7MlzbZW/7qzywhils6piRf3I0sY68eutj8FnaKxzib6Af/DatienH5Q6fK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769071692; c=relaxed/simple; bh=73FZ59Y0LrZN7kznxfUedf4wMtg/be2Q45yi8oYwaJA=; h=From:To:CC:Subject:Date:Message-ID:References:In-Reply-To: Content-Type:MIME-Version; b=RxwdyjJblr0BGe7o6rHKN3LrEG7+ni3Kl8mHPKX2n/eJDtHFBMoj9HL0mXMN34K/yiM53wSOoPXejaW6JawWtg0wiU7mG9sh6XR7+01YP6FW70mNgtRD4Qv/3HyhQYw2mfDYB5idKQALEsKgWg90rsUvudXN56DIVEb0tEP7cIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=TZ4HErRQ; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="TZ4HErRQ" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 60M8ln2Z3719314, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1769071669; bh=73FZ59Y0LrZN7kznxfUedf4wMtg/be2Q45yi8oYwaJA=; h=From:To:CC:Subject:Date:Message-ID:References:In-Reply-To: Content-Type:Content-Transfer-Encoding:MIME-Version; b=TZ4HErRQtuor03lAfq8dbR3naW+CZZQME1ytbRxtkt4meq+Uf7qL7JoVz1VvBkYOB UQoF6d3oz368uap5CopoxxGb4OYnt1OxPlIk0jQ6b6kPdv6b8rbHy6H1kULdRQCvsb e2XWRLnvaGiz2urMn571hna+axu8n/YqjDmis6jScmxYcMYsiZoj6m9OluouKHUz3+ r1YM5f0JCQgcrgpweGj1cjdZIRzSB5OQYcMEHPriazssSzdaZVXFzzMnzHG7xdaf33 M/MhHtoWE47ulYDBvwf88/Xfg5MOB2oE34EmrQinLQnFfWgxiF9jYAqnTLCGtCoTTk fTnFA+B2K7nTQ== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.21/5.94) with ESMTPS id 60M8ln2Z3719314 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 22 Jan 2026 16:47:49 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Thu, 22 Jan 2026 16:47:49 +0800 Received: from RTKEXHMBS04.realtek.com.tw ([::1]) by RTKEXHMBS04.realtek.com.tw ([fe80::1835:4740:79c:5e0a%6]) with mapi id 15.02.1748.010; Thu, 22 Jan 2026 16:47:49 +0800 From: Ricky WU To: Ulf Hansson , Matthew Schwartz CC: "linux-mmc@vger.kernel.org" , "linux-kernel@vger.kernel.org" Subject: RE: [PATCH] mmc: rtsx_pci_sdmmc: implement sdmmc_card_busy function Thread-Topic: [PATCH] mmc: rtsx_pci_sdmmc: implement sdmmc_card_busy function Thread-Index: AQHceQRkLnb7EmC95kS/HOptKpYFOLVTHP+wgAk2dQCAAamt4A== Date: Thu, 22 Jan 2026 08:47:49 +0000 Message-ID: <62b33623756d497d88bbdb9deccc0766@realtek.com> References: <20251229204526.2850803-1-matthew.schwartz@linux.dev> <220bd61b3ab743b492632764a38f95f0@realtek.com> In-Reply-To: Accept-Language: zh-TW, en-US Content-Language: zh-TW Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 > > > > Hi Matthew, > > > > Thanks for working on this patch. > > > > We=E2=80=99ve tested this change on our platforms and can confirm that = adding the > > card_busy() callback does resolve the > > =E2=80=9Ccannot verify signal voltage switch=E2=80=9D issue for us =F0= =9F=91=8D. > > > > That said, while reviewing the change we noticed a potential redundancy= in > > the existing driver logic. In sdmmc_switch_voltage() we already perform > > explicit DAT line stabilization checks via > > sd_wait_voltage_stable_1() and sd_wait_voltage_stable_2(). > > > > Once card_busy() is implemented and used by the MMC core during the > > voltage-switch verification phase, these two stabilization steps appear= to > > be partially overlapping with what the core now validates via > > card_busy(). In our testing, with card_busy() present, the stable_1 / > > stable_2 logic no longer seems strictly necessary and could likely be > > simplified or removed with some adjustment. > > > > From a process point of view, we=E2=80=99re not sure which approach you= =E2=80=99d prefer: > > > > Land your patch as-is first, and then we can follow up with a separate > > cleanup/modification patch to adjust sdmmc_switch_voltage(), or > > > > We can prepare an additional patch that builds on top of yours and share > > it with you for review, so the changes can be aligned together. > > > > Please let us know which option you think makes more sense for upstream, > or > > if you=E2=80=99d prefer a different approach. > > > > Thanks again for the fix and for looking into this driver. > > > > Best regards, > > Ricky > > > > > rtsx_pci_sdmmc does not have an sdmmc_card_busy function, so any > voltage > > > switches cause a kernel warning, "mmc0: cannot verify signal voltage > switch." > > > > > > Copy the sdmmc_card_busy function from rtsx_pci_usb to rtsx_pci_sdmmc > to > > > fix this. > > > > > > Fixes: ff984e57d36e ("mmc: Add realtek pcie sdmmc host driver") > > > Signed-off-by: Matthew Schwartz >=20 > I have applied this for fixes and by adding a stable tag. I am also > adding Ricky's reviewed/tested-by tag, according to the above. >=20 > Let's deal with the potential improvement on-top, as agreed. >=20 > Kind regards > Uffe >=20 >=20 Hi Matthew Ulf, based on card_busy() patch, we=E2=80=99ve prepared a small follow-up change that simplifies the voltage-switch handling in sdmmc_switch_voltage(). sd_wait_voltage_stable_1() and sd_wait_voltage_stable_2() become largely redundant. In our testing, removing these two helpers and keeping only the minimal clock-control handling (forcing the SD clock to stop before switching and cleaning up on error) works correctly and still conforms to the expected SD voltage switch behavior. The core-level checks via card_busy() now cover the DAT line verification that was previously duplicated in the driver. The attached diff removes sd_wait_voltage_stable_1() and sd_wait_voltage_stable_2(), and simplifies sdmmc_switch_voltage() accordingly. Ricky --- drivers/mmc/host/rtsx_pci_sdmmc.c | 88 +++---------------------------- 1 file changed, 6 insertions(+), 82 deletions(-) diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_= sdmmc.c index 4db3328f46df..8dfbc62f165b 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -1181,79 +1181,6 @@ static int sdmmc_get_cd(struct mmc_host *mmc) return cd; } =20 -static int sd_wait_voltage_stable_1(struct realtek_pci_sdmmc *host) -{ - struct rtsx_pcr *pcr =3D host->pcr; - int err; - u8 stat; - - /* Reference to Signal Voltage Switch Sequence in SD spec. - * Wait for a period of time so that the card can drive SD_CMD and - * SD_DAT[3:0] to low after sending back CMD11 response. - */ - mdelay(1); - - /* SD_CMD, SD_DAT[3:0] should be driven to low by card; - * If either one of SD_CMD,SD_DAT[3:0] is not low, - * abort the voltage switch sequence; - */ - err =3D rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); - if (err < 0) - return err; - - if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) - return -EINVAL; - - /* Stop toggle SD clock */ - err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, - 0xFF, SD_CLK_FORCE_STOP); - if (err < 0) - return err; - - return 0; -} - -static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host) -{ - struct rtsx_pcr *pcr =3D host->pcr; - int err; - u8 stat, mask, val; - - /* Wait 1.8V output of voltage regulator in card stable */ - msleep(50); - - /* Toggle SD clock again */ - err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); - if (err < 0) - return err; - - /* Wait for a period of time so that the card can drive - * SD_DAT[3:0] to high at 1.8V - */ - msleep(20); - - /* SD_CMD, SD_DAT[3:0] should be pulled high by host */ - err =3D rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); - if (err < 0) - return err; - - mask =3D SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS; - val =3D SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS; - if ((stat & mask) !=3D val) { - dev_dbg(sdmmc_dev(host), - "%s: SD_BUS_STAT =3D 0x%x\n", __func__, stat); - rtsx_pci_write_register(pcr, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - rtsx_pci_write_register(pcr, CARD_CLK_EN, 0xFF, 0); - return -EINVAL; - } - - return 0; -} - static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios) { struct realtek_pci_sdmmc *host =3D mmc_priv(mmc); @@ -1281,7 +1208,9 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc,= struct mmc_ios *ios) voltage =3D OUTPUT_1V8; =20 if (voltage =3D=3D OUTPUT_1V8) { - err =3D sd_wait_voltage_stable_1(host); + /* Stop toggle SD clock */ + err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, + 0xFF, SD_CLK_FORCE_STOP); if (err < 0) goto out; } @@ -1290,16 +1219,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mm= c, struct mmc_ios *ios) if (err < 0) goto out; =20 - if (voltage =3D=3D OUTPUT_1V8) { - err =3D sd_wait_voltage_stable_2(host); - if (err < 0) - goto out; - } - out: /* Stop toggle SD clock in idle */ - err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + if (err < 0) + rtsx_pci_write_register(pcr, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); =20 mutex_unlock(&pcr->pcr_mutex); =20 --=20 2.34.1 > > > --- > > > drivers/mmc/host/rtsx_pci_sdmmc.c | 41 > > > +++++++++++++++++++++++++++++++ > > > 1 file changed, 41 insertions(+) > > > > > > diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c > > > b/drivers/mmc/host/rtsx_pci_sdmmc.c > > > index dc2587ff8519..4db3328f46df 100644 > > > --- a/drivers/mmc/host/rtsx_pci_sdmmc.c > > > +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c > > > @@ -1306,6 +1306,46 @@ static int sdmmc_switch_voltage(struct > mmc_host > > > *mmc, struct mmc_ios *ios) > > > return err; > > > } > > > > > > +static int sdmmc_card_busy(struct mmc_host *mmc) { > > > + struct realtek_pci_sdmmc *host =3D mmc_priv(mmc); > > > + struct rtsx_pcr *pcr =3D host->pcr; > > > + int err; > > > + u8 stat; > > > + u8 mask =3D SD_DAT3_STATUS | SD_DAT2_STATUS | > SD_DAT1_STATUS > > > + | SD_DAT0_STATUS; > > > + > > > + mutex_lock(&pcr->pcr_mutex); > > > + > > > + rtsx_pci_start_run(pcr); > > > + > > > + err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, > > > + SD_CLK_TOGGLE_EN | > > > SD_CLK_FORCE_STOP, > > > + SD_CLK_TOGGLE_EN); > > > + if (err) > > > + goto out; > > > + > > > + mdelay(1); > > > + > > > + err =3D rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); > > > + if (err) > > > + goto out; > > > + > > > + err =3D rtsx_pci_write_register(pcr, SD_BUS_STAT, > > > + SD_CLK_TOGGLE_EN | > > > +SD_CLK_FORCE_STOP, 0); > > > +out: > > > + mutex_unlock(&pcr->pcr_mutex); > > > + > > > + if (err) > > > + return err; > > > + > > > + /* check if any pin between dat[0:3] is low */ > > > + if ((stat & mask) !=3D mask) > > > + return 1; > > > + else > > > + return 0; > > > +} > > > + > > > static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode) > { > > > struct realtek_pci_sdmmc *host =3D mmc_priv(mmc); @@ -1418,6 > > > +1458,7 @@ static const struct mmc_host_ops realtek_pci_sdmmc_ops =3D= { > > > .get_ro =3D sdmmc_get_ro, > > > .get_cd =3D sdmmc_get_cd, > > > .start_signal_voltage_switch =3D sdmmc_switch_voltage, > > > + .card_busy =3D sdmmc_card_busy, > > > .execute_tuning =3D sdmmc_execute_tuning, > > > .init_sd_express =3D sdmmc_init_sd_express, }; > > > -- > > > 2.52.0 > >