Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Vishnu Reddy" <busanna.reddy@oss.qualcomm.com>
Cc: conor+dt@kernel.org, devicetree@vger.kernel.org,
	linux-media@vger.kernel.org, robh@kernel.org
Subject: Re: [PATCH v7 06/12] media: iris: Replace enum-indexed clock and power domain tables with per-block structures
Date: Wed, 03 Jun 2026 14:37:18 +0000	[thread overview]
Message-ID: <20260603143718.A65981F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260603-glymur-v7-6-afaa55d11fe0@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:

New issues:
- [High] Uninitialized stack pointer dereference when a hardware block has 0 power domains.
- [High] Secondary hardware cores are left unpowered due to missing iteration over `num_cores`.
- [High] NULL pointer dereference when optional hardware blocks are enabled in hardware but missing from platform data.
- [High] Premature OPP voltage drop causes DVFS sequence violation.
- [High] Uninitialized fields in `struct dev_pm_domain_attach_data` result in arbitrary behavior.
- [Medium] API mismatch silently discards additional power domains if `pd_cnt > 1`.

Pre-existing issues:
- [High] Resource leak of Runtime PM usage counter and OPP rate on error path.
--

commit 569dbace99d0eb806398e44f1f3dd0f46e77e155
Author: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>

media: iris: Replace enum-indexed clock and power domain tables with per-block structures

This patch replaces flat, enum-indexed tables for clocks and power domains with 
per-hardware block structures in the iris driver. It groups devices, power 
domains, and clocks together logically in the iris_power_domain struct, and 
removes index lookups at runtime.

> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
> index c2dcb50a27824..681db1da9559a 100644
> --- a/drivers/media/platform/qcom/iris/iris_probe.c
> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
> @@ -39,15 +39,32 @@ static int iris_init_icc(struct iris_core *core)
>  	return devm_of_icc_bulk_get(core->dev, core->icc_count, core->icc_tbl);
>  }
>  
> -static int iris_init_power_domains(struct iris_core *core)
> +static int iris_init_power_domains_per_block(struct iris_core *core,
> +					     struct iris_power_domain *pd,
> +					     const struct iris_power_domain_data *pd_data)
>  {
> +	struct dev_pm_domain_attach_data iris_pd_data;

[Severity: High]
Does this leave fields in iris_pd_data uninitialized? Since it's allocated on the
stack without zero-initialization, any fields added to struct
dev_pm_domain_attach_data (like link_flags) could contain stack garbage when
passed to devm_pm_domain_attach_list().

> +	struct dev_pm_domain_list *pmdomain_tbl;
>  	int ret;
>  
> +	iris_pd_data.pd_names = pd_data->pd_names;
> +	iris_pd_data.num_pd_names = pd_data->pd_cnt;
> +	iris_pd_data.pd_flags = PD_FLAG_NO_DEV_LINK;
> +
> +	ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &pmdomain_tbl);
> +	if (ret < 0)
> +		return ret;
> +
> +	pd->dev = pmdomain_tbl->pd_devs[0];

[Severity: High]
If pd_data->pd_cnt is 0, devm_pm_domain_attach_list() returns 0 but does not
modify pmdomain_tbl. Does this result in an uninitialized pointer dereference
when accessing pmdomain_tbl->pd_devs[0]?

[Severity: Medium]
Also, if the platform data specifies multiple power domains (pd_cnt > 1), does
this logic silently discard all but the first power domain? Since
PD_FLAG_NO_DEV_LINK is used, the driver has to power them on manually, which
means secondary domains might never be powered on.

> +
> +	return 0;
> +}
[ ... ]
> diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c
> index 773f6548370a2..fdc6eb68e5c78 100644
> --- a/drivers/media/platform/qcom/iris/iris_resources.c
> +++ b/drivers/media/platform/qcom/iris/iris_resources.c
[ ... ]
> @@ -70,7 +69,7 @@ int iris_opp_set_rate(struct device *dev, unsigned long freq)
>  	return dev_pm_opp_set_opp(dev, opp);
>  }
>  
> -int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev)
> +int iris_enable_power_domain_and_clocks(struct iris_core *core, struct iris_power_domain *pd)
>  {
>  	int ret;
>  
> @@ -78,66 +77,20 @@ int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev)
>  	if (ret)
>  		return ret;
>  
> -	ret = pm_runtime_get_sync(pd_dev);
> +	ret = pm_runtime_get_sync(pd->dev);
>  	if (ret < 0)
>  		return ret;
>  

[Severity: High]
This is a pre-existing issue, but does this error path permanently leak the
runtime PM usage counter and leave the global core device forced to its highest
performance state? If pm_runtime_get_sync() fails, there is no
pm_runtime_put_noidle() or iris_opp_set_rate(core->dev, 0) called before
returning.

> -	return ret;
> -}
> -
> -int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev)
> -{
> -	int ret;
> -
> -	ret = iris_opp_set_rate(core->dev, 0);
> +	ret = clk_bulk_prepare_enable(pd->clk_cnt, pd->clocks);
>  	if (ret)
> -		return ret;
> -
> -	pm_runtime_put_sync(pd_dev);
> -
> -	return 0;
> -}
> +		pm_runtime_put_sync(pd->dev);
>  
> -static struct clk *iris_get_clk_by_type(struct iris_core *core, enum platform_clk_type clk_type)
> -{
[ ... ]
> +	return ret;
>  }
>  
> -int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type)
> +void iris_disable_power_domain_and_clocks(struct iris_core *core, struct iris_power_domain *pd)
>  {
> -	struct clk *clock;
> -
> -	clock = iris_get_clk_by_type(core, clk_type);
> -	if (!clock)
> -		return -EINVAL;
> -
> -	clk_disable_unprepare(clock);
> -
> -	return 0;
> +	clk_bulk_disable_unprepare(pd->clk_cnt, pd->clocks);
> +	iris_opp_set_rate(core->dev, 0);
> +	pm_runtime_put_sync(pd->dev);
>  }

[Severity: High]
Could dropping the OPP rate to 0 inside a block-specific helper cause issues?
If multiple blocks are being torn down (for example, in
iris_vpu4x_power_off_hardware() which shuts down VPP1, VPP0, then VCODEC), this
would instantly drop the global controller OPP to 0 when the first block is
disabled, while other blocks' clocks are still running. Does this violate DVFS
constraints?

[ ... ]
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c
> index 02e100a4045fc..0feb5eaa544f9 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu4x.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c
[ ... ]
> @@ -158,116 +136,43 @@ static void iris_vpu4x_ahb_sync_reset_hardware(struct iris_core *core)
>  	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>  }
>  
> -static int iris_vpu4x_enable_hardware_clocks(struct iris_core *core, u32 efuse_value)
> -{
[ ... ]
> -}
> -
>  static int iris_vpu4x_power_on_hardware(struct iris_core *core)
>  {
>  	u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR);
>  	int ret;
>  
> -	ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> +	ret = iris_enable_power_domain_and_clocks(core, core->vcodec);
>  	if (ret)
>  		return ret;
>  
>  	if (!(efuse_value & DISABLE_VIDEO_VPP0_BIT)) {
> -		ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs
> -						[IRIS_VPP0_HW_POWER_DOMAIN]);
> +		ret = iris_enable_power_domain_and_clocks(core, core->vcodec_vpp0);

[Severity: High]
If the hardware efuse indicates VPP0 is present, but the platform data omits
vcodec_vpp0_data, core->vcodec_vpp0 will not be allocated during probe. Does
this result in a NULL pointer dereference here since
iris_enable_power_domain_and_clocks() accesses pd->dev?

>  		if (ret)
>  			goto disable_hw_power_domain;
>  	}
>  
[ ... ]
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> index 23a7ce3ecb2d0..f35754ef53ed1 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
[ ... ]
>  int iris_vpu_power_on_hw(struct iris_core *core)
>  {
> -	int ret;
> -
> -	ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> -	if (ret)
> -		return ret;
> -
> -	ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
> -	if (ret)
> -		goto err_disable_power;
> -
> -	ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK);
> -	if (ret && ret != -ENOENT)
> -		goto err_disable_hw_clock;
> -
> -	ret = iris_prepare_enable_clock(core, IRIS_BSE_HW_CLK);
> -	if (ret && ret != -ENOENT)
> -		goto err_disable_hw_ahb_clock;
> -
> -	return 0;
> -
> -err_disable_hw_ahb_clock:
> -	iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
> -err_disable_hw_clock:
> -	iris_disable_unprepare_clock(core, IRIS_HW_CLK);
> -err_disable_power:
> -	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> -
> -	return ret;
> +	return iris_enable_power_domain_and_clocks(core, core->vcodec);
>  }

[Severity: High]
Does this fail to power on any secondary hardware cores? The probe function
dynamically allocates core->vcodec as an array based on num_cores, but this only
passes the pointer to the first element to
iris_enable_power_domain_and_clocks(), without iterating over the remaining
cores.

>  
>  int iris_vpu_set_hwmode(struct iris_core *core)
>  {
> -	return dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
> +	return dev_pm_genpd_set_hwmode(core->vcodec->dev, true);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260603-glymur-v7-0-afaa55d11fe0@oss.qualcomm.com?part=6

  reply	other threads:[~2026-06-03 14:37 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-03 14:18 [PATCH v7 00/12] media: iris: Add support for glymur platform Vishnu Reddy
2026-06-03 14:18 ` [PATCH v7 01/12] media: iris: Add iris vpu bus support Vishnu Reddy
2026-06-03 14:45   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 02/12] iommu: Add iris-vpu-bus to iommu_buses Vishnu Reddy
2026-06-03 14:34   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 03/12] dt-bindings: media: qcom,glymur-iris: Add glymur video codec Vishnu Reddy
2026-06-03 14:18 ` [PATCH v7 04/12] media: iris: Add context bank hooks for platform specific initialization Vishnu Reddy
2026-06-03 14:36   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 05/12] media: iris: Enable Secure PAS support with IOMMU managed by Linux Vishnu Reddy
2026-06-03 14:39   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 06/12] media: iris: Replace enum-indexed clock and power domain tables with per-block structures Vishnu Reddy
2026-06-03 14:37   ` sashiko-bot [this message]
2026-06-03 14:18 ` [PATCH v7 07/12] media: iris: Add power sequence for glymur Vishnu Reddy
2026-06-03 14:18 ` [PATCH v7 08/12] media: iris: Handle CPU_CS_SCIACMDARG3 register write via program bootup registers hook Vishnu Reddy
2026-06-03 14:18 ` [PATCH v7 09/12] media: iris: Add support to select core for dual core platforms Vishnu Reddy
2026-06-03 14:44   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 10/12] media: iris: Add platform data for glymur Vishnu Reddy
2026-06-03 14:46   ` sashiko-bot
2026-06-03 14:18 ` [PATCH v7 11/12] arm64: dts: qcom: glymur: Add iris video node Vishnu Reddy
2026-06-03 14:18 ` [PATCH v7 12/12] arm64: dts: qcom: glymur-crd: Enable iris video codec node Vishnu Reddy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260603143718.A65981F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=busanna.reddy@oss.qualcomm.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox