[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAPDyKFqocghs2ucVpAz=9vErxSpCO=54RBdQg3ttoqf9t=-tYg@mail.gmail.com>
Date: Thu, 5 Feb 2026 11:56:17 +0100
From: Ulf Hansson <ulf.hansson@...aro.org>
To: Xu Yang <xu.yang_2@....com>
Cc: Frank.Li@....com, s.hauer@...gutronix.de, kernel@...gutronix.de,
festevam@...il.com, peng.fan@....com, jun.li@....com,
rafael.j.wysocki@...el.com, a.fatoum@...gutronix.de, ping.bai@....com,
shawnguo@...nel.org, l.stach@...gutronix.de, linux-pm@...r.kernel.org,
imx@...ts.linux.dev, linux-arm-kernel@...ts.infradead.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2 1/2] pmdomain: imx8mp-blk-ctrl: keep gpc power domain
on if blk-ctrl pd is on during system pm
On Wed, 4 Feb 2026 at 12:10, Xu Yang <xu.yang_2@....com> wrote:
>
> Current design will power off all dependent GPC power domains in
> imx8mp_blk_ctrl_suspend(), even though the user device has enabled
> wakeup capability. The result is that wakeup function never works
> for such device.
>
> An example will be USB wakeup on i.MX8MP. PHY device '382f0040.usb-phy'
> is attached to power domain 'hsioblk-usb-phy2' which is spawned by hsio
> block control. A virtual power domain device 'genpd:3:32f10000.blk-ctrl'
> is created to build connection with 'hsioblk-usb-phy2' and it depends on
> GPC power domain 'usb-otg2'. If device '382f0040.usb-phy' enable wakeup,
> only power domain 'hsioblk-usb-phy2' keeps on during system suspend,
> power domain 'usb-otg2' is off all the time. So the wakeup event can't
> happen.
>
> In order to further establish a connection between the power domains
> related to GPC and block control during system pm, register a notifier
> to power_dev, so that GPC power domain will know that block control power
> domain is on and will not power off itself.
>
> Suggested-by: Ulf Hansson <ulf.hansson@...aro.org>
> Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl")
> Cc: stable@...nel.org
> Signed-off-by: Xu Yang <xu.yang_2@....com>
Applied for fixes and by amending the commit message a little bit to
make it clearer, thanks!
Kind regards
Uffe
>
> ---
> Changes in v2:
> - add notifier to support wakeup needs
> ---
> drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> index 34576be606e3..56bbfee8668d 100644
> --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> @@ -65,6 +65,7 @@ struct imx8mp_blk_ctrl_domain {
> struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
> struct device *power_dev;
> struct imx8mp_blk_ctrl *bc;
> + struct notifier_block power_nb;
> int num_paths;
> int id;
> };
> @@ -594,6 +595,20 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd)
> return 0;
> }
>
> +static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb,
> + unsigned long action, void *data)
> +{
> + struct imx8mp_blk_ctrl_domain *domain =
> + container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb);
> +
> + if (action == GENPD_NOTIFY_PRE_OFF) {
> + if (domain->genpd.status == GENPD_STATE_ON)
> + return NOTIFY_BAD;
> + }
> +
> + return NOTIFY_OK;
> +}
> +
> static struct lock_class_key blk_ctrl_genpd_lock_class;
>
> static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
> @@ -698,6 +713,14 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
> goto cleanup_pds;
> }
>
> + domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier;
> + ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb);
> + if (ret) {
> + dev_err_probe(dev, ret, "failed to add power notifier\n");
> + dev_pm_domain_detach(domain->power_dev, true);
> + goto cleanup_pds;
> + }
> +
> domain->genpd.name = data->name;
> domain->genpd.power_on = imx8mp_blk_ctrl_power_on;
> domain->genpd.power_off = imx8mp_blk_ctrl_power_off;
> @@ -707,6 +730,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
> ret = pm_genpd_init(&domain->genpd, NULL, true);
> if (ret) {
> dev_err_probe(dev, ret, "failed to init power domain\n");
> + dev_pm_genpd_remove_notifier(domain->power_dev);
> dev_pm_domain_detach(domain->power_dev, true);
> goto cleanup_pds;
> }
> @@ -755,6 +779,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
> cleanup_pds:
> for (i--; i >= 0; i--) {
> pm_genpd_remove(&bc->domains[i].genpd);
> + dev_pm_genpd_remove_notifier(bc->domains[i].power_dev);
> dev_pm_domain_detach(bc->domains[i].power_dev, true);
> }
>
> @@ -774,6 +799,7 @@ static void imx8mp_blk_ctrl_remove(struct platform_device *pdev)
> struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
>
> pm_genpd_remove(&domain->genpd);
> + dev_pm_genpd_remove_notifier(domain->power_dev);
> dev_pm_domain_detach(domain->power_dev, true);
> }
>
> --
> 2.34.1
>
Powered by blists - more mailing lists