diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-08-11 17:52:50 -0400 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-08-18 02:17:42 -0400 |
commit | ddf711872c9d2b05b0fb25db3e6e0c2a50be39e3 (patch) | |
tree | 91c25d55265316d6bdd355bdf1d6c1dadf08aa0f | |
parent | 14096c13ef5bc0d21819a502f2b71ae17b60e452 (diff) |
remoteproc: Introduce auto-boot flag
Introduce an "auto-boot" flag on rprocs to make it possible to flag
remote processors without vdevs to automatically boot once the firmware
is found.
Preserve previous behavior of the wkup_m3 processor being explicitly
booted by a consumer.
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Loic Pallardy <loic.pallardy@st.com>
Cc: Suman Anna <s-anna@ti.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 28 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 13 | ||||
-rw-r--r-- | drivers/remoteproc/wkup_m3_rproc.c | 2 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 1 |
4 files changed, 30 insertions, 14 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 0f85f7eb476d..d3b812e85250 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -932,6 +932,10 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context) | |||
932 | /* look for virtio devices and register them */ | 932 | /* look for virtio devices and register them */ |
933 | ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler); | 933 | ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler); |
934 | 934 | ||
935 | /* if rproc is marked always-on, request it to boot */ | ||
936 | if (rproc->auto_boot) | ||
937 | rproc_boot_nowait(rproc); | ||
938 | |||
935 | out: | 939 | out: |
936 | release_firmware(fw); | 940 | release_firmware(fw); |
937 | /* allow rproc_del() contexts, if any, to proceed */ | 941 | /* allow rproc_del() contexts, if any, to proceed */ |
@@ -977,11 +981,16 @@ static int rproc_add_virtio_devices(struct rproc *rproc) | |||
977 | int rproc_trigger_recovery(struct rproc *rproc) | 981 | int rproc_trigger_recovery(struct rproc *rproc) |
978 | { | 982 | { |
979 | struct rproc_vdev *rvdev, *rvtmp; | 983 | struct rproc_vdev *rvdev, *rvtmp; |
984 | int ret; | ||
980 | 985 | ||
981 | dev_err(&rproc->dev, "recovering %s\n", rproc->name); | 986 | dev_err(&rproc->dev, "recovering %s\n", rproc->name); |
982 | 987 | ||
983 | init_completion(&rproc->crash_comp); | 988 | init_completion(&rproc->crash_comp); |
984 | 989 | ||
990 | /* shut down the remote */ | ||
991 | /* TODO: make sure this works with rproc->power > 1 */ | ||
992 | rproc_shutdown(rproc); | ||
993 | |||
985 | /* clean up remote vdev entries */ | 994 | /* clean up remote vdev entries */ |
986 | list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) | 995 | list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) |
987 | rproc_remove_virtio_dev(rvdev); | 996 | rproc_remove_virtio_dev(rvdev); |
@@ -992,7 +1001,18 @@ int rproc_trigger_recovery(struct rproc *rproc) | |||
992 | /* Free the copy of the resource table */ | 1001 | /* Free the copy of the resource table */ |
993 | kfree(rproc->cached_table); | 1002 | kfree(rproc->cached_table); |
994 | 1003 | ||
995 | return rproc_add_virtio_devices(rproc); | 1004 | ret = rproc_add_virtio_devices(rproc); |
1005 | if (ret) | ||
1006 | return ret; | ||
1007 | |||
1008 | /* | ||
1009 | * boot the remote processor up again, if the async firmware loader | ||
1010 | * didn't do so already, waiting for the async fw load to finish | ||
1011 | */ | ||
1012 | if (!rproc->auto_boot) | ||
1013 | rproc_boot(rproc); | ||
1014 | |||
1015 | return 0; | ||
996 | } | 1016 | } |
997 | 1017 | ||
998 | /** | 1018 | /** |
@@ -1373,6 +1393,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, | |||
1373 | rproc->name = name; | 1393 | rproc->name = name; |
1374 | rproc->ops = ops; | 1394 | rproc->ops = ops; |
1375 | rproc->priv = &rproc[1]; | 1395 | rproc->priv = &rproc[1]; |
1396 | rproc->auto_boot = true; | ||
1376 | 1397 | ||
1377 | device_initialize(&rproc->dev); | 1398 | device_initialize(&rproc->dev); |
1378 | rproc->dev.parent = dev; | 1399 | rproc->dev.parent = dev; |
@@ -1451,6 +1472,11 @@ int rproc_del(struct rproc *rproc) | |||
1451 | /* if rproc is just being registered, wait */ | 1472 | /* if rproc is just being registered, wait */ |
1452 | wait_for_completion(&rproc->firmware_loading_complete); | 1473 | wait_for_completion(&rproc->firmware_loading_complete); |
1453 | 1474 | ||
1475 | /* if rproc is marked always-on, rproc_add() booted it */ | ||
1476 | /* TODO: make sure this works with rproc->power > 1 */ | ||
1477 | if (rproc->auto_boot) | ||
1478 | rproc_shutdown(rproc); | ||
1479 | |||
1454 | /* clean up remote vdev entries */ | 1480 | /* clean up remote vdev entries */ |
1455 | list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) | 1481 | list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) |
1456 | rproc_remove_virtio_dev(rvdev); | 1482 | rproc_remove_virtio_dev(rvdev); |
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 93bf00d9c64e..01870a16d6d2 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c | |||
@@ -136,11 +136,6 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev) | |||
136 | 136 | ||
137 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) | 137 | static void rproc_virtio_del_vqs(struct virtio_device *vdev) |
138 | { | 138 | { |
139 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
140 | |||
141 | /* power down the remote processor before deleting vqs */ | ||
142 | rproc_shutdown(rproc); | ||
143 | |||
144 | __rproc_virtio_del_vqs(vdev); | 139 | __rproc_virtio_del_vqs(vdev); |
145 | } | 140 | } |
146 | 141 | ||
@@ -149,7 +144,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, | |||
149 | vq_callback_t *callbacks[], | 144 | vq_callback_t *callbacks[], |
150 | const char * const names[]) | 145 | const char * const names[]) |
151 | { | 146 | { |
152 | struct rproc *rproc = vdev_to_rproc(vdev); | ||
153 | int i, ret; | 147 | int i, ret; |
154 | 148 | ||
155 | for (i = 0; i < nvqs; ++i) { | 149 | for (i = 0; i < nvqs; ++i) { |
@@ -160,13 +154,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, | |||
160 | } | 154 | } |
161 | } | 155 | } |
162 | 156 | ||
163 | /* now that the vqs are all set, boot the remote processor */ | ||
164 | ret = rproc_boot_nowait(rproc); | ||
165 | if (ret) { | ||
166 | dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret); | ||
167 | goto error; | ||
168 | } | ||
169 | |||
170 | return 0; | 157 | return 0; |
171 | 158 | ||
172 | error: | 159 | error: |
diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c index 02d271d101b4..3811cb522af3 100644 --- a/drivers/remoteproc/wkup_m3_rproc.c +++ b/drivers/remoteproc/wkup_m3_rproc.c | |||
@@ -167,6 +167,8 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev) | |||
167 | goto err; | 167 | goto err; |
168 | } | 168 | } |
169 | 169 | ||
170 | rproc->auto_boot = false; | ||
171 | |||
170 | wkupm3 = rproc->priv; | 172 | wkupm3 = rproc->priv; |
171 | wkupm3->rproc = rproc; | 173 | wkupm3->rproc = rproc; |
172 | wkupm3->pdev = pdev; | 174 | wkupm3->pdev = pdev; |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 8229523f70a5..4783c8c4645a 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h | |||
@@ -443,6 +443,7 @@ struct rproc { | |||
443 | struct resource_table *cached_table; | 443 | struct resource_table *cached_table; |
444 | u32 table_csum; | 444 | u32 table_csum; |
445 | bool has_iommu; | 445 | bool has_iommu; |
446 | bool auto_boot; | ||
446 | }; | 447 | }; |
447 | 448 | ||
448 | /* we currently support only two vrings per rvdev */ | 449 | /* we currently support only two vrings per rvdev */ |