diff options
author | Wei WANG <wei_wang@realsil.com.cn> | 2013-08-20 10:18:52 +0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-08-20 12:22:00 +0400 |
commit | 5947c167d145f32d4475d647a87e2af2699efe45 (patch) | |
tree | b75c7a66d0c946c714ed141aff8f66839cd01f6a /drivers/mfd/rtsx_pcr.c | |
parent | 773ccdfd9cc6f9bf8ec75a59fa742d7a663a5903 (diff) | |
download | linux-5947c167d145f32d4475d647a87e2af2699efe45.tar.xz |
mfd: rtsx: Add shutdown callback in rtsx_pci_driver
Some actions to clear power state should be handled in .shutdown
callback in rtsx_pci_driver. This patch adopts the following measures to
catch this goal:
1. Add a function rtsx_pci_power_off to abstract the common ops in
.shutdown and .suspend
2. Add pcr->ops->force_power_down to fulfill the individual action for
each reader model
Signed-off-by: Wei WANG <wei_wang@realsil.com.cn>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index e06d6b0d55f6..97526f1acf96 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -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); |