aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2018-02-28 18:11:56 -0600
committerSuman Anna2019-03-11 11:57:24 -0500
commit418ad4b211e9723bc6344167543f98f0fe5944ab (patch)
treee0b6bd931894a1ec89a4417874a5985c18f9aeaa
parent344028330ccef94440b2fc1c771d487c5b413dba (diff)
downloadremoteproc-418ad4b211e9723bc6344167543f98f0fe5944ab.tar.gz
remoteproc-418ad4b211e9723bc6344167543f98f0fe5944ab.tar.xz
remoteproc-418ad4b211e9723bc6344167543f98f0fe5944ab.zip
Revert "remoteproc: Introduce rproc_{start,stop}() functions"
This reverts commit 1efa30d0895e7e9a58a59b0880b330b38245be68. The commit 1efa30d0895e ("remoteproc: Introduce rproc_{start,stop}() functions") has refactored code out from rproc_boot() and rproc_shutdown() to optimize resource allocation overheads during the recovery. This patch was made with an implicit assumption that the same firmware image will always be used during recovery (rightfully so in a product environment), and so the resources will also remain the same. The patch had also changed the rproc state to RPROC_OFFLINE prior to cleaning up all resources and disabling the MMU in rproc_shutdown(). This does not play nice with doing any additional processing steps during recovery in the resource cleanup function. This patch is a custom revert of the above commit, accounting for all the changes added to the rproc_start() and rproc_stop() functions since kernel v4.13 and some additional changes added in commit 20afed1b45bf ("remoteproc: add infrastructure support to allow pre-loaded remoteprocs") and commit 2794d1693b05 ("remoteproc: Add support to handle device specific resource types") thereby allowing a new last trace mechanism to be supported in a subsequent patch. Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--drivers/remoteproc/remoteproc_core.c167
1 files changed, 73 insertions, 94 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 00a6e855784c..7e4ff372f2fa 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1014,19 +1014,60 @@ static void rproc_resource_cleanup(struct rproc *rproc)
1014 rproc_coredump_cleanup(rproc); 1014 rproc_coredump_cleanup(rproc);
1015} 1015}
1016 1016
1017static int rproc_start(struct rproc *rproc, const struct firmware *fw) 1017/*
1018 * take a firmware and boot a remote processor with it.
1019 */
1020static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
1018{ 1021{
1019 struct resource_table *loaded_table;
1020 struct device *dev = &rproc->dev; 1022 struct device *dev = &rproc->dev;
1023 const char *name = rproc->firmware;
1024 struct resource_table *loaded_table;
1021 int ret; 1025 int ret;
1022 1026
1027 ret = rproc_fw_sanity_check(rproc, fw);
1028 if (ret)
1029 return ret;
1030
1031 if (!rproc->skip_firmware_request)
1032 dev_info(dev, "Booting fw image %s, size %zd\n",
1033 name, fw->size);
1034 else
1035 dev_info(dev, "Booting unspecified pre-loaded fw image\n");
1036
1037 /*
1038 * if enabling an IOMMU isn't relevant for this rproc, this is
1039 * just a nop
1040 */
1041 ret = rproc_enable_iommu(rproc);
1042 if (ret) {
1043 dev_err(dev, "can't enable iommu: %d\n", ret);
1044 return ret;
1045 }
1046
1047 rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
1048
1049 /* Load resource table, core dump segment list etc from the firmware */
1050 ret = rproc_parse_fw(rproc, fw);
1051 if (ret)
1052 goto disable_iommu;
1053
1054 /* reset max_notifyid */
1055 rproc->max_notifyid = -1;
1056
1057 /* handle fw resources which are required to boot rproc */
1058 ret = rproc_handle_resources(rproc, rproc_loading_handlers);
1059 if (ret) {
1060 dev_err(dev, "Failed to process resources: %d\n", ret);
1061 goto clean_up_resources;
1062 }
1063
1023 if (!rproc->skip_load) { 1064 if (!rproc->skip_load) {
1024 /* load the ELF segments to memory */ 1065 /* load the ELF segments to memory */
1025 ret = rproc_load_segments(rproc, fw); 1066 ret = rproc_load_segments(rproc, fw);
1026 if (ret) { 1067 if (ret) {
1027 dev_err(dev, "Failed to load program segments: %d\n", 1068 dev_err(dev, "Failed to load program segments: %d\n",
1028 ret); 1069 ret);
1029 return ret; 1070 goto clean_up_resources;
1030 } 1071 }
1031 } 1072 }
1032 1073
@@ -1086,67 +1127,12 @@ unprepare_subdevices:
1086 rproc_unprepare_subdevices(rproc); 1127 rproc_unprepare_subdevices(rproc);
1087reset_table_ptr: 1128reset_table_ptr:
1088 rproc->table_ptr = rproc->cached_table; 1129 rproc->table_ptr = rproc->cached_table;
1089
1090 return ret;
1091}
1092
1093/*
1094 * take a firmware and boot a remote processor with it.
1095 */
1096static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
1097{
1098 struct device *dev = &rproc->dev;
1099 const char *name = rproc->firmware;
1100 int ret;
1101
1102 ret = rproc_fw_sanity_check(rproc, fw);
1103 if (ret)
1104 return ret;
1105
1106 if (!rproc->skip_firmware_request)
1107 dev_info(dev, "Booting fw image %s, size %zd\n",
1108 name, fw->size);
1109 else
1110 dev_info(dev, "Booting unspecified pre-loaded fw image\n");
1111
1112 /*
1113 * if enabling an IOMMU isn't relevant for this rproc, this is
1114 * just a nop
1115 */
1116 ret = rproc_enable_iommu(rproc);
1117 if (ret) {
1118 dev_err(dev, "can't enable iommu: %d\n", ret);
1119 return ret;
1120 }
1121
1122 rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
1123
1124 /* Load resource table, core dump segment list etc from the firmware */
1125 ret = rproc_parse_fw(rproc, fw);
1126 if (ret)
1127 goto disable_iommu;
1128
1129 /* reset max_notifyid */
1130 rproc->max_notifyid = -1;
1131
1132 /* handle fw resources which are required to boot rproc */
1133 ret = rproc_handle_resources(rproc, rproc_loading_handlers);
1134 if (ret) {
1135 dev_err(dev, "Failed to process resources: %d\n", ret);
1136 goto clean_up_resources;
1137 }
1138
1139 ret = rproc_start(rproc, fw);
1140 if (ret)
1141 goto clean_up_resources;
1142
1143 return 0;
1144
1145clean_up_resources: 1130clean_up_resources:
1146 rproc_resource_cleanup(rproc); 1131 rproc_resource_cleanup(rproc);
1147 kfree(rproc->cached_table); 1132 kfree(rproc->cached_table);
1148 rproc->cached_table = NULL; 1133 rproc->cached_table = NULL;
1149 rproc->table_ptr = NULL; 1134 rproc->table_ptr = NULL;
1135 rproc->table_sz = 0;
1150disable_iommu: 1136disable_iommu:
1151 rproc_disable_iommu(rproc); 1137 rproc_disable_iommu(rproc);
1152 return ret; 1138 return ret;
@@ -1186,40 +1172,6 @@ static int rproc_trigger_auto_boot(struct rproc *rproc)
1186 return ret; 1172 return ret;
1187} 1173}
1188 1174
1189static int rproc_stop(struct rproc *rproc, bool crashed)
1190{
1191 struct device *dev = &rproc->dev;
1192 int ret;
1193
1194 /* Stop any subdevices for the remote processor */
1195 rproc_stop_subdevices(rproc, crashed);
1196
1197 /* the installed resource table is no longer accessible */
1198 rproc->table_ptr = rproc->cached_table;
1199
1200 /* power off the remote processor */
1201 ret = rproc->ops->stop(rproc);
1202 if (ret) {
1203 dev_err(dev, "can't stop rproc: %d\n", ret);
1204 return ret;
1205 }
1206
1207 rproc_unprepare_subdevices(rproc);
1208
1209 /* if in crash state, perform coredump and unlock crash handler */
1210 if (rproc->state == RPROC_CRASHED) {
1211 rproc_coredump(rproc);
1212
1213 complete_all(&rproc->crash_comp);
1214 }
1215
1216 rproc->state = RPROC_OFFLINE;
1217
1218 dev_info(dev, "stopped remote processor %s\n", rproc->name);
1219
1220 return 0;
1221}
1222
1223/** 1175/**
1224 * rproc_coredump_add_segment() - add segment of device memory to coredump 1176 * rproc_coredump_add_segment() - add segment of device memory to coredump
1225 * @rproc: handle of a remote processor 1177 * @rproc: handle of a remote processor
@@ -1510,6 +1462,7 @@ void rproc_shutdown(struct rproc *rproc)
1510{ 1462{
1511 struct device *dev = &rproc->dev; 1463 struct device *dev = &rproc->dev;
1512 int ret; 1464 int ret;
1465 bool crashed = false;
1513 1466
1514 ret = mutex_lock_interruptible(&rproc->lock); 1467 ret = mutex_lock_interruptible(&rproc->lock);
1515 if (ret) { 1468 if (ret) {
@@ -1521,12 +1474,29 @@ void rproc_shutdown(struct rproc *rproc)
1521 if (!atomic_dec_and_test(&rproc->power)) 1474 if (!atomic_dec_and_test(&rproc->power))
1522 goto out; 1475 goto out;
1523 1476
1524 ret = rproc_stop(rproc, false); 1477 if (rproc->state == RPROC_CRASHED)
1478 crashed = true;
1479
1480 /* remove any subdevices for the remote processor */
1481 rproc_stop_subdevices(rproc, crashed);
1482
1483 /* power off the remote processor */
1484 ret = rproc->ops->stop(rproc);
1525 if (ret) { 1485 if (ret) {
1526 atomic_inc(&rproc->power); 1486 atomic_inc(&rproc->power);
1487 dev_err(dev, "can't stop rproc: %d\n", ret);
1527 goto out; 1488 goto out;
1528 } 1489 }
1529 1490
1491 rproc_unprepare_subdevices(rproc);
1492
1493 /* generate coredump */
1494 if (rproc->state == RPROC_CRASHED)
1495 rproc_coredump(rproc);
1496
1497 /* the installed resource table may no longer be accessible */
1498 rproc->table_ptr = rproc->cached_table;
1499
1530 /* clean up all acquired resources */ 1500 /* clean up all acquired resources */
1531 rproc_resource_cleanup(rproc); 1501 rproc_resource_cleanup(rproc);
1532 1502
@@ -1536,6 +1506,15 @@ void rproc_shutdown(struct rproc *rproc)
1536 kfree(rproc->cached_table); 1506 kfree(rproc->cached_table);
1537 rproc->cached_table = NULL; 1507 rproc->cached_table = NULL;
1538 rproc->table_ptr = NULL; 1508 rproc->table_ptr = NULL;
1509
1510 /* if in crash state, unlock crash handler */
1511 if (rproc->state == RPROC_CRASHED)
1512 complete_all(&rproc->crash_comp);
1513
1514 rproc->state = RPROC_OFFLINE;
1515
1516 dev_info(dev, "stopped remote processor %s\n", rproc->name);
1517
1539out: 1518out:
1540 mutex_unlock(&rproc->lock); 1519 mutex_unlock(&rproc->lock);
1541} 1520}