diff options
Diffstat (limited to 'drivers/thunderbolt/switch.c')
| -rw-r--r-- | drivers/thunderbolt/switch.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index c1b016574fb4..10b56c66fec3 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c | |||
| @@ -239,7 +239,16 @@ static int tb_switch_nvm_read(void *priv, unsigned int offset, void *val, | |||
| 239 | int ret; | 239 | int ret; |
| 240 | 240 | ||
| 241 | pm_runtime_get_sync(&sw->dev); | 241 | pm_runtime_get_sync(&sw->dev); |
| 242 | |||
| 243 | if (!mutex_trylock(&sw->tb->lock)) { | ||
| 244 | ret = restart_syscall(); | ||
| 245 | goto out; | ||
| 246 | } | ||
| 247 | |||
| 242 | ret = dma_port_flash_read(sw->dma_port, offset, val, bytes); | 248 | ret = dma_port_flash_read(sw->dma_port, offset, val, bytes); |
| 249 | mutex_unlock(&sw->tb->lock); | ||
| 250 | |||
| 251 | out: | ||
| 243 | pm_runtime_mark_last_busy(&sw->dev); | 252 | pm_runtime_mark_last_busy(&sw->dev); |
| 244 | pm_runtime_put_autosuspend(&sw->dev); | 253 | pm_runtime_put_autosuspend(&sw->dev); |
| 245 | 254 | ||
| @@ -1019,7 +1028,6 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) | |||
| 1019 | * the new tunnel too early. | 1028 | * the new tunnel too early. |
| 1020 | */ | 1029 | */ |
| 1021 | pci_lock_rescan_remove(); | 1030 | pci_lock_rescan_remove(); |
| 1022 | pm_runtime_get_sync(&sw->dev); | ||
| 1023 | 1031 | ||
| 1024 | switch (val) { | 1032 | switch (val) { |
| 1025 | /* Approve switch */ | 1033 | /* Approve switch */ |
| @@ -1040,8 +1048,6 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) | |||
| 1040 | break; | 1048 | break; |
| 1041 | } | 1049 | } |
| 1042 | 1050 | ||
| 1043 | pm_runtime_mark_last_busy(&sw->dev); | ||
| 1044 | pm_runtime_put_autosuspend(&sw->dev); | ||
| 1045 | pci_unlock_rescan_remove(); | 1051 | pci_unlock_rescan_remove(); |
| 1046 | 1052 | ||
| 1047 | if (!ret) { | 1053 | if (!ret) { |
| @@ -1069,7 +1075,10 @@ static ssize_t authorized_store(struct device *dev, | |||
| 1069 | if (val > 2) | 1075 | if (val > 2) |
| 1070 | return -EINVAL; | 1076 | return -EINVAL; |
| 1071 | 1077 | ||
| 1078 | pm_runtime_get_sync(&sw->dev); | ||
| 1072 | ret = tb_switch_set_authorized(sw, val); | 1079 | ret = tb_switch_set_authorized(sw, val); |
| 1080 | pm_runtime_mark_last_busy(&sw->dev); | ||
| 1081 | pm_runtime_put_autosuspend(&sw->dev); | ||
| 1073 | 1082 | ||
| 1074 | return ret ? ret : count; | 1083 | return ret ? ret : count; |
| 1075 | } | 1084 | } |
| @@ -1195,8 +1204,12 @@ static ssize_t nvm_authenticate_store(struct device *dev, | |||
| 1195 | bool val; | 1204 | bool val; |
| 1196 | int ret; | 1205 | int ret; |
| 1197 | 1206 | ||
| 1198 | if (!mutex_trylock(&sw->tb->lock)) | 1207 | pm_runtime_get_sync(&sw->dev); |
| 1199 | return restart_syscall(); | 1208 | |
| 1209 | if (!mutex_trylock(&sw->tb->lock)) { | ||
| 1210 | ret = restart_syscall(); | ||
| 1211 | goto exit_rpm; | ||
| 1212 | } | ||
| 1200 | 1213 | ||
| 1201 | /* If NVMem devices are not yet added */ | 1214 | /* If NVMem devices are not yet added */ |
| 1202 | if (!sw->nvm) { | 1215 | if (!sw->nvm) { |
| @@ -1217,13 +1230,9 @@ static ssize_t nvm_authenticate_store(struct device *dev, | |||
| 1217 | goto exit_unlock; | 1230 | goto exit_unlock; |
| 1218 | } | 1231 | } |
| 1219 | 1232 | ||
| 1220 | pm_runtime_get_sync(&sw->dev); | ||
| 1221 | ret = nvm_validate_and_write(sw); | 1233 | ret = nvm_validate_and_write(sw); |
| 1222 | if (ret) { | 1234 | if (ret) |
| 1223 | pm_runtime_mark_last_busy(&sw->dev); | ||
| 1224 | pm_runtime_put_autosuspend(&sw->dev); | ||
| 1225 | goto exit_unlock; | 1235 | goto exit_unlock; |
| 1226 | } | ||
| 1227 | 1236 | ||
| 1228 | sw->nvm->authenticating = true; | 1237 | sw->nvm->authenticating = true; |
| 1229 | 1238 | ||
| @@ -1239,12 +1248,13 @@ static ssize_t nvm_authenticate_store(struct device *dev, | |||
| 1239 | } else { | 1248 | } else { |
| 1240 | ret = nvm_authenticate_device(sw); | 1249 | ret = nvm_authenticate_device(sw); |
| 1241 | } | 1250 | } |
| 1242 | pm_runtime_mark_last_busy(&sw->dev); | ||
| 1243 | pm_runtime_put_autosuspend(&sw->dev); | ||
| 1244 | } | 1251 | } |
| 1245 | 1252 | ||
| 1246 | exit_unlock: | 1253 | exit_unlock: |
| 1247 | mutex_unlock(&sw->tb->lock); | 1254 | mutex_unlock(&sw->tb->lock); |
| 1255 | exit_rpm: | ||
| 1256 | pm_runtime_mark_last_busy(&sw->dev); | ||
| 1257 | pm_runtime_put_autosuspend(&sw->dev); | ||
| 1248 | 1258 | ||
| 1249 | if (ret) | 1259 | if (ret) |
| 1250 | return ret; | 1260 | return ret; |
| @@ -1380,11 +1390,22 @@ static void tb_switch_release(struct device *dev) | |||
| 1380 | */ | 1390 | */ |
| 1381 | static int __maybe_unused tb_switch_runtime_suspend(struct device *dev) | 1391 | static int __maybe_unused tb_switch_runtime_suspend(struct device *dev) |
| 1382 | { | 1392 | { |
| 1393 | struct tb_switch *sw = tb_to_switch(dev); | ||
| 1394 | const struct tb_cm_ops *cm_ops = sw->tb->cm_ops; | ||
| 1395 | |||
| 1396 | if (cm_ops->runtime_suspend_switch) | ||
| 1397 | return cm_ops->runtime_suspend_switch(sw); | ||
| 1398 | |||
| 1383 | return 0; | 1399 | return 0; |
| 1384 | } | 1400 | } |
| 1385 | 1401 | ||
| 1386 | static int __maybe_unused tb_switch_runtime_resume(struct device *dev) | 1402 | static int __maybe_unused tb_switch_runtime_resume(struct device *dev) |
| 1387 | { | 1403 | { |
| 1404 | struct tb_switch *sw = tb_to_switch(dev); | ||
| 1405 | const struct tb_cm_ops *cm_ops = sw->tb->cm_ops; | ||
| 1406 | |||
| 1407 | if (cm_ops->runtime_resume_switch) | ||
| 1408 | return cm_ops->runtime_resume_switch(sw); | ||
| 1388 | return 0; | 1409 | return 0; |
| 1389 | } | 1410 | } |
| 1390 | 1411 | ||
