|
@@ -927,6 +927,21 @@ static void rtsx_pci_idle_work(struct work_struct *work)
|
|
|
mutex_unlock(&pcr->pcr_mutex);
|
|
|
}
|
|
|
|
|
|
+static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
|
|
|
+{
|
|
|
+ if (pcr->ops->turn_off_led)
|
|
|
+ pcr->ops->turn_off_led(pcr);
|
|
|
+
|
|
|
+ rtsx_pci_writel(pcr, RTSX_BIER, 0);
|
|
|
+ pcr->bier = 0;
|
|
|
+
|
|
|
+ rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
|
|
|
+ rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, pm_state);
|
|
|
+
|
|
|
+ if (pcr->ops->force_power_down)
|
|
|
+ pcr->ops->force_power_down(pcr);
|
|
|
+}
|
|
|
+
|
|
|
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
|
|
|
{
|
|
|
int err;
|
|
@@ -1255,7 +1270,6 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
|
|
|
{
|
|
|
struct pcr_handle *handle;
|
|
|
struct rtsx_pcr *pcr;
|
|
|
- int ret = 0;
|
|
|
|
|
|
dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
|
|
|
|
|
@@ -1267,14 +1281,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
|
|
|
|
|
|
mutex_lock(&pcr->pcr_mutex);
|
|
|
|
|
|
- if (pcr->ops->turn_off_led)
|
|
|
- pcr->ops->turn_off_led(pcr);
|
|
|
-
|
|
|
- rtsx_pci_writel(pcr, RTSX_BIER, 0);
|
|
|
- pcr->bier = 0;
|
|
|
-
|
|
|
- rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
|
|
|
- rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
|
|
|
+ rtsx_pci_power_off(pcr, HOST_ENTER_S3);
|
|
|
|
|
|
pci_save_state(pcidev);
|
|
|
pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
|
|
@@ -1282,7 +1289,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
|
|
|
pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
|
|
|
|
|
|
mutex_unlock(&pcr->pcr_mutex);
|
|
|
- return ret;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int rtsx_pci_resume(struct pci_dev *pcidev)
|
|
@@ -1320,10 +1327,25 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static void rtsx_pci_shutdown(struct pci_dev *pcidev)
|
|
|
+{
|
|
|
+ struct pcr_handle *handle;
|
|
|
+ struct rtsx_pcr *pcr;
|
|
|
+
|
|
|
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
|
|
|
+
|
|
|
+ handle = pci_get_drvdata(pcidev);
|
|
|
+ pcr = handle->pcr;
|
|
|
+ rtsx_pci_power_off(pcr, HOST_ENTER_S1);
|
|
|
+
|
|
|
+ pci_disable_device(pcidev);
|
|
|
+}
|
|
|
+
|
|
|
#else /* CONFIG_PM */
|
|
|
|
|
|
#define rtsx_pci_suspend NULL
|
|
|
#define rtsx_pci_resume NULL
|
|
|
+#define rtsx_pci_shutdown NULL
|
|
|
|
|
|
#endif /* CONFIG_PM */
|
|
|
|
|
@@ -1334,6 +1356,7 @@ static struct pci_driver rtsx_pci_driver = {
|
|
|
.remove = rtsx_pci_remove,
|
|
|
.suspend = rtsx_pci_suspend,
|
|
|
.resume = rtsx_pci_resume,
|
|
|
+ .shutdown = rtsx_pci_shutdown,
|
|
|
};
|
|
|
module_pci_driver(rtsx_pci_driver);
|
|
|
|