* [PATCH] misc: rtsx: usb card reader: add OCP support
@ 2025-08-05 3:22 Ricky Wu
2025-08-06 10:24 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Ricky Wu @ 2025-08-05 3:22 UTC (permalink / raw)
To: linux-kernel, linux-mmc, arnd, gregkh, chenhuacai, ricky_wu,
ulf.hansson, maximlevitsky
This patch adds support for Over Current Protection (OCP) to the Realtek
USB card reader driver.
The OCP mechanism protects the hardware by detecting and handling current
overload conditions.
This implementation includes:
- Register configurations to enable OCP monitoring.
- Handling of OCP interrupt events and associated error reporting.
- Card power management changes in response to OCP triggers.
This enhancement improves the robustness of the driver when operating in
environments where electrical anomalies may occur, particularly with SD
and MS card interfaces.
Signed-off-by: Ricky Wu <ricky_wu@realtek.com>
---
drivers/memstick/host/rtsx_usb_ms.c | 5 ++++-
drivers/misc/cardreader/rtsx_usb.c | 7 +++++++
drivers/mmc/host/rtsx_usb_sdmmc.c | 32 +++++++++++++++++++++++++----
include/linux/rtsx_usb.h | 11 ++++++++++
4 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
index 3878136227e4..9389e9643c24 100644
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -216,7 +216,10 @@ static int ms_power_off(struct rtsx_usb_ms *host)
rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0);
rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0);
-
+ rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+ POWER_MASK, POWER_OFF);
+ rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+ POWER_MASK | LDO3318_PWR_MASK, POWER_OFF | LDO_SUSPEND);
err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
if (err < 0)
return err;
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index d007a4455ce5..1830e9ed2521 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -552,6 +552,10 @@ static int rtsx_usb_reset_chip(struct rtsx_ucr *ucr)
ret = rtsx_usb_send_cmd(ucr, MODE_C, 100);
if (ret)
return ret;
+ /* config OCP */
+ rtsx_usb_write_register(ucr, OCPCTL, MS_OCP_DETECT_EN, MS_OCP_DETECT_EN);
+ rtsx_usb_write_register(ucr, OCPPARA1, 0xF0, 0x50);
+ rtsx_usb_write_register(ucr, OCPPARA2, 0x7, 0x3);
/* config non-crystal mode */
rtsx_usb_read_register(ucr, CFG_MODE, &val);
@@ -722,6 +726,9 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (val & (SD_CD | MS_CD)) {
device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);
return -EAGAIN;
+ } else {
+ /* if the card does not exists, clear OCP status */
+ rtsx_usb_write_register(ucr, OCPCTL, MS_OCP_CLEAR, MS_OCP_CLEAR);
}
} else {
/* There is an ongoing operation*/
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index c5f6b9df066b..0632d294b12f 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -48,7 +48,7 @@ struct rtsx_usb_sdmmc {
bool ddr_mode;
unsigned char power_mode;
-
+ u16 ocp_stat;
#ifdef RTSX_USB_USE_LEDS_CLASS
struct led_classdev led;
char led_name[32];
@@ -785,6 +785,9 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
mutex_unlock(&ucr->dev_mutex);
+ /* get OCP status */
+ host->ocp_stat = (val >> 4) & 0x03;
+
/* Treat failed detection as non-exist */
if (err)
goto no_card;
@@ -795,6 +798,11 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
}
no_card:
+ /* clear OCP status */
+ if (host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) {
+ rtsx_usb_write_register(ucr, OCPCTL, MS_OCP_CLEAR, MS_OCP_CLEAR);
+ host->ocp_stat = 0;
+ }
host->card_exist = false;
return 0;
}
@@ -818,7 +826,11 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
cmd->error = -ENOMEDIUM;
goto finish_detect_card;
}
-
+ /* check OCP stat */
+ if (host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) {
+ cmd->error = -ENOMEDIUM;
+ goto finish_detect_card;
+ }
mutex_lock(&ucr->dev_mutex);
mutex_lock(&host->host_mutex);
@@ -977,9 +989,19 @@ static int sd_power_on(struct rtsx_usb_sdmmc *host)
usleep_range(800, 1000);
+ rtsx_usb_init_cmd(ucr);
+ /* WA OCP issue: after OCP, there were problems with reopen card power */
+ rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, POWER_ON);
+ rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, FPDCTL, SSC_POWER_MASK, SSC_POWER_DOWN);
+ err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
+ if (err)
+ return err;
+ msleep(20);
+ rtsx_usb_write_register(ucr, FPDCTL, SSC_POWER_MASK, SSC_POWER_ON);
+ usleep_range(180, 200);
rtsx_usb_init_cmd(ucr);
rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
- POWER_MASK|LDO3318_PWR_MASK, POWER_ON|LDO_ON);
+ LDO3318_PWR_MASK, LDO_ON);
rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE,
SD_OUTPUT_EN, SD_OUTPUT_EN);
@@ -1029,7 +1051,8 @@ static void sd_set_power_mode(struct rtsx_usb_sdmmc *host,
case MMC_POWER_UP:
pm_runtime_get_noresume(sdmmc_dev(host));
- err = sd_power_on(host);
+ if (!(host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)))
+ err = sd_power_on(host);
if (err)
dev_dbg(sdmmc_dev(host), "power-on (err = %d)\n", err);
/* issue the clock signals to card at least 74 clocks */
@@ -1332,6 +1355,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host)
mmc->max_req_size = 524288;
host->power_mode = MMC_POWER_OFF;
+ host->ocp_stat = 0;
}
static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
diff --git a/include/linux/rtsx_usb.h b/include/linux/rtsx_usb.h
index f267a06c6b1e..276b509c03e3 100644
--- a/include/linux/rtsx_usb.h
+++ b/include/linux/rtsx_usb.h
@@ -99,6 +99,17 @@ extern int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card);
#define CD_MASK (SD_CD | MS_CD | XD_CD)
#define SD_WP 0x08
+/* OCPCTL */
+#define MS_OCP_DETECT_EN 0x08
+#define MS_OCP_INT_EN 0x04
+#define MS_OCP_INT_CLR 0x02
+#define MS_OCP_CLEAR 0x01
+
+/* OCPSTAT */
+#define MS_OCP_DETECT 0x80
+#define MS_OCP_NOW 0x02
+#define MS_OCP_EVER 0x01
+
/* reader command field offset & parameters */
#define READ_REG_CMD 0
#define WRITE_REG_CMD 1
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] misc: rtsx: usb card reader: add OCP support
2025-08-05 3:22 [PATCH] misc: rtsx: usb card reader: add OCP support Ricky Wu
@ 2025-08-06 10:24 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2025-08-06 10:24 UTC (permalink / raw)
To: Ricky Wu, linux-kernel, linux-mmc, arnd, gregkh, chenhuacai,
ulf.hansson, maximlevitsky
Cc: llvm, oe-kbuild-all
Hi Ricky,
kernel test robot noticed the following build warnings:
[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on char-misc/char-misc-next char-misc/char-misc-linus linus/master next-20250806]
[cannot apply to soc/for-next ulf-hansson-mmc-mirror/next v6.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ricky-Wu/misc-rtsx-usb-card-reader-add-OCP-support/20250806-101802
base: char-misc/char-misc-testing
patch link: https://lore.kernel.org/r/20250805032220.2355160-1-ricky_wu%40realtek.com
patch subject: [PATCH] misc: rtsx: usb card reader: add OCP support
config: i386-buildonly-randconfig-001-20250806 (https://download.01.org/0day-ci/archive/20250806/202508061704.hwI8epAJ-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250806/202508061704.hwI8epAJ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508061704.hwI8epAJ-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/mmc/host/rtsx_usb_sdmmc.c:1054:7: warning: variable 'err' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
1054 | if (!(host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mmc/host/rtsx_usb_sdmmc.c:1056:7: note: uninitialized use occurs here
1056 | if (err)
| ^~~
drivers/mmc/host/rtsx_usb_sdmmc.c:1054:3: note: remove the 'if' if its condition is always true
1054 | if (!(host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1055 | err = sd_power_on(host);
drivers/mmc/host/rtsx_usb_sdmmc.c:1038:9: note: initialize the variable 'err' to silence this warning
1038 | int err;
| ^
| = 0
1 warning generated.
vim +1054 drivers/mmc/host/rtsx_usb_sdmmc.c
1034
1035 static void sd_set_power_mode(struct rtsx_usb_sdmmc *host,
1036 unsigned char power_mode)
1037 {
1038 int err;
1039 struct rtsx_ucr *ucr = host->ucr;
1040
1041 if (power_mode == host->power_mode)
1042 return;
1043
1044 switch (power_mode) {
1045 case MMC_POWER_OFF:
1046 err = sd_power_off(host);
1047 if (err)
1048 dev_dbg(sdmmc_dev(host), "power-off (err = %d)\n", err);
1049 pm_runtime_put_noidle(sdmmc_dev(host));
1050 break;
1051
1052 case MMC_POWER_UP:
1053 pm_runtime_get_noresume(sdmmc_dev(host));
> 1054 if (!(host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)))
1055 err = sd_power_on(host);
1056 if (err)
1057 dev_dbg(sdmmc_dev(host), "power-on (err = %d)\n", err);
1058 /* issue the clock signals to card at least 74 clocks */
1059 rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN);
1060 break;
1061
1062 case MMC_POWER_ON:
1063 /* stop to send the clock signals */
1064 rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
1065 break;
1066
1067 case MMC_POWER_UNDEFINED:
1068 break;
1069
1070 default:
1071 break;
1072 }
1073
1074 host->power_mode = power_mode;
1075 }
1076
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-08-06 10:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-05 3:22 [PATCH] misc: rtsx: usb card reader: add OCP support Ricky Wu
2025-08-06 10:24 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).