From: Arnaud Pouliquen Date: Wed, 7 Jan 2026 14:56:36 +0100 Subject: [PATCH] remoteproc: stm32_rproc: make reset and hold boot optional As specified in the bindings, the "mcu_rst" and "hold_boot" resets are optional. They are needed only in the following topologies: - stm32mp15: when the device tree defines the compatible "st,stm32mp1-m4" - stm32mp2x A35 cold boot: when the device tree defines the compatible "st,stm32mp2-m33" This commit splits the management of the "mcu_rst" and "hold_boot" resets per series: - Migrates reset management code from stm32_rproc_parse_dt() to the stm32_rproc_get_m4_reset() function - Creates `stm32_rproc_get_m33_reset()` function to manage M33 resets - No legacy property support needed - "mcu_rst" and "hold_boot" are optional Additionally, the get_reset() ops is called only for "st,stm32mp2-m33" or "st,stm32mp2-m4" compatibles, when `ddata->trproc` is NULL. https://onedigi.atlassian.net/browse/DEL-9920 Change-Id: Iddf5c28882eac4e051fec10367439f5991cdcaf1 Signed-off-by: Arnaud Pouliquen --- drivers/remoteproc/stm32_rproc.c | 129 ++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 47 deletions(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index d21f22164814..46390045a63d 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -83,6 +83,7 @@ struct stm32_rproc_mem { struct stm32_rproc_data { int proc_id; int (*get_info)(struct rproc *rproc); + int (*get_reset)(struct rproc *rproc); }; struct stm32_mbox { @@ -997,24 +998,6 @@ static int stm32_rproc_get_m33_info(struct rproc *rproc) return 0; } -static const struct stm32_rproc_data stm32_rproc_stm32pm15 = { - .proc_id = STM32_MP1_M4_PROC_ID, - .get_info = stm32_rproc_get_m4_info, -}; - -static const struct stm32_rproc_data stm32_rproc_stm32pm25 = { - .proc_id = STM32_MP2_M33_PROC_ID, - .get_info = stm32_rproc_get_m33_info, -}; - -static const struct of_device_id stm32_rproc_match[] = { - {.compatible = "st,stm32mp1-m4", .data = &stm32_rproc_stm32pm15}, - {.compatible = "st,stm32mp1-m4-tee", .data = &stm32_rproc_stm32pm15}, - {.compatible = "st,stm32mp2-m33", .data = &stm32_rproc_stm32pm25}, - {.compatible = "st,stm32mp2-m33-tee", .data = &stm32_rproc_stm32pm25}, - {}, -}; -MODULE_DEVICE_TABLE(of, stm32_rproc_match); static int stm32_rproc_get_syscon(struct device_node *np, const char *prop, struct stm32_syscon *syscon) @@ -1038,42 +1021,29 @@ static int stm32_rproc_get_syscon(struct device_node *np, const char *prop, return err; } -static int stm32_rproc_parse_dt(struct platform_device *pdev, - struct stm32_rproc *ddata, bool *auto_boot) +static int stm32_rproc_get_m4_reset(struct rproc *rproc) { - struct device *dev = &pdev->dev; + struct stm32_rproc *ddata = rproc->priv; + struct device *dev = rproc->dev.parent; struct device_node *np = dev->of_node; struct stm32_syscon tz; unsigned int tzen; - int err, irq; - - irq = platform_get_irq(pdev, 0); - if (irq == -EPROBE_DEFER) - return dev_err_probe(dev, irq, "failed to get interrupt\n"); - - if (irq > 0) { - err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0, - dev_name(dev), pdev); - if (err) - return dev_err_probe(dev, err, - "failed to request wdg irq\n"); - - ddata->wdg_irq = irq; - - if (of_property_read_bool(np, "wakeup-source")) - ddata->wdg_wake_up = 1; - - dev_info(dev, "wdg irq registered\n"); - } + int err = 0; ddata->rst = devm_reset_control_get_optional(dev, "mcu_rst"); if (!ddata->rst) { /* Try legacy fallback method: get it by index */ ddata->rst = devm_reset_control_get_by_index(dev, 0); } - if (IS_ERR(ddata->rst)) - return dev_err_probe(dev, PTR_ERR(ddata->rst), - "failed to get mcu_reset\n"); + if (IS_ERR(ddata->rst)) { + if (PTR_ERR(ddata->rst) != -ENOENT) + return dev_err_probe(dev, PTR_ERR(ddata->rst), + "failed to get mcu_reset\n"); + ddata->rst = NULL; + } + + if (!ddata->rst) + return 0; /* * Three ways to manage the hold boot @@ -1085,11 +1055,10 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev, * - default(no SCMI, no SMC): the hold boot is managed as a syscon register * The DT "reset-mames" property is optional, "st,syscfg-holdboot" is required */ - ddata->hold_boot_rst = devm_reset_control_get_optional(dev, "hold_boot"); if (IS_ERR(ddata->hold_boot_rst)) return dev_err_probe(dev, PTR_ERR(ddata->hold_boot_rst), - "failed to get hold_boot reset\n"); + "failed to get hold_boot reset\n"); if (!ddata->hold_boot_rst && IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)) { /* Manage the MCU_BOOT using SMC call */ @@ -1108,6 +1077,72 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev, /* Default: hold boot manage it through the syscon controller */ err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot", &ddata->hold_boot); + } + + return err; +} + +static int stm32_rproc_get_m33_reset(struct rproc *rproc) +{ + struct stm32_rproc *ddata = rproc->priv; + struct device *dev = rproc->dev.parent; + + ddata->rst = devm_reset_control_get_optional(dev, "mcu_rst"); + ddata->hold_boot_rst = devm_reset_control_get_optional(dev, "hold_boot"); + + return 0; +} + +static const struct stm32_rproc_data stm32_rproc_stm32pm15 = { + .proc_id = STM32_MP1_M4_PROC_ID, + .get_info = stm32_rproc_get_m4_info, + .get_reset = stm32_rproc_get_m4_reset, +}; + +static const struct stm32_rproc_data stm32_rproc_stm32pm25 = { + .proc_id = STM32_MP2_M33_PROC_ID, + .get_info = stm32_rproc_get_m33_info, + .get_reset = stm32_rproc_get_m33_reset, +}; + +static const struct of_device_id stm32_rproc_match[] = { + {.compatible = "st,stm32mp1-m4", .data = &stm32_rproc_stm32pm15}, + {.compatible = "st,stm32mp1-m4-tee", .data = &stm32_rproc_stm32pm15}, + {.compatible = "st,stm32mp2-m33", .data = &stm32_rproc_stm32pm25}, + {.compatible = "st,stm32mp2-m33-tee", .data = &stm32_rproc_stm32pm25}, + {}, +}; +MODULE_DEVICE_TABLE(of, stm32_rproc_match); + +static int stm32_rproc_parse_dt(struct platform_device *pdev, + struct rproc *rproc, bool *auto_boot) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct stm32_rproc *ddata = rproc->priv; + int err, irq; + + irq = platform_get_irq(pdev, 0); + if (irq == -EPROBE_DEFER) + return dev_err_probe(dev, irq, "failed to get interrupt\n"); + + if (irq > 0) { + err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0, + dev_name(dev), pdev); + if (err) + return dev_err_probe(dev, err, + "failed to request wdg irq\n"); + + ddata->wdg_irq = irq; + + if (of_property_read_bool(np, "wakeup-source")) + ddata->wdg_wake_up = 1; + + dev_info(dev, "wdg irq registered\n"); + } + + if (!ddata->trproc) { + err = ddata->desc->get_reset(rproc); if (err) { dev_err(dev, "failed to get hold boot\n"); return err; @@ -1231,7 +1266,7 @@ static int stm32_rproc_probe(struct platform_device *pdev) ddata->desc = desc; ddata->trproc = trproc; - ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot); + ret = stm32_rproc_parse_dt(pdev, rproc, &rproc->auto_boot); if (ret) goto free_rproc;