aboutsummaryrefslogtreecommitdiffci
path: root/patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
authorGravatar Saya Andy <saya.andy@posteo.com> 2026-09-18 21:45:43 +0700
committerGravatar Saya Andy <saya.andy@posteo.com> 2026-09-18 21:45:43 +0700
commit1f2b96ab1a13be88c57c78be08168c0bb0080088 (patch)
treecb830075f52e08698d63f0e5c4e1359a063a62b8 /patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch
parentee8c44555b0c3d61bf1998ddf3a5823db04ae68f (diff)
downloadkernel-surface-1f2b96ab1a13be88c57c78be08168c0bb0080088.tar.gz
kernel-surface-1f2b96ab1a13be88c57c78be08168c0bb0080088.zip
fix: adapt patches for some 7.2.6 kernel updates to remoteproc and usbfedora-45-kernel-7.2.6-patchset-1
Diffstat (limited to 'patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch')
-rw-r--r--patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch349
1 files changed, 349 insertions, 0 deletions
diff --git a/patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch b/patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch
new file mode 100644
index 0000000..47f81de
--- /dev/null
+++ b/patches/remoteproc/0009-remoteproc-core-Allow-restarting-detached-remoteproc.patch
@@ -0,0 +1,349 @@
+At the moment, the remoteproc core supports only one auto boot "strategy":
+A remoteproc that is already running during boot ("detached") is attached,
+a remoteproc that is offline is started after loading the firmware. This
+works if the firmware loaded during boot is the same that we would start
+later, but it could also be outdated or a reduced size version that is
+missing some functionality. In this case, the best option is to try
+restarting it with new firmware - assuming that it is available while
+booting.
+
+Add support for this alternative behavior by replacing the "auto_boot" bool
+with a more explicit enum rproc_auto_boot.
+
+For RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE, try requesting the firmware
+early and - if successful - perform a clean stop of the remoteproc so that
+it can be restarted with the new firmware afterwards. A remoteproc driver
+making use of this functionality must handle the stop() callback being
+called during the initial detached state.
+
+Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
+---
+ drivers/remoteproc/imx_rproc.c | 8 +++--
+ drivers/remoteproc/ingenic_rproc.c | 5 ++-
+ drivers/remoteproc/pru_rproc.c | 2 +-
+ drivers/remoteproc/qcom_q6v5_adsp.c | 5 ++-
+ drivers/remoteproc/qcom_q6v5_mss.c | 2 +-
+ drivers/remoteproc/qcom_q6v5_pas.c | 5 ++-
+ drivers/remoteproc/rcar_rproc.c | 2 +-
+ drivers/remoteproc/remoteproc_core.c | 47 ++++++++++++++++++-------
+ drivers/remoteproc/stm32_rproc.c | 8 +++--
+ drivers/remoteproc/wkup_m3_rproc.c | 2 +-
+ drivers/remoteproc/xlnx_r5_remoteproc.c | 2 +-
+ include/linux/remoteproc.h | 23 +++++++++++-
+ 12 files changed, 85 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index 0dd80e688b0ea3..d5758207d155b6 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -1288,8 +1288,12 @@ static int imx_rproc_probe(struct platform_device *pdev)
+ return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to enable clock\n");
+ }
+
+- if (rproc->state != RPROC_DETACHED)
+- rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
++ if (rproc->state != RPROC_DETACHED) {
++ if (of_property_read_bool(np, "fsl,auto-boot"))
++ rproc->auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
++ else
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
++ }
+
+ if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) {
+ /*
+diff --git a/drivers/remoteproc/ingenic_rproc.c b/drivers/remoteproc/ingenic_rproc.c
+index 1b78d8ddeacfd5..351b9529713790 100644
+--- a/drivers/remoteproc/ingenic_rproc.c
++++ b/drivers/remoteproc/ingenic_rproc.c
+@@ -177,7 +177,10 @@ static int ingenic_rproc_probe(struct platform_device *pdev)
+ if (!rproc)
+ return -ENOMEM;
+
+- rproc->auto_boot = auto_boot;
++ if (auto_boot)
++ rproc->auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
++ else
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+
+ vpu = rproc->priv;
+ vpu->dev = &pdev->dev;
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index a4636c7bc6b7be..0928a75916f352 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -1029,7 +1029,7 @@ static int pru_rproc_probe(struct platform_device *pdev)
+ * remote-processor as part of its state machine either through the
+ * remoteproc sysfs interface or through the equivalent kernel API.
+ */
+- rproc->auto_boot = false;
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+
+ pru = rproc->priv;
+ pru->dev = dev;
+diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
+index b5c8d6d38c9cbc..7184f73be69105 100644
+--- a/drivers/remoteproc/qcom_q6v5_adsp.c
++++ b/drivers/remoteproc/qcom_q6v5_adsp.c
+@@ -673,7 +673,10 @@ static int adsp_probe(struct platform_device *pdev)
+ return -ENOMEM;
+ }
+
+- rproc->auto_boot = desc->auto_boot;
++ if (desc->auto_boot)
++ rproc->auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
++ else
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+ rproc->has_iommu = desc->has_iommu;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
+
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index ae78f5c7c1b69e..606896500ec310 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -2095,7 +2095,7 @@ static int q6v5_probe(struct platform_device *pdev)
+ return -ENOMEM;
+ }
+
+- rproc->auto_boot = false;
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
+
+ qproc = rproc->priv;
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index da27d1d3c9da64..1327e187514821 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -774,7 +774,10 @@ static int qcom_pas_probe(struct platform_device *pdev)
+ }
+
+ rproc->has_iommu = of_property_present(pdev->dev.of_node, "iommus");
+- rproc->auto_boot = desc->auto_boot;
++ if (desc->auto_boot)
++ rproc->auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
++ else
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
+
+ pas = rproc->priv;
+diff --git a/drivers/remoteproc/rcar_rproc.c b/drivers/remoteproc/rcar_rproc.c
+index 3c25625f966dcb..99a26a05165883 100644
+--- a/drivers/remoteproc/rcar_rproc.c
++++ b/drivers/remoteproc/rcar_rproc.c
+@@ -172,7 +172,7 @@ static int rcar_rproc_probe(struct platform_device *pdev)
+ dev_set_drvdata(dev, rproc);
+
+ /* Manually start the rproc */
+- rproc->auto_boot = false;
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+
+ ret = devm_rproc_add(dev, rproc);
+ if (ret) {
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index b087ed21858a8c..ec75659957033b 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -1683,7 +1683,8 @@ static int rproc_trigger_auto_boot(struct rproc *rproc)
+ {
+ int ret;
+
+- if (rproc->state == RPROC_DETACHED) {
++ if (rproc->state == RPROC_DETACHED &&
++ rproc->auto_boot != RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE) {
+ schedule_work(&rproc->attach_work);
+ return 0;
+ }
+@@ -1708,8 +1709,9 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
+ if (!rproc->ops->stop)
+ return -EINVAL;
+
+- /* Stop any subdevices for the remote processor */
+- rproc_stop_subdevices(rproc, crashed);
++ /* Stop any subdevices for the remote processor if it was attached */
++ if (rproc->state != RPROC_DETACHED)
++ rproc_stop_subdevices(rproc, crashed);
+
+ /* the installed resource table is no longer accessible */
+ ret = rproc_reset_rsc_table_on_stop(rproc);
+@@ -1726,7 +1728,8 @@ static int rproc_stop(struct rproc *rproc, bool crashed)
+ return ret;
+ }
+
+- rproc_unprepare_subdevices(rproc);
++ if (rproc->state != RPROC_DETACHED)
++ rproc_unprepare_subdevices(rproc);
+
+ rproc->state = RPROC_OFFLINE;
+
+@@ -1903,9 +1906,9 @@ static void rproc_crash_handler_work(struct work_struct *work)
+ */
+ int rproc_boot(struct rproc *rproc)
+ {
+- const struct firmware *firmware_p;
++ const struct firmware *firmware_p = NULL;
+ struct device *dev;
+- int ret;
++ int ret, fw_ret = 1;
+
+ if (!rproc) {
+ pr_err("invalid rproc handle\n");
+@@ -1932,6 +1935,19 @@ int rproc_boot(struct rproc *rproc)
+ goto unlock_mutex;
+ }
+
++ /* Check early if we have firmware avilable if needed */
++ if (rproc->auto_boot == RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE &&
++ rproc->state == RPROC_DETACHED) {
++ fw_ret = request_firmware(&firmware_p, rproc->firmware, dev);
++ if (fw_ret == 0) {
++ dev_info(dev, "restarting %s with new firmware\n", rproc->name);
++
++ ret = rproc_stop(rproc, false);
++ if (ret)
++ goto downref_rproc;
++ }
++ }
++
+ if (rproc->state == RPROC_DETACHED) {
+ dev_info(dev, "attaching to %s\n", rproc->name);
+
+@@ -1939,19 +1955,20 @@ int rproc_boot(struct rproc *rproc)
+ } else {
+ dev_info(dev, "powering up %s\n", rproc->name);
+
+- /* load firmware */
+- ret = request_firmware(&firmware_p, rproc->firmware, dev);
+- if (ret < 0) {
+- dev_err(dev, "request_firmware failed: %d\n", ret);
++ /* load firmware (if not already happened above) */
++ if (fw_ret == 1)
++ fw_ret = request_firmware(&firmware_p, rproc->firmware, dev);
++ if (fw_ret < 0) {
++ dev_err(dev, "request_firmware failed: %d\n", fw_ret);
++ ret = fw_ret;
+ goto downref_rproc;
+ }
+
+ ret = rproc_fw_boot(rproc, firmware_p);
+-
+- release_firmware(firmware_p);
+ }
+
+ downref_rproc:
++ release_firmware(firmware_p);
+ if (ret)
+ atomic_dec(&rproc->power);
+ unlock_mutex:
+@@ -2259,6 +2276,10 @@ static int rproc_validate(struct rproc *rproc)
+ return -EINVAL;
+ }
+
++ if (rproc->auto_boot == RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE &&
++ (!rproc->ops->stop || !rproc->ops->start || !rproc->ops->attach))
++ return -EINVAL;
++
+ return 0;
+ }
+
+@@ -2470,7 +2491,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
+ return NULL;
+
+ rproc->priv = &rproc[1];
+- rproc->auto_boot = true;
++ rproc->auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
+ rproc->elf_class = ELFCLASSNONE;
+ rproc->elf_machine = EM_NONE;
+
+diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
+index 632614013dc652..891fc17f8a63eb 100644
+--- a/drivers/remoteproc/stm32_rproc.c
++++ b/drivers/remoteproc/stm32_rproc.c
+@@ -696,7 +696,8 @@ static int stm32_rproc_get_syscon(struct device_node *np, const char *prop,
+ }
+
+ static int stm32_rproc_parse_dt(struct platform_device *pdev,
+- struct stm32_rproc *ddata, bool *auto_boot)
++ struct stm32_rproc *ddata,
++ enum rproc_auto_boot *auto_boot)
+ {
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+@@ -777,7 +778,10 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
+ if (err)
+ dev_info(dev, "failed to get pdds\n");
+
+- *auto_boot = of_property_read_bool(np, "st,auto-boot");
++ if (of_property_read_bool(np, "st,auto-boot"))
++ *auto_boot = RPROC_AUTO_BOOT_ATTACH_OR_START;
++ else
++ *auto_boot = RPROC_AUTO_BOOT_DISABLED;
+
+ /*
+ * See if we can check the M4 status, i.e if it was started
+diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c
+index 2d5bfbefcacc5b..8815648295c892 100644
+--- a/drivers/remoteproc/wkup_m3_rproc.c
++++ b/drivers/remoteproc/wkup_m3_rproc.c
+@@ -170,7 +170,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
+ if (!rproc)
+ return -ENOMEM;
+
+- rproc->auto_boot = false;
++ rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+ rproc->sysfs_read_only = true;
+
+ wkupm3 = rproc->priv;
+diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
+index 50a9974f3202e6..4e230838a24abd 100644
+--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
++++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
+@@ -931,7 +931,7 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
+
+ r5_rproc->recovery_disabled = true;
+ r5_rproc->has_iommu = false;
+- r5_rproc->auto_boot = false;
++ r5_rproc->auto_boot = RPROC_AUTO_BOOT_DISABLED;
+
+ /* attempt to boot automatically if the firmware-name is provided */
+ if (fw_name)
+diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
+index b4795698d8c2a4..c40b18d120ab46 100644
+--- a/include/linux/remoteproc.h
++++ b/include/linux/remoteproc.h
+@@ -503,6 +503,27 @@ enum rproc_features {
+ RPROC_MAX_FEATURES,
+ };
+
++/**
++ * enum rproc_auto_boot - auto boot strategy for remoteproc during initial boot
++ *
++ * @RPROC_AUTO_BOOT_DISABLED: The remoteproc will be left offline (or detached).
++ * @RPROC_AUTO_BOOT_ATTACH_OR_START: The remoteproc will be attached (if it is
++ * already running). Otherwise, it will be
++ * started with new loaded firmware.
++ * @RPROC_FEAT_REBOOT_IF_FW_AVAILABLE: The remoteproc will be restarted if
++ * requesting new firmware succeeds. If
++ * the firmware is missing and the
++ * remoteproc is already running, it will
++ * be attached instead. A remoteproc
++ * implementing this must handle stop()
++ * being called in detached state.
++ */
++enum rproc_auto_boot {
++ RPROC_AUTO_BOOT_DISABLED,
++ RPROC_AUTO_BOOT_ATTACH_OR_START,
++ RPROC_AUTO_BOOT_RESTART_IF_FW_AVAILABLE,
++};
++
+ /**
+ * struct rproc - represents a physical remote processor device
+ * @node: list node of this rproc object
+@@ -577,7 +598,7 @@ struct rproc {
+ struct resource_table *cached_table;
+ size_t table_sz;
+ bool has_iommu;
+- bool auto_boot;
++ enum rproc_auto_boot auto_boot;
+ bool sysfs_read_only;
+ struct list_head dump_segments;
+ int nb_vdev;