On Di, 2025-01-21 at 14:49 +0800, Friday Yang wrote: > From: "friday.yang" <friday.yang@xxxxxxxxxxxx> > > To prevent handling glitch signals during MTCMOS on/off transitions, > SMI requires clamp and reset operations. Parse the reset settings for > SMI LARBs and the clamp settings for the SMI Sub-Common. Register > genpd callback for the SMI LARBs located in image, camera and IPE > subsystems, and apply reset and clamp operations within the callback. > > Signed-off-by: Friday Yang <friday.yang@xxxxxxxxxxxx> > --- > drivers/memory/mtk-smi.c | 141 +++++++++++++++++++++++++++++++++++++-- > 1 file changed, 137 insertions(+), 4 deletions(-) > > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c > index 5710348f72f6..aaeb80379ec1 100644 > --- a/drivers/memory/mtk-smi.c > +++ b/drivers/memory/mtk-smi.c [...] > @@ -528,6 +598,53 @@ static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi, > return ret; > } > > +static int mtk_smi_larb_parse_clamp_optional(struct mtk_smi_larb *larb) > +{ > + struct device *dev = larb->dev; > + const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen; > + u32 larb_id; > + int ret; > + > + /** > + * Only SMI LARBs in camera, image and IPE subsys need to > + * apply clamp and reset operations, others can be skipped. > + */ > + ret = of_property_read_u32(dev->of_node, "mediatek,larb-id", &larb_id); > + if (ret) > + return -EINVAL; > + if (!larb_gen->clamp_port || !larb_gen->clamp_port[larb_id]) > + return 0; > + > + larb->sub_comm_inport = larb_gen->clamp_port[larb_id]; > + larb->sub_comm_syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "mediatek,smi"); > + if (IS_ERR(larb->sub_comm_syscon)) { > + larb->sub_comm_syscon = NULL; > + return dev_err_probe(dev, -EINVAL, > + "Unknown clamp port for larb %d\n", larb_id); > + } > + > + return 0; > +} > + > +static int mtk_smi_larb_parse_reset_optional(struct mtk_smi_larb *larb) > +{ > + struct device *dev = larb->dev; > + int ret; > + > + larb->rst_con = devm_reset_control_get(dev, "larb"); Please use devm_reset_control_get_exclusive() directly. Or use devm_reset_control_get_optional_exclusive(), which returns NULL instead of -ENOENT. That way you can ... > + if (IS_ERR(larb->rst_con)) > + return dev_err_probe(dev, PTR_ERR(larb->rst_con), > + "Failed to get larb reset controller\n"); ... suppress this error message in case of -ENOENT and return with: if (!larb->rst_con) return 0; here. > + > + larb->nb.notifier_call = mtk_smi_genpd_callback; > + ret = dev_pm_genpd_add_notifier(dev, &larb->nb); > + if (ret) > + return dev_err_probe(dev, -EINVAL, > + "Failed to add genpd callback %d\n", ret); > + > + return 0; > +} > + > static int mtk_smi_larb_probe(struct platform_device *pdev) > { > struct mtk_smi_larb *larb; > @@ -538,6 +655,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) > if (!larb) > return -ENOMEM; > > + larb->dev = dev; > larb->larb_gen = of_device_get_match_data(dev); > larb->base = devm_platform_ioremap_resource(pdev, 0); > if (IS_ERR(larb->base)) > @@ -554,15 +672,24 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) > if (ret < 0) > return ret; > > - pm_runtime_enable(dev); > + ret = mtk_smi_larb_parse_clamp_optional(larb); > + if (ret) > + goto err_link_remove; > + > + ret = mtk_smi_larb_parse_reset_optional(larb); > + if (ret && ret != -ENOENT) The ret != -ENOENT check could be dropped if you use devm_reset_control_get_optional_exclusive() above. regards Philipp