diff options
author | Wei WANG <wei_wang@realsil.com.cn> | 2013-08-20 02:18:52 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-08-20 04:22:00 -0400 |
commit | 5947c167d145f32d4475d647a87e2af2699efe45 (patch) | |
tree | b75c7a66d0c946c714ed141aff8f66839cd01f6a /drivers/mfd/rtsx_pcr.c | |
parent | 773ccdfd9cc6f9bf8ec75a59fa742d7a663a5903 (diff) |
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) | |||
927 | mutex_unlock(&pcr->pcr_mutex); | 927 | mutex_unlock(&pcr->pcr_mutex); |
928 | } | 928 | } |
929 | 929 | ||
930 | static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state) | ||
931 | { | ||
932 | if (pcr->ops->turn_off_led) | ||
933 | pcr->ops->turn_off_led(pcr); | ||
934 | |||
935 | rtsx_pci_writel(pcr, RTSX_BIER, 0); | ||
936 | pcr->bier = 0; | ||
937 | |||
938 | rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08); | ||
939 | rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, pm_state); | ||
940 | |||
941 | if (pcr->ops->force_power_down) | ||
942 | pcr->ops->force_power_down(pcr); | ||
943 | } | ||
944 | |||
930 | static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) | 945 | static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) |
931 | { | 946 | { |
932 | int err; | 947 | int err; |
@@ -1255,7 +1270,6 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state) | |||
1255 | { | 1270 | { |
1256 | struct pcr_handle *handle; | 1271 | struct pcr_handle *handle; |
1257 | struct rtsx_pcr *pcr; | 1272 | struct rtsx_pcr *pcr; |
1258 | int ret = 0; | ||
1259 | 1273 | ||
1260 | dev_dbg(&(pcidev->dev), "--> %s\n", __func__); | 1274 | dev_dbg(&(pcidev->dev), "--> %s\n", __func__); |
1261 | 1275 | ||
@@ -1267,14 +1281,7 @@ static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state) | |||
1267 | 1281 | ||
1268 | mutex_lock(&pcr->pcr_mutex); | 1282 | mutex_lock(&pcr->pcr_mutex); |
1269 | 1283 | ||
1270 | if (pcr->ops->turn_off_led) | 1284 | rtsx_pci_power_off(pcr, HOST_ENTER_S3); |
1271 | pcr->ops->turn_off_led(pcr); | ||
1272 | |||
1273 | rtsx_pci_writel(pcr, RTSX_BIER, 0); | ||
1274 | pcr->bier = 0; | ||
1275 | |||
1276 | rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08); | ||
1277 | rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02); | ||
1278 | 1285 | ||
1279 | pci_save_state(pcidev); | 1286 | pci_save_state(pcidev); |
1280 | pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0); | 1287 | 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) | |||
1282 | pci_set_power_state(pcidev, pci_choose_state(pcidev, state)); | 1289 | pci_set_power_state(pcidev, pci_choose_state(pcidev, state)); |
1283 | 1290 | ||
1284 | mutex_unlock(&pcr->pcr_mutex); | 1291 | mutex_unlock(&pcr->pcr_mutex); |
1285 | return ret; | 1292 | return 0; |
1286 | } | 1293 | } |
1287 | 1294 | ||
1288 | static int rtsx_pci_resume(struct pci_dev *pcidev) | 1295 | static int rtsx_pci_resume(struct pci_dev *pcidev) |
@@ -1320,10 +1327,25 @@ out: | |||
1320 | return ret; | 1327 | return ret; |
1321 | } | 1328 | } |
1322 | 1329 | ||
1330 | static void rtsx_pci_shutdown(struct pci_dev *pcidev) | ||
1331 | { | ||
1332 | struct pcr_handle *handle; | ||
1333 | struct rtsx_pcr *pcr; | ||
1334 | |||
1335 | dev_dbg(&(pcidev->dev), "--> %s\n", __func__); | ||
1336 | |||
1337 | handle = pci_get_drvdata(pcidev); | ||
1338 | pcr = handle->pcr; | ||
1339 | rtsx_pci_power_off(pcr, HOST_ENTER_S1); | ||
1340 | |||
1341 | pci_disable_device(pcidev); | ||
1342 | } | ||
1343 | |||
1323 | #else /* CONFIG_PM */ | 1344 | #else /* CONFIG_PM */ |
1324 | 1345 | ||
1325 | #define rtsx_pci_suspend NULL | 1346 | #define rtsx_pci_suspend NULL |
1326 | #define rtsx_pci_resume NULL | 1347 | #define rtsx_pci_resume NULL |
1348 | #define rtsx_pci_shutdown NULL | ||
1327 | 1349 | ||
1328 | #endif /* CONFIG_PM */ | 1350 | #endif /* CONFIG_PM */ |
1329 | 1351 | ||
@@ -1334,6 +1356,7 @@ static struct pci_driver rtsx_pci_driver = { | |||
1334 | .remove = rtsx_pci_remove, | 1356 | .remove = rtsx_pci_remove, |
1335 | .suspend = rtsx_pci_suspend, | 1357 | .suspend = rtsx_pci_suspend, |
1336 | .resume = rtsx_pci_resume, | 1358 | .resume = rtsx_pci_resume, |
1359 | .shutdown = rtsx_pci_shutdown, | ||
1337 | }; | 1360 | }; |
1338 | module_pci_driver(rtsx_pci_driver); | 1361 | module_pci_driver(rtsx_pci_driver); |
1339 | 1362 | ||