maxItems: 3
resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: mcu_rst
+ - const: hold_boot
+ minItems: 1
st,syscfg-holdboot:
description: remote processor reset hold boot
- description: The field mask of the hold boot
st,syscfg-tz:
+ deprecated: true
description:
Reference to the system configuration which holds the RCC trust zone mode
$ref: /schemas/types.yaml#/definitions/phandle-array
- compatible
- reg
- resets
- - st,syscfg-holdboot
- - st,syscfg-tz
+
+allOf:
+ - if:
+ properties:
+ reset-names:
+ not:
+ contains:
+ const: hold_boot
+ then:
+ required:
+ - st,syscfg-holdboot
+ else:
+ properties:
+ st,syscfg-holdboot: false
additionalProperties: false
examples:
- |
#include <dt-bindings/reset/stm32mp1-resets.h>
- m4_rproc: m4@10000000 {
+ m4@10000000 {
compatible = "st,stm32mp1-m4";
reg = <0x10000000 0x40000>,
<0x30000000 0x40000>,
<0x38000000 0x10000>;
resets = <&rcc MCU_R>;
+ reset-names = "mcu_rst";
+ /* Hold boot managed using system config*/
st,syscfg-holdboot = <&rcc 0x10C 0x1>;
- st,syscfg-tz = <&rcc 0x000 0x1>;
+ st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
+ st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
+ };
+ - |
+ #include <dt-bindings/reset/stm32mp1-resets.h>
+ m4@10000000 {
+ compatible = "st,stm32mp1-m4";
+ reg = <0x10000000 0x40000>,
+ <0x30000000 0x40000>,
+ <0x38000000 0x10000>;
+ /* Hold boot managed using SCMI reset controller */
+ resets = <&scmi MCU_R>, <&scmi MCU_HOLD_BOOT_R>;
+ reset-names = "mcu_rst", "hold_boot";
st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
};
return ret;
}
-static int da8xx_rproc_remove(struct platform_device *pdev)
+static void da8xx_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct da8xx_rproc *drproc = rproc->priv;
rproc_free(rproc);
if (dev->of_node)
of_reserved_mem_device_release(dev);
-
- return 0;
}
static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = {
static struct platform_driver da8xx_rproc_driver = {
.probe = da8xx_rproc_probe,
- .remove = da8xx_rproc_remove,
+ .remove_new = da8xx_rproc_remove,
.driver = {
.name = "davinci-rproc",
.of_match_table = of_match_ptr(davinci_rproc_of_match),
return ret;
}
-static int imx_dsp_rproc_remove(struct platform_device *pdev)
+static void imx_dsp_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct imx_dsp_rproc *priv = rproc->priv;
rproc_del(rproc);
imx_dsp_detach_pm_domains(priv);
rproc_free(rproc);
-
- return 0;
}
/* pm runtime functions */
release_firmware(fw);
}
-static __maybe_unused int imx_dsp_suspend(struct device *dev)
+static int imx_dsp_suspend(struct device *dev)
{
struct rproc *rproc = dev_get_drvdata(dev);
struct imx_dsp_rproc *priv = rproc->priv;
return pm_runtime_force_suspend(dev);
}
-static __maybe_unused int imx_dsp_resume(struct device *dev)
+static int imx_dsp_resume(struct device *dev)
{
struct rproc *rproc = dev_get_drvdata(dev);
int ret = 0;
}
static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
- SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
- imx_dsp_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
+ RUNTIME_PM_OPS(imx_dsp_runtime_suspend, imx_dsp_runtime_resume, NULL)
};
static const struct of_device_id imx_dsp_rproc_of_match[] = {
static struct platform_driver imx_dsp_rproc_driver = {
.probe = imx_dsp_rproc_probe,
- .remove = imx_dsp_rproc_remove,
+ .remove_new = imx_dsp_rproc_remove,
.driver = {
.name = "imx-dsp-rproc",
.of_match_table = imx_dsp_rproc_of_match,
- .pm = &imx_dsp_rproc_pm_ops,
+ .pm = pm_ptr(&imx_dsp_rproc_pm_ops),
},
};
module_platform_driver(imx_dsp_rproc_driver);
return ret;
}
-static int imx_rproc_remove(struct platform_device *pdev)
+static void imx_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct imx_rproc *priv = rproc->priv;
imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue);
rproc_free(rproc);
-
- return 0;
}
static const struct of_device_id imx_rproc_of_match[] = {
static struct platform_driver imx_rproc_driver = {
.probe = imx_rproc_probe,
- .remove = imx_rproc_remove,
+ .remove_new = imx_rproc_remove,
.driver = {
.name = "imx-rproc",
.of_match_table = imx_rproc_of_match,
return ret;
}
-static int keystone_rproc_remove(struct platform_device *pdev)
+static void keystone_rproc_remove(struct platform_device *pdev)
{
struct keystone_rproc *ksproc = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
rproc_free(ksproc->rproc);
of_reserved_mem_device_release(&pdev->dev);
-
- return 0;
}
static const struct of_device_id keystone_rproc_of_match[] = {
static struct platform_driver keystone_rproc_driver = {
.probe = keystone_rproc_probe,
- .remove = keystone_rproc_remove,
+ .remove_new = keystone_rproc_remove,
.driver = {
.name = "keystone-rproc",
.of_match_table = keystone_rproc_of_match,
return ret;
}
-static int meson_mx_ao_arc_rproc_remove(struct platform_device *pdev)
+static void meson_mx_ao_arc_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct meson_mx_ao_arc_rproc_priv *priv = rproc->priv;
rproc_del(rproc);
gen_pool_free(priv->sram_pool, priv->sram_va, priv->sram_size);
-
- return 0;
}
static const struct of_device_id meson_mx_ao_arc_rproc_match[] = {
static struct platform_driver meson_mx_ao_arc_rproc_driver = {
.probe = meson_mx_ao_arc_rproc_probe,
- .remove = meson_mx_ao_arc_rproc_remove,
+ .remove_new = meson_mx_ao_arc_rproc_remove,
.driver = {
.name = "meson-mx-ao-arc-rproc",
.of_match_table = meson_mx_ao_arc_rproc_match,
return ret;
}
-static int scp_remove(struct platform_device *pdev)
+static void scp_remove(struct platform_device *pdev)
{
struct mtk_scp *scp = platform_get_drvdata(pdev);
int i;
for (i = 0; i < SCP_IPI_MAX; i++)
mutex_destroy(&scp->ipi_desc[i].lock);
mutex_destroy(&scp->send_lock);
-
- return 0;
}
static const struct mtk_scp_of_data mt8183_of_data = {
static struct platform_driver mtk_scp_driver = {
.probe = scp_probe,
- .remove = scp_remove,
+ .remove_new = scp_remove,
.driver = {
.name = "mtk-scp",
.of_match_table = mtk_scp_of_match,
return ret;
}
-static int omap_rproc_remove(struct platform_device *pdev)
+static void omap_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
rproc_del(rproc);
rproc_free(rproc);
of_reserved_mem_device_release(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops omap_rproc_pm_ops = {
static struct platform_driver omap_rproc_driver = {
.probe = omap_rproc_probe,
- .remove = omap_rproc_remove,
+ .remove_new = omap_rproc_remove,
.driver = {
.name = "omap-rproc",
.pm = &omap_rproc_pm_ops,
return 0;
}
-static int pru_rproc_remove(struct platform_device *pdev)
+static void pru_rproc_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rproc *rproc = platform_get_drvdata(pdev);
dev_dbg(dev, "%s: removing rproc %s\n", __func__, rproc->name);
-
- return 0;
}
static const struct pru_private_data pru_data = {
.suppress_bind_attrs = true,
},
.probe = pru_rproc_probe,
- .remove = pru_rproc_remove,
+ .remove_new = pru_rproc_remove,
};
module_platform_driver(pru_rproc_driver);
return ret;
}
-static int adsp_remove(struct platform_device *pdev)
+static void adsp_remove(struct platform_device *pdev)
{
struct qcom_adsp *adsp = platform_get_drvdata(pdev);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
rproc_free(adsp->rproc);
-
- return 0;
}
static const struct adsp_pil_data adsp_resource_init = {
static struct platform_driver adsp_pil_driver = {
.probe = adsp_probe,
- .remove = adsp_remove,
+ .remove_new = adsp_remove,
.driver = {
.name = "qcom_q6v5_adsp",
.of_match_table = adsp_of_match,
return ret;
}
-static int q6v5_remove(struct platform_device *pdev)
+static void q6v5_remove(struct platform_device *pdev)
{
struct q6v5 *qproc = platform_get_drvdata(pdev);
struct rproc *rproc = qproc->rproc;
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
rproc_free(rproc);
-
- return 0;
}
static const struct rproc_hexagon_res sc7180_mss = {
static struct platform_driver q6v5_driver = {
.probe = q6v5_probe,
- .remove = q6v5_remove,
+ .remove_new = q6v5_remove,
.driver = {
.name = "qcom-q6v5-mss",
.of_match_table = q6v5_of_match,
struct qcom_scm_pas_metadata dtb_pas_metadata;
};
-void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
+static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
void *dest, size_t offset, size_t size)
{
struct qcom_adsp *adsp = rproc->priv;
return ret;
}
-static int adsp_remove(struct platform_device *pdev)
+static void adsp_remove(struct platform_device *pdev)
{
struct qcom_adsp *adsp = platform_get_drvdata(pdev);
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
device_init_wakeup(adsp->dev, false);
rproc_free(adsp->rproc);
-
- return 0;
}
static const struct adsp_data adsp_resource_init = {
static struct platform_driver adsp_driver = {
.probe = adsp_probe,
- .remove = adsp_remove,
+ .remove_new = adsp_remove,
.driver = {
.name = "qcom_q6v5_pas",
.of_match_table = adsp_of_match,
return ret;
}
-static int q6v5_wcss_remove(struct platform_device *pdev)
+static void q6v5_wcss_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct q6v5_wcss *wcss = rproc->priv;
qcom_q6v5_deinit(&wcss->q6v5);
rproc_del(rproc);
rproc_free(rproc);
-
- return 0;
}
static const struct wcss_data wcss_ipq8074_res_init = {
static struct platform_driver q6v5_wcss_driver = {
.probe = q6v5_wcss_probe,
- .remove = q6v5_wcss_remove,
+ .remove_new = q6v5_wcss_remove,
.driver = {
.name = "qcom-q6v5-wcss-pil",
.of_match_table = q6v5_wcss_of_match,
return ret;
}
-static int wcnss_remove(struct platform_device *pdev)
+static void wcnss_remove(struct platform_device *pdev)
{
struct qcom_wcnss *wcnss = platform_get_drvdata(pdev);
qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev);
wcnss_release_pds(wcnss);
rproc_free(wcnss->rproc);
-
- return 0;
}
static const struct of_device_id wcnss_of_match[] = {
static struct platform_driver wcnss_driver = {
.probe = wcnss_probe,
- .remove = wcnss_remove,
+ .remove_new = wcnss_remove,
.driver = {
.name = "qcom-wcnss-pil",
.of_match_table = wcnss_of_match,
return ret;
}
-static int rcar_rproc_remove(struct platform_device *pdev)
+static void rcar_rproc_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
pm_runtime_disable(dev);
-
- return 0;
}
static const struct of_device_id rcar_rproc_of_match[] = {
static struct platform_driver rcar_rproc_driver = {
.probe = rcar_rproc_probe,
- .remove = rcar_rproc_remove,
+ .remove_new = rcar_rproc_remove,
.driver = {
.name = "rcar-rproc",
.of_match_table = rcar_rproc_of_match,
return ret;
}
-static int rproc_virtio_remove(struct platform_device *pdev)
+static void rproc_virtio_remove(struct platform_device *pdev)
{
struct rproc_vdev *rvdev = dev_get_drvdata(&pdev->dev);
struct rproc *rproc = rvdev->rproc;
dma_release_coherent_memory(&pdev->dev);
put_device(&rproc->dev);
-
- return 0;
}
/* Platform driver */
static struct platform_driver rproc_virtio_driver = {
.probe = rproc_virtio_probe,
- .remove = rproc_virtio_remove,
+ .remove_new = rproc_virtio_remove,
.driver = {
.name = "rproc-virtio",
},
return ret;
}
-static int st_rproc_remove(struct platform_device *pdev)
+static void st_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct st_rproc *ddata = rproc->priv;
mbox_free_channel(ddata->mbox_chan[i]);
rproc_free(rproc);
-
- return 0;
}
static struct platform_driver st_rproc_driver = {
.probe = st_rproc_probe,
- .remove = st_rproc_remove,
+ .remove_new = st_rproc_remove,
.driver = {
.name = "st-rproc",
.of_match_table = of_match_ptr(st_rproc_match),
struct stm32_rproc {
struct reset_control *rst;
+ struct reset_control *hold_boot_rst;
struct stm32_syscon hold_boot;
struct stm32_syscon pdds;
struct stm32_syscon m4_state;
struct stm32_rproc_mem *rmems;
struct stm32_mbox mb[MBOX_NB_MBX];
struct workqueue_struct *workqueue;
- bool secured_soc;
+ bool hold_boot_smc;
void __iomem *rsc_va;
};
struct arm_smccc_res smc_res;
int val, err;
+ /*
+ * Three ways to manage the hold boot
+ * - using SCMI: the hold boot is managed as a reset,
+ * - using Linux(no SCMI): the hold boot is managed as a syscon register
+ * - using SMC call (deprecated): use SMC reset interface
+ */
+
val = hold ? HOLD_BOOT : RELEASE_BOOT;
- if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ddata->secured_soc) {
+ if (ddata->hold_boot_rst) {
+ /* Use the SCMI reset controller */
+ if (!hold)
+ err = reset_control_deassert(ddata->hold_boot_rst);
+ else
+ err = reset_control_assert(ddata->hold_boot_rst);
+ } else if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ddata->hold_boot_smc) {
+ /* Use the SMC call */
arm_smccc_smc(STM32_SMC_RCC, STM32_SMC_REG_WRITE,
hold_boot.reg, val, 0, 0, 0, 0, &smc_res);
err = smc_res.a0;
} else {
+ /* Use syscon */
err = regmap_update_bits(hold_boot.map, hold_boot.reg,
hold_boot.mask, val);
}
dev_info(dev, "wdg irq registered\n");
}
- ddata->rst = devm_reset_control_get_by_index(dev, 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 platform is secured the hold boot bit must be written by
- * smc call and read normally.
- * if not secure the hold boot bit could be read/write normally
+ * Three ways to manage the hold boot
+ * - using SCMI: the hold boot is managed as a reset
+ * The DT "reset-mames" property should be defined with 2 items:
+ * reset-names = "mcu_rst", "hold_boot";
+ * - using SMC call (deprecated): use SMC reset interface
+ * The DT "reset-mames" property is optional, "st,syscfg-tz" is required
+ * - 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
*/
- err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz);
- if (err) {
- dev_err(dev, "failed to get tz syscfg\n");
- return err;
- }
- err = regmap_read(tz.map, tz.reg, &tzen);
- if (err) {
- dev_err(dev, "failed to read tzen\n");
- return err;
+ 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");
+
+ if (!ddata->hold_boot_rst && IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)) {
+ /* Manage the MCU_BOOT using SMC call */
+ err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz);
+ if (!err) {
+ err = regmap_read(tz.map, tz.reg, &tzen);
+ if (err) {
+ dev_err(dev, "failed to read tzen\n");
+ return err;
+ }
+ ddata->hold_boot_smc = tzen & tz.mask;
+ }
}
- ddata->secured_soc = tzen & tz.mask;
- err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot",
- &ddata->hold_boot);
- if (err) {
- dev_err(dev, "failed to get hold boot\n");
- return err;
+ if (!ddata->hold_boot_rst && !ddata->hold_boot_smc) {
+ /* Default: hold boot manage it through the syscon controller */
+ err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot",
+ &ddata->hold_boot);
+ if (err) {
+ dev_err(dev, "failed to get hold boot\n");
+ return err;
+ }
}
err = stm32_rproc_get_syscon(np, "st,syscfg-pdds", &ddata->pdds);
return ret;
}
-static int stm32_rproc_remove(struct platform_device *pdev)
+static void stm32_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct stm32_rproc *ddata = rproc->priv;
device_init_wakeup(dev, false);
}
rproc_free(rproc);
-
- return 0;
}
static int __maybe_unused stm32_rproc_suspend(struct device *dev)
static struct platform_driver stm32_rproc_driver = {
.probe = stm32_rproc_probe,
- .remove = stm32_rproc_remove,
+ .remove_new = stm32_rproc_remove,
.driver = {
.name = "stm32-rproc",
.pm = &stm32_rproc_pm_ops,
return ret;
}
-static int wkup_m3_rproc_remove(struct platform_device *pdev)
+static void wkup_m3_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
rproc_free(rproc);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM
static struct platform_driver wkup_m3_rproc_driver = {
.probe = wkup_m3_rproc_probe,
- .remove = wkup_m3_rproc_remove,
+ .remove_new = wkup_m3_rproc_remove,
.driver = {
.name = "wkup_m3_rproc",
.of_match_table = wkup_m3_rproc_of_match,