Hi Thomas, On Fri Jun 20, 2025 at 1:02 PM CEST, Thomas Zimmermann wrote: > Hi > > Am 20.06.25 um 12:31 schrieb Luca Weiss: >> Some devices might require keeping an interconnect path alive so that >> the framebuffer continues working. Add support for that by setting the >> bandwidth requirements appropriately for all provided interconnect >> paths. >> >> Signed-off-by: Luca Weiss <luca.we...@fairphone.com> >> --- >> drivers/video/fbdev/simplefb.c | 83 >> ++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 83 insertions(+) >> >> diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c >> index >> be95fcddce4c8ca794826b805cd7dad2985bd637..ca73e079fd13550ddc779e84db80f7f9b743d074 >> 100644 >> --- a/drivers/video/fbdev/simplefb.c >> +++ b/drivers/video/fbdev/simplefb.c >> @@ -27,6 +27,7 @@ >> #include <linux/parser.h> >> #include <linux/pm_domain.h> >> #include <linux/regulator/consumer.h> >> +#include <linux/interconnect.h> > > With alphabetical sorting: > > Reviewed-by: Thomas Zimmermann <tzimmerm...@suse.de>
Thanks for the reviews! For both simpledrm.c and simplefb.c, the includes are not strictly alphabetically sorted (1 mis-sort in simpledrm, 3 in simplefb), shall I just try and slot it into the best fitting place, or make them sorted in my patch? Or I can add a separate commit for each driver before to sort them. Let me know! Regards Luca > > Best regards > Thomas > > >> >> static const struct fb_fix_screeninfo simplefb_fix = { >> .id = "simple", >> @@ -89,6 +90,10 @@ struct simplefb_par { >> u32 regulator_count; >> struct regulator **regulators; >> #endif >> +#if defined CONFIG_OF && defined CONFIG_INTERCONNECT >> + unsigned int icc_count; >> + struct icc_path **icc_paths; >> +#endif >> }; >> >> static void simplefb_clocks_destroy(struct simplefb_par *par); >> @@ -525,6 +530,80 @@ static int simplefb_attach_genpds(struct simplefb_par >> *par, >> } >> #endif >> >> +#if defined CONFIG_OF && defined CONFIG_PM_GENERIC_DOMAINS >> +/* >> + * Generic interconnect path handling code. >> + */ >> +static void simplefb_detach_icc(void *res) >> +{ >> + struct simplefb_par *par = res; >> + int i; >> + >> + for (i = par->icc_count - 1; i >= 0; i--) { >> + if (!IS_ERR_OR_NULL(par->icc_paths[i])) >> + icc_put(par->icc_paths[i]); >> + } >> +} >> + >> +static int simplefb_attach_icc(struct simplefb_par *par, >> + struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + int ret, count, i; >> + >> + count = of_count_phandle_with_args(dev->of_node, "interconnects", >> + "#interconnect-cells"); >> + if (count < 0) >> + return 0; >> + >> + /* An interconnect path consists of two elements */ >> + if (count % 2) { >> + dev_err(dev, "invalid interconnects value\n"); >> + return -EINVAL; >> + } >> + par->icc_count = count / 2; >> + >> + par->icc_paths = devm_kcalloc(dev, par->icc_count, >> + sizeof(*par->icc_paths), >> + GFP_KERNEL); >> + if (!par->icc_paths) >> + return -ENOMEM; >> + >> + for (i = 0; i < par->icc_count; i++) { >> + par->icc_paths[i] = of_icc_get_by_index(dev, i); >> + if (IS_ERR_OR_NULL(par->icc_paths[i])) { >> + ret = PTR_ERR(par->icc_paths[i]); >> + if (ret == -EPROBE_DEFER) >> + goto err; >> + dev_err(dev, "failed to get interconnect path %u: >> %d\n", i, ret); >> + continue; >> + } >> + >> + ret = icc_set_bw(par->icc_paths[i], 0, UINT_MAX); >> + if (ret) { >> + dev_err(dev, "failed to set interconnect bandwidth %u: >> %d\n", i, ret); >> + continue; >> + } >> + } >> + >> + return devm_add_action_or_reset(dev, simplefb_detach_icc, par); >> + >> +err: >> + while (i) { >> + --i; >> + if (!IS_ERR_OR_NULL(par->icc_paths[i])) >> + icc_put(par->icc_paths[i]); >> + } >> + return ret; >> +} >> +#else >> +static int simplefb_attach_icc(struct simplefb_par *par, >> + struct platform_device *pdev) >> +{ >> + return 0; >> +} >> +#endif >> + >> static int simplefb_probe(struct platform_device *pdev) >> { >> int ret; >> @@ -615,6 +694,10 @@ static int simplefb_probe(struct platform_device *pdev) >> if (ret < 0) >> goto error_regulators; >> >> + ret = simplefb_attach_icc(par, pdev); >> + if (ret < 0) >> + goto error_regulators; >> + >> simplefb_clocks_enable(par, pdev); >> simplefb_regulators_enable(par, pdev); >> >>