diff options
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/ds.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 143c6efc478a..a99607142fc8 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -1127,6 +1127,34 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, | |||
1127 | 1127 | ||
1128 | #endif | 1128 | #endif |
1129 | 1129 | ||
1130 | /************************ runtime PM support ***************************/ | ||
1131 | |||
1132 | static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); | ||
1133 | static int pcmcia_dev_resume(struct device *dev); | ||
1134 | |||
1135 | static int runtime_suspend(struct device *dev) | ||
1136 | { | ||
1137 | int rc; | ||
1138 | |||
1139 | down(&dev->sem); | ||
1140 | rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); | ||
1141 | up(&dev->sem); | ||
1142 | if (!rc) | ||
1143 | dev->power.power_state.event = PM_EVENT_SUSPEND; | ||
1144 | return rc; | ||
1145 | } | ||
1146 | |||
1147 | static void runtime_resume(struct device *dev) | ||
1148 | { | ||
1149 | int rc; | ||
1150 | |||
1151 | down(&dev->sem); | ||
1152 | rc = pcmcia_dev_resume(dev); | ||
1153 | up(&dev->sem); | ||
1154 | if (!rc) | ||
1155 | dev->power.power_state.event = PM_EVENT_ON; | ||
1156 | } | ||
1157 | |||
1130 | /************************ per-device sysfs output ***************************/ | 1158 | /************************ per-device sysfs output ***************************/ |
1131 | 1159 | ||
1132 | #define pcmcia_device_attr(field, test, format) \ | 1160 | #define pcmcia_device_attr(field, test, format) \ |
@@ -1173,9 +1201,9 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute | |||
1173 | return -EINVAL; | 1201 | return -EINVAL; |
1174 | 1202 | ||
1175 | if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) | 1203 | if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) |
1176 | ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); | 1204 | ret = runtime_suspend(dev); |
1177 | else if (p_dev->suspended && !strncmp(buf, "on", 2)) | 1205 | else if (p_dev->suspended && !strncmp(buf, "on", 2)) |
1178 | dpm_runtime_resume(dev); | 1206 | runtime_resume(dev); |
1179 | 1207 | ||
1180 | return ret ? ret : count; | 1208 | return ret ? ret : count; |
1181 | } | 1209 | } |
@@ -1312,10 +1340,10 @@ static int pcmcia_bus_suspend_callback(struct device *dev, void * _data) | |||
1312 | struct pcmcia_socket *skt = _data; | 1340 | struct pcmcia_socket *skt = _data; |
1313 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 1341 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
1314 | 1342 | ||
1315 | if (p_dev->socket != skt) | 1343 | if (p_dev->socket != skt || p_dev->suspended) |
1316 | return 0; | 1344 | return 0; |
1317 | 1345 | ||
1318 | return dpm_runtime_suspend(dev, PMSG_SUSPEND); | 1346 | return runtime_suspend(dev); |
1319 | } | 1347 | } |
1320 | 1348 | ||
1321 | static int pcmcia_bus_resume_callback(struct device *dev, void * _data) | 1349 | static int pcmcia_bus_resume_callback(struct device *dev, void * _data) |
@@ -1323,10 +1351,10 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) | |||
1323 | struct pcmcia_socket *skt = _data; | 1351 | struct pcmcia_socket *skt = _data; |
1324 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 1352 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
1325 | 1353 | ||
1326 | if (p_dev->socket != skt) | 1354 | if (p_dev->socket != skt || !p_dev->suspended) |
1327 | return 0; | 1355 | return 0; |
1328 | 1356 | ||
1329 | dpm_runtime_resume(dev); | 1357 | runtime_resume(dev); |
1330 | 1358 | ||
1331 | return 0; | 1359 | return 0; |
1332 | } | 1360 | } |