* [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; 3+ 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] 3+ 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; 3+ 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] 3+ messages in thread
* Re: [PATCH] misc: rtsx: usb card reader: add OCP support
@ 2025-08-11 17:00 kernel test robot
0 siblings, 0 replies; 3+ messages in thread
From: kernel test robot @ 2025-08-11 17:00 UTC (permalink / raw)
To: oe-kbuild; +Cc: lkp, Dan Carpenter
BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <20250805032220.2355160-1-ricky_wu@realtek.com>
References: <20250805032220.2355160-1-ricky_wu@realtek.com>
TO: Ricky Wu <ricky_wu@realtek.com>
TO: linux-kernel@vger.kernel.org
TO: linux-mmc@vger.kernel.org
TO: arnd@arndb.de
TO: gregkh@linuxfoundation.org
TO: chenhuacai@kernel.org
TO: ricky_wu@realtek.com
TO: ulf.hansson@linaro.org
TO: maximlevitsky@gmail.com
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 v6.17-rc1 next-20250808]
[cannot apply to soc/for-next ulf-hansson-mmc-mirror/next]
[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
:::::: branch date: 6 days ago
:::::: commit date: 6 days ago
config: i386-randconfig-141-20250811 (https://download.01.org/0day-ci/archive/20250812/202508120033.mgYsS7v2-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
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>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202508120033.mgYsS7v2-lkp@intel.com/
smatch warnings:
drivers/mmc/host/rtsx_usb_sdmmc.c:1056 sd_set_power_mode() error: uninitialized symbol 'err'.
vim +/err +1056 drivers/mmc/host/rtsx_usb_sdmmc.c
c7f6558d84afe6 Roger Tseng 2014-04-11 1034
55131d685ebee4 Ulf Hansson 2025-06-10 1035 static void sd_set_power_mode(struct rtsx_usb_sdmmc *host,
c7f6558d84afe6 Roger Tseng 2014-04-11 1036 unsigned char power_mode)
c7f6558d84afe6 Roger Tseng 2014-04-11 1037 {
c7f6558d84afe6 Roger Tseng 2014-04-11 1038 int err;
9939ac6ca0f5d5 Ricky Wu 2025-06-16 1039 struct rtsx_ucr *ucr = host->ucr;
c7f6558d84afe6 Roger Tseng 2014-04-11 1040
c7f6558d84afe6 Roger Tseng 2014-04-11 1041 if (power_mode == host->power_mode)
55131d685ebee4 Ulf Hansson 2025-06-10 1042 return;
c7f6558d84afe6 Roger Tseng 2014-04-11 1043
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1044 switch (power_mode) {
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1045 case MMC_POWER_OFF:
c7f6558d84afe6 Roger Tseng 2014-04-11 1046 err = sd_power_off(host);
f12b55b9782017 Ulf Hansson 2025-06-10 1047 if (err)
f12b55b9782017 Ulf Hansson 2025-06-10 1048 dev_dbg(sdmmc_dev(host), "power-off (err = %d)\n", err);
f275179f7bdcf0 Ulf Hansson 2018-05-31 1049 pm_runtime_put_noidle(sdmmc_dev(host));
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1050 break;
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1051
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1052 case MMC_POWER_UP:
f275179f7bdcf0 Ulf Hansson 2018-05-31 1053 pm_runtime_get_noresume(sdmmc_dev(host));
5bd9223f706cd9 Ricky Wu 2025-08-05 1054 if (!(host->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)))
c7f6558d84afe6 Roger Tseng 2014-04-11 1055 err = sd_power_on(host);
f12b55b9782017 Ulf Hansson 2025-06-10 @1056 if (err)
f12b55b9782017 Ulf Hansson 2025-06-10 1057 dev_dbg(sdmmc_dev(host), "power-on (err = %d)\n", err);
9939ac6ca0f5d5 Ricky Wu 2025-06-16 1058 /* issue the clock signals to card at least 74 clocks */
9939ac6ca0f5d5 Ricky Wu 2025-06-16 1059 rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN);
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1060 break;
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1061
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1062 case MMC_POWER_ON:
9939ac6ca0f5d5 Ricky Wu 2025-06-16 1063 /* stop to send the clock signals */
9939ac6ca0f5d5 Ricky Wu 2025-06-16 1064 rtsx_usb_write_register(ucr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00);
3ab659eb696f0a Nathan Chancellor 2025-06-20 1065 break;
3ab659eb696f0a Nathan Chancellor 2025-06-20 1066
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1067 case MMC_POWER_UNDEFINED:
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1068 break;
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1069
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1070 default:
f9a1a9448f5c12 Ulf Hansson 2025-06-10 1071 break;
c7f6558d84afe6 Roger Tseng 2014-04-11 1072 }
c7f6558d84afe6 Roger Tseng 2014-04-11 1073
c7f6558d84afe6 Roger Tseng 2014-04-11 1074 host->power_mode = power_mode;
c7f6558d84afe6 Roger Tseng 2014-04-11 1075 }
c7f6558d84afe6 Roger Tseng 2014-04-11 1076
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-11 17:01 UTC | newest]
Thread overview: 3+ 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
-- strict thread matches above, loose matches on Subject: below --
2025-08-11 17:00 kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.