summaryrefslogtreecommitdiff
path: root/drivers/pmdomain
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2024-04-15 19:00:23 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-06-21 14:38:44 +0200
commita3be677629e4e0d246284956ff422392fafd715f (patch)
tree1d77f0e0d96b1ba5e36454c1a007dadb129b1ea5 /drivers/pmdomain
parent6fd062713d9995de9e68ac3a071213eee1c11ea9 (diff)
downloadlinux-a3be677629e4e0d246284956ff422392fafd715f.tar.gz
linux-a3be677629e4e0d246284956ff422392fafd715f.tar.bz2
linux-a3be677629e4e0d246284956ff422392fafd715f.zip
pmdomain: ti-sci: Fix duplicate PD referrals
commit 670c900f69645db394efb38934b3344d8804171a upstream. When the dts file has multiple referrers to a single PD (e.g. simple-framebuffer and dss nodes both point to the DSS power-domain) the ti-sci driver will create two power domains, both with the same ID, and that will cause problems as one of the power domains will hide the other one. Fix this checking if a PD with the ID has already been created, and only create a PD for new IDs. Fixes: efa5c01cd7ee ("soc: ti: ti_sci_pm_domains: switch to use multiple genpds instead of one") Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240415-ti-sci-pd-v1-1-a0e56b8ad897@ideasonboard.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pmdomain')
-rw-r--r--drivers/pmdomain/ti/ti_sci_pm_domains.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index 34645104fe45..f520228e1b6a 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = {
};
MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches);
+static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx)
+{
+ struct ti_sci_pm_domain *pd;
+
+ list_for_each_entry(pd, &pd_provider->pd_list, node) {
+ if (pd->idx == idx)
+ return true;
+ }
+
+ return false;
+}
+
static int ti_sci_pm_domain_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -149,8 +161,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
break;
if (args.args_count >= 1 && args.np == dev->of_node) {
- if (args.args[0] > max_id)
+ if (args.args[0] > max_id) {
max_id = args.args[0];
+ } else {
+ if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) {
+ index++;
+ continue;
+ }
+ }
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd)