From c2eccd3ff2f0c838a1362e9f921790600f3b4aed Mon Sep 17 00:00:00 2001 From: Nan Li Date: Fri, 1 Nov 2019 16:39:14 +0800 Subject: [PATCH] sdio: optimize sdio suspend/resume [1/1] PD#SWPL-16036 Problem: When the system starts up, wifi is turned on. When we manually turn off wifi and start the suspend & resume operation, we will find that the sdio error is reported when we wake up Solution: Add the sdio_notify() interface to notify the sdio controller when wifi is on/off, enabling the keep_power standard to be configured when suspend. Verify: TL1 Change-Id: I48e0c31bf7ea80d3efd4b0d41b4af378e859dc15 Signed-off-by: Nan Li --- drivers/amlogic/mmc/aml_sd_emmc_v3.c | 4 ++++ drivers/amlogic/mmc/amlsd.c | 14 ++++++++++++++ drivers/amlogic/mmc/amlsd_of.c | 1 - drivers/amlogic/wifi/wifi_dt.c | 2 ++ drivers/mmc/core/sdio.c | 3 +++ include/linux/amlogic/wifi_dt.h | 1 + include/linux/mmc/host.h | 1 + 7 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index d6bdd87ff0bd..a18583c495ac 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -251,6 +251,10 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc, writel(vcfg, host->base + SD_EMMC_CFG); pdata->stop_clk = 1; } + if (!clk_ios) { + mmc->actual_clock = clk_ios; + return 0; + } if (aml_card_type_mmc(pdata)) { if ((clk_ios >= 200000000) && conf->ddr) { diff --git a/drivers/amlogic/mmc/amlsd.c b/drivers/amlogic/mmc/amlsd.c index 606adc517344..67af1f686ae3 100644 --- a/drivers/amlogic/mmc/amlsd.c +++ b/drivers/amlogic/mmc/amlsd.c @@ -331,6 +331,20 @@ void sdio_reinit(void) } EXPORT_SYMBOL(sdio_reinit); +void sdio_notify(int on) +{ + if (sdio_host) { + if (sdio_host->card) { + if (on) + sdio_host->wifi_down_f = 0; + else + sdio_host->wifi_down_f = 1; + } + } + pr_info("[%s] finish\n", __func__); +} +EXPORT_SYMBOL(sdio_notify); + void of_amlsd_pwr_prepare(struct amlsd_platform *pdata) { } diff --git a/drivers/amlogic/mmc/amlsd_of.c b/drivers/amlogic/mmc/amlsd_of.c index a117ef59ee0f..3803142510fd 100644 --- a/drivers/amlogic/mmc/amlsd_of.c +++ b/drivers/amlogic/mmc/amlsd_of.c @@ -57,7 +57,6 @@ static const struct sd_caps host_caps[] = { SD_CAPS(MMC_CAP_CMD23, "MMC_CAP_CMD23"), SD_CAPS(MMC_CAP_HW_RESET, "MMC_CAP_HW_RESET"), SD_CAPS(MMC_CAP_AGGRESSIVE_PM, "MMC_CAP_AGGRESSIVE_PM"), - SD_CAPS(MMC_PM_KEEP_POWER, "MMC_PM_KEEP_POWER"), }; static int amlsd_get_host_caps(struct device_node *of_node, diff --git a/drivers/amlogic/wifi/wifi_dt.c b/drivers/amlogic/wifi/wifi_dt.c index c3f9bf8cf919..66c695bd2d86 100644 --- a/drivers/amlogic/wifi/wifi_dt.c +++ b/drivers/amlogic/wifi/wifi_dt.c @@ -214,6 +214,7 @@ static void usb_power_control(int is_power, int shift) if (!usb_power) { set_wifi_power(is_power); WIFI_INFO("Set %s power on !\n", (shift ? "WiFi":"BT")); + sdio_notify(1); sdio_reinit(); } usb_power |= (1 << shift); @@ -223,6 +224,7 @@ static void usb_power_control(int is_power, int shift) if (!usb_power) { set_wifi_power(is_power); WIFI_INFO("Set %s power down\n", (shift ? "WiFi":"BT")); + sdio_notify(0); } } mutex_unlock(&wifi_bt_mutex); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index beff76b5f1b0..b4fe12f92b4a 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -919,6 +919,9 @@ static int mmc_sdio_suspend(struct mmc_host *host) { mmc_claim_host(host); + if (host->wifi_down_f) + host->pm_flags |= MMC_PM_KEEP_POWER; + if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) sdio_disable_wide(host->card); diff --git a/include/linux/amlogic/wifi_dt.h b/include/linux/amlogic/wifi_dt.h index 64cc1e3adc09..fac7577cb6b5 100644 --- a/include/linux/amlogic/wifi_dt.h +++ b/include/linux/amlogic/wifi_dt.h @@ -19,6 +19,7 @@ #define _wifi_dt_h_ extern void sdio_reinit(void); +void sdio_notify(int on); extern char *get_wifi_inf(void); void extern_wifi_set_enable(int is_on); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8e046c6ed9b6..8ed2dd8f8ac0 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -229,6 +229,7 @@ struct mmc_host { unsigned int f_init; #ifdef CONFIG_AMLOGIC_MMC u8 first_init_flag; + int wifi_down_f; #endif u32 ocr_avail; u32 ocr_avail_sdio; /* SDIO-specific OCR */