meta-digi/meta-digi-arm/recipes-kernel/linux/linux-dey/ccmp1/0002-remoteproc-stm32_rproc...

218 lines
7.1 KiB
Diff

From: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
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 <arnaud.pouliquen@foss.st.com>
---
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;