218 lines
7.1 KiB
Diff
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;
|
|
|