struct pci_dev *pcidev = to_pci_dev(dev_d);
struct pcr_handle *handle = pci_get_drvdata(pcidev);
struct rtsx_pcr *pcr = handle->pcr;
+ struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
mutex_lock(&pcr->pcr_mutex);
+ if (slot->p_dev && slot->power_off)
+ slot->power_off(slot->p_dev);
+
rtsx_pci_power_off(pcr, HOST_ENTER_S3, false);
mutex_unlock(&pcr->pcr_mutex);
struct pci_dev *pcidev = to_pci_dev(device);
struct pcr_handle *handle = pci_get_drvdata(pcidev);
struct rtsx_pcr *pcr = handle->pcr;
+ struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
dev_dbg(device, "--> %s\n", __func__);
cancel_delayed_work_sync(&pcr->carddet_work);
mutex_lock(&pcr->pcr_mutex);
+
+ if (slot->p_dev && slot->power_off)
+ slot->power_off(slot->p_dev);
+
rtsx_pci_power_off(pcr, HOST_ENTER_S3, true);
mutex_unlock(&pcr->pcr_mutex);
};
static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios);
+static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode);
static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
{
rtsx_pci_start_run(pcr);
+ if (host->prev_power_state == MMC_POWER_OFF) {
+ err = sd_power_on(host, MMC_POWER_ON);
+ if (err) {
+ cmd->error = err;
+ mutex_unlock(&pcr->pcr_mutex);
+ goto finish;
+ }
+ }
+
rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
host->initial_mode, host->double_clk, host->vpclk);
rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
mmc_detect_change(host->mmc, 0);
}
+static void rtsx_pci_sdmmc_power_off(struct platform_device *pdev)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+
+ if (!host)
+ return;
+
+ host->prev_power_state = MMC_POWER_OFF;
+}
+
static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
platform_set_drvdata(pdev, host);
pcr->slots[RTSX_SD_CARD].p_dev = pdev;
pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
+ pcr->slots[RTSX_SD_CARD].power_off = rtsx_pci_sdmmc_power_off;
mutex_init(&host->host_mutex);
pcr = host->pcr;
pcr->slots[RTSX_SD_CARD].p_dev = NULL;
pcr->slots[RTSX_SD_CARD].card_event = NULL;
+ pcr->slots[RTSX_SD_CARD].power_off = NULL;
mmc = host->mmc;
cancel_work_sync(&host->work);