From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/mmc/host/rtsx_usb_sdmmc.c | 81 +++++++++++++++++++++++++--------------- 1 files changed, 51 insertions(+), 30 deletions(-) diff --git a/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c b/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c index 9a3ff22..1be3a35 100644 --- a/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/kernel/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Realtek USB SD/MMC Card Interface driver * * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. * * Author: * Roger Tseng <rogerable@realtek.com> @@ -28,6 +17,7 @@ #include <linux/mmc/sd.h> #include <linux/mmc/card.h> #include <linux/scatterlist.h> +#include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/rtsx_usb.h> @@ -589,7 +579,6 @@ static int sd_change_phase(struct rtsx_usb_sdmmc *host, u8 sample_point, int tx) { struct rtsx_ucr *ucr = host->ucr; - int err; dev_dbg(sdmmc_dev(host), "%s: %s sample_point = %d\n", __func__, tx ? "TX" : "RX", sample_point); @@ -611,11 +600,7 @@ rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, 0); rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_RST, 0); - err = rtsx_usb_send_cmd(ucr, MODE_C, 100); - if (err) - return err; - - return 0; + return rtsx_usb_send_cmd(ucr, MODE_C, 100); } static inline u32 get_phase_point(u32 phase_map, unsigned int idx) @@ -664,12 +649,11 @@ static void sd_wait_data_idle(struct rtsx_usb_sdmmc *host) { - int err, i; + int i; u8 val = 0; for (i = 0; i < 100; i++) { - err = rtsx_usb_ep0_read_register(host->ucr, - SD_DATA_STATE, &val); + rtsx_usb_ep0_read_register(host->ucr, SD_DATA_STATE, &val); if (val & SD_DATA_IDLE) return; @@ -1042,9 +1026,9 @@ if (power_mode == MMC_POWER_OFF) { err = sd_power_off(host); - pm_runtime_put(sdmmc_dev(host)); + pm_runtime_put_noidle(sdmmc_dev(host)); } else { - pm_runtime_get_sync(sdmmc_dev(host)); + pm_runtime_get_noresume(sdmmc_dev(host)); err = sd_power_on(host); } @@ -1297,16 +1281,20 @@ container_of(work, struct rtsx_usb_sdmmc, led_work); struct rtsx_ucr *ucr = host->ucr; - pm_runtime_get_sync(sdmmc_dev(host)); + pm_runtime_get_noresume(sdmmc_dev(host)); mutex_lock(&ucr->dev_mutex); + + if (host->power_mode == MMC_POWER_OFF) + goto out; if (host->led.brightness == LED_OFF) rtsx_usb_turn_off_led(ucr); else rtsx_usb_turn_on_led(ucr); +out: mutex_unlock(&ucr->dev_mutex); - pm_runtime_put(sdmmc_dev(host)); + pm_runtime_put_sync_suspend(sdmmc_dev(host)); } #endif @@ -1320,7 +1308,7 @@ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | - MMC_CAP_NEEDS_POLL | MMC_CAP_ERASE; + MMC_CAP_SYNC_RUNTIME_PM; mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE | MMC_CAP2_NO_SDIO; @@ -1344,6 +1332,7 @@ #ifdef RTSX_USB_USE_LEDS_CLASS int err; #endif + int ret; ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent)); if (!ucr) @@ -1363,8 +1352,6 @@ mutex_init(&host->host_mutex); rtsx_usb_init_host(host); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, 50); pm_runtime_enable(&pdev->dev); #ifdef RTSX_USB_USE_LEDS_CLASS @@ -1382,7 +1369,15 @@ INIT_WORK(&host->led_work, rtsx_usb_update_led); #endif - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) { +#ifdef RTSX_USB_USE_LEDS_CLASS + led_classdev_unregister(&host->led); +#endif + mmc_free_host(mmc); + pm_runtime_disable(&pdev->dev); + return ret; + } return 0; } @@ -1419,7 +1414,6 @@ mmc_free_host(mmc); pm_runtime_disable(&pdev->dev); - pm_runtime_dont_use_autosuspend(&pdev->dev); platform_set_drvdata(pdev, NULL); dev_dbg(&(pdev->dev), @@ -1427,6 +1421,31 @@ return 0; } + +#ifdef CONFIG_PM +static int rtsx_usb_sdmmc_runtime_suspend(struct device *dev) +{ + struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev); + + host->mmc->caps &= ~MMC_CAP_NEEDS_POLL; + return 0; +} + +static int rtsx_usb_sdmmc_runtime_resume(struct device *dev) +{ + struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev); + + host->mmc->caps |= MMC_CAP_NEEDS_POLL; + if (sdmmc_get_cd(host->mmc) == 1) + mmc_detect_change(host->mmc, 0); + return 0; +} +#endif + +static const struct dev_pm_ops rtsx_usb_sdmmc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(rtsx_usb_sdmmc_runtime_suspend, + rtsx_usb_sdmmc_runtime_resume, NULL) +}; static const struct platform_device_id rtsx_usb_sdmmc_ids[] = { { @@ -1443,6 +1462,8 @@ .id_table = rtsx_usb_sdmmc_ids, .driver = { .name = "rtsx_usb_sdmmc", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .pm = &rtsx_usb_sdmmc_dev_pm_ops, }, }; module_platform_driver(rtsx_usb_sdmmc_driver); -- Gitblit v1.6.2