drivers/mmc/host/rtsx_usb_sdmmc.c | 36 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-)
SD spec definition:
"Host provides at least 74 Clocks before issuing first command"
add issue the clocks when power_mode is POWER_UP
and stop the signal when power_mode is POWER_up to POWER_ON
Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
---
v2: remove delay 100ms in power_on
v3: Use switch-case instead of if statements
---
drivers/mmc/host/rtsx_usb_sdmmc.c | 36 ++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index d229c2b83ea9..1c808cfb44ff 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -1014,24 +1014,40 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host,
unsigned char power_mode)
{
int err;
+ struct rtsx_ucr *ucr = host->ucr;
- if (power_mode != MMC_POWER_OFF)
- power_mode = MMC_POWER_ON;
-
- if (power_mode == host->power_mode)
- return 0;
-
- if (power_mode == MMC_POWER_OFF) {
+ switch (power_mode) {
+ case MMC_POWER_OFF:
+ if (host->power_mode == MMC_POWER_OFF)
+ return 0;
err = sd_power_off(host);
pm_runtime_put_noidle(sdmmc_dev(host));
- } else {
+ break;
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ if (host->power_mode == MMC_POWER_ON) {
+ return 0;
+ } else if (host->power_mode == MMC_POWER_UP) {
+ /* stop to send the clock signals */
+ rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
+ host->power_mode = power_mode;
+ return 0;
+ }
pm_runtime_get_noresume(sdmmc_dev(host));
err = sd_power_on(host);
+ break;
+ default:
+ return 0;
}
+ if (!err) {
+ if (power_mode == MMC_POWER_UP) {
+ /* issue the clock signals to card */
+ rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN,
+ SD_CLK_TOGGLE_EN);
+ }
- if (!err)
host->power_mode = power_mode;
-
+ }
return err;
}
--
2.25.1
On Fri, 6 Jun 2025 at 05:05, Ricky Wu <ricky_wu@realtek.com> wrote:
>
> SD spec definition:
> "Host provides at least 74 Clocks before issuing first command"
>
> add issue the clocks when power_mode is POWER_UP
> and stop the signal when power_mode is POWER_up to POWER_ON
>
> Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
Thanks for trying to re-work the code according to my earlier
suggestions. However, $subject patch still seems a bit messy in my
opinion. I decided to try to help out a bit and posted a series [1],
please try to re-base your patch on top of this.
Kind regards
Uffe
[1]
https://lore.kernel.org/all/20250610111633.504366-1-ulf.hansson@linaro.org/
> ---
> v2: remove delay 100ms in power_on
> v3: Use switch-case instead of if statements
> ---
> drivers/mmc/host/rtsx_usb_sdmmc.c | 36 ++++++++++++++++++++++---------
> 1 file changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
> index d229c2b83ea9..1c808cfb44ff 100644
> --- a/drivers/mmc/host/rtsx_usb_sdmmc.c
> +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
> @@ -1014,24 +1014,40 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host,
> unsigned char power_mode)
> {
> int err;
> + struct rtsx_ucr *ucr = host->ucr;
>
> - if (power_mode != MMC_POWER_OFF)
> - power_mode = MMC_POWER_ON;
> -
> - if (power_mode == host->power_mode)
> - return 0;
> -
> - if (power_mode == MMC_POWER_OFF) {
> + switch (power_mode) {
> + case MMC_POWER_OFF:
> + if (host->power_mode == MMC_POWER_OFF)
> + return 0;
> err = sd_power_off(host);
> pm_runtime_put_noidle(sdmmc_dev(host));
> - } else {
> + break;
> + case MMC_POWER_UP:
> + case MMC_POWER_ON:
> + if (host->power_mode == MMC_POWER_ON) {
> + return 0;
> + } else if (host->power_mode == MMC_POWER_UP) {
> + /* stop to send the clock signals */
> + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
> + host->power_mode = power_mode;
> + return 0;
> + }
> pm_runtime_get_noresume(sdmmc_dev(host));
> err = sd_power_on(host);
> + break;
> + default:
> + return 0;
> }
> + if (!err) {
> + if (power_mode == MMC_POWER_UP) {
> + /* issue the clock signals to card */
> + rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN,
> + SD_CLK_TOGGLE_EN);
> + }
>
> - if (!err)
> host->power_mode = power_mode;
> -
> + }
> return err;
> }
>
> --
> 2.25.1
>
© 2016 - 2025 Red Hat, Inc.