* [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-13 11:26 ` Konrad Dybcio
2026-07-13 15:11 ` Marc Zyngier
2026-07-13 10:25 ` [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain Sneh Mankad
` (5 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
Remove #power-domain-cells property and add power-domains property for
MPM device.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
.../devicetree/bindings/interrupt-controller/qcom,mpm.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
index ebb40c48950ab3a8fc86f5708acfc33c33d68993..3f9645fbc3c20633077aaa589e5d5a43928dab51 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
@@ -68,8 +68,8 @@ properties:
- description: MPM pin number
- description: GIC SPI number for the MPM pin
- '#power-domain-cells':
- const: 0
+ power-domains:
+ maxItems: 1
required:
- compatible
@@ -113,6 +113,6 @@ examples:
<24 79>,
<86 183>,
<91 260>;
- #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
};
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property
2026-07-13 10:25 ` [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property Sneh Mankad
@ 2026-07-13 11:26 ` Konrad Dybcio
2026-07-13 15:11 ` Marc Zyngier
1 sibling, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-13 11:26 UTC (permalink / raw)
To: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel
On 7/13/26 12:25 PM, Sneh Mankad wrote:
> Remove #power-domain-cells property and add power-domains property for
> MPM device.
"why"?
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property
2026-07-13 10:25 ` [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property Sneh Mankad
2026-07-13 11:26 ` Konrad Dybcio
@ 2026-07-13 15:11 ` Marc Zyngier
2026-07-15 6:38 ` Marek Szyprowski
1 sibling, 1 reply; 21+ messages in thread
From: Marc Zyngier @ 2026-07-13 15:11 UTC (permalink / raw)
To: Sneh Mankad
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, linux-arm-msm,
devicetree, linux-kernel
On Mon, 13 Jul 2026 11:25:41 +0100,
Sneh Mankad <sneh.mankad@oss.qualcomm.com> wrote:
>
> Remove #power-domain-cells property and add power-domains property for
> MPM device.
>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> ---
> .../devicetree/bindings/interrupt-controller/qcom,mpm.yaml | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> index ebb40c48950ab3a8fc86f5708acfc33c33d68993..3f9645fbc3c20633077aaa589e5d5a43928dab51 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> @@ -68,8 +68,8 @@ properties:
> - description: MPM pin number
> - description: GIC SPI number for the MPM pin
>
> - '#power-domain-cells':
> - const: 0
> + power-domains:
> + maxItems: 1
What makes you think it is OK to change an existing binding in an
incompatible way?
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property
2026-07-13 15:11 ` Marc Zyngier
@ 2026-07-15 6:38 ` Marek Szyprowski
2026-07-15 8:54 ` Marc Zyngier
0 siblings, 1 reply; 21+ messages in thread
From: Marek Szyprowski @ 2026-07-15 6:38 UTC (permalink / raw)
To: Marc Zyngier, Sneh Mankad, Ulf Hansson
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, linux-arm-msm,
devicetree, linux-kernel
On 13.07.2026 17:11, Marc Zyngier wrote:
> On Mon, 13 Jul 2026 11:25:41 +0100,
> Sneh Mankad <sneh.mankad@oss.qualcomm.com> wrote:
>> Remove #power-domain-cells property and add power-domains property for
>> MPM device.
>>
>> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
>> ---
>> .../devicetree/bindings/interrupt-controller/qcom,mpm.yaml | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
>> index ebb40c48950ab3a8fc86f5708acfc33c33d68993..3f9645fbc3c20633077aaa589e5d5a43928dab51 100644
>> --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
>> @@ -68,8 +68,8 @@ properties:
>> - description: MPM pin number
>> - description: GIC SPI number for the MPM pin
>>
>> - '#power-domain-cells':
>> - const: 0
>> + power-domains:
>> + maxItems: 1
> What makes you think it is OK to change an existing binding in an
> incompatible way?
Ulf suggests that this has been modeled upside down in the initial
submission:
https://lore.kernel.org/all/CAPx+jO9d1qH12mxg-n1rkbp6Xd__sdrSMeoc7CPELE+jgxRYHA@mail.gmail.com/
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property
2026-07-15 6:38 ` Marek Szyprowski
@ 2026-07-15 8:54 ` Marc Zyngier
0 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2026-07-15 8:54 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Sneh Mankad, Ulf Hansson, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner,
Shawn Guo, linux-arm-msm, devicetree, linux-kernel
On Wed, 15 Jul 2026 07:38:59 +0100,
Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
> On 13.07.2026 17:11, Marc Zyngier wrote:
> > On Mon, 13 Jul 2026 11:25:41 +0100,
> > Sneh Mankad <sneh.mankad@oss.qualcomm.com> wrote:
> >> Remove #power-domain-cells property and add power-domains property for
> >> MPM device.
> >>
> >> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> >> ---
> >> .../devicetree/bindings/interrupt-controller/qcom,mpm.yaml | 6 +++---
> >> 1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> >> index ebb40c48950ab3a8fc86f5708acfc33c33d68993..3f9645fbc3c20633077aaa589e5d5a43928dab51 100644
> >> --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> >> +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
> >> @@ -68,8 +68,8 @@ properties:
> >> - description: MPM pin number
> >> - description: GIC SPI number for the MPM pin
> >>
> >> - '#power-domain-cells':
> >> - const: 0
> >> + power-domains:
> >> + maxItems: 1
> > What makes you think it is OK to change an existing binding in an
> > incompatible way?
>
>
> Ulf suggests that this has been modeled upside down in the initial
> submission:
>
> https://lore.kernel.org/all/CAPx+jO9d1qH12mxg-n1rkbp6Xd__sdrSMeoc7CPELE+jgxRYHA@mail.gmail.com/
Sure. We have collectively fucked up a lot of bindings over the years,
mostly because of the lack of accurate documentation and people not
giving a damn about the correctness of these descriptions. I'm glad
that Ulf is now able to make it right.
But that is not a license to invalidate DTs retrospectively. We don't
update DTs in lockstep with the kernel (I *never* do), and something
that existed must be supported in the long run.
Properties can be deprecated, but:
- they must be kept in the binding
- drivers must still honor them if they are present in the DT
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
2026-07-13 10:25 ` [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-15 9:46 ` Konrad Dybcio
2026-07-13 10:25 ` [PATCH 3/7] irqchip/irq-qcom-mpm: Prepare common access path for timer and pin regs Sneh Mankad
` (4 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
the latest wake up capable interrupts when the CPU cluster is entering the
deepest idle state. This is done by sending IPC interrupt to RPM and is
implemented as .power_off() callback by registering MPM as parent power
domain to CPU cluster.
Such implementation introduces a hard probe dependency between MPM irqchip
and CPU cluster power domains. That is MPM irqchip needs to finish probe
before PSCI power domains are probed. MPM irqchip can be build as module
and can get later inserted where as PSCI power domains is not a module.
For in-built driver cases too PSCI domain gets probed first and later MPM
irqchip leading to failure of CPUidle states.
Detailed flow of the non-working scenario:
psci-cpuidle-domain.c probe
--> dt_idle_pd_init_topology()
--> of_genpd_add_subdomain()
--> genpd_get_from_provider()
--> fails to find parent MPM genPD provider
--> returns -EPROBE_DEFER.
irq-qcom-mpm.c probe
--> of_genpd_add_provider_simple()
--> genpd_add_provider()
--> MPM added as a genPD provider.
Now when psci_cpuidle_probe() is called to probe the CPU idle states, it
tries to map the states to the mentioned power-domains.
But since power domains probe has been deferred, psci_cpuidle_probe() too
will return -EPROBE_DEFER.
commit af5376a77e87 ("cpuidle: psci: Transition to the faux device
interface") transitioned cpuidle-psci to a faux device interface.
faux_device_create() calls faux_device_create_with_groups(), which ignores
the probe return value, and destroys the device if dev->driver is not set.
This will lead to psci_cpuidle_probe() not being called again, resulting in
all idle-state devices failing to init in SoCs setting MPM as a parent
power domain to CPU cluster.
cpuidle-psci.c init
--> faux_device_create()
...
--> psci_cpuidle_probe()
--> psci_idle_init_cpu()
...
--> psci_dt_cpu_init_topology()
...
-> dev_pm_domain_attach_by_name()
--> __genpd_dev_pm_attach()
--> genpd_get_from_provider()
--> fails to find CPU genPD provider
--> returns -EPROBE_DEFER
--> return value ignored and device
destroyed
Move the RPM notification handling to the GENPD_NOTIFY_PRE_OFF callback and
register MPM under the CPU cluster power domain. Use runtime PM to report
the default RPM_SUSPENDED state to genPD so that the CPU cluster power
domain can enter low power mode.
If MPM has not registered with CPU cluster power domain, utilize the CPU PM
notifications to manage RPM communication when the last CPU goes to power
collapse.
Fixes: a6199bb514d8 ("irqchip: Add Qualcomm MPM controller driver")
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
drivers/irqchip/irq-qcom-mpm.c | 97 ++++++++++++++++++++++++++++++------------
1 file changed, 69 insertions(+), 28 deletions(-)
diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c
index 181320528a47ac1bde6cf7d2d0a9f79499990092..01fd1843172aa22760d359281e39f0d9394bab6d 100644
--- a/drivers/irqchip/irq-qcom-mpm.c
+++ b/drivers/irqchip/irq-qcom-mpm.c
@@ -4,6 +4,8 @@
* Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
*/
+#include <linux/atomic.h>
+#include <linux/cpu_pm.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -18,6 +20,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/soc/qcom/irq.h>
#include <linux/spinlock.h>
@@ -84,7 +87,9 @@ struct qcom_mpm_priv {
unsigned int map_cnt;
unsigned int reg_stride;
struct irq_domain *domain;
- struct generic_pm_domain genpd;
+ struct notifier_block genpd_nb;
+ struct notifier_block mpm_pm;
+ atomic_t cpus_in_pm;
};
static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, unsigned int reg,
@@ -292,10 +297,8 @@ static irqreturn_t qcom_mpm_handler(int irq, void *dev_id)
return ret;
}
-static int mpm_pd_power_off(struct generic_pm_domain *genpd)
+static int handle_rpm_notification(struct qcom_mpm_priv *priv)
{
- struct qcom_mpm_priv *priv = container_of(genpd, struct qcom_mpm_priv,
- genpd);
int i, ret;
for (i = 0; i < priv->reg_stride; i++)
@@ -307,10 +310,59 @@ static int mpm_pd_power_off(struct generic_pm_domain *genpd)
return ret;
mbox_client_txdone(priv->mbox_chan, 0);
-
return 0;
}
+static int mpm_pd_power_cb(struct notifier_block *nb, unsigned long action, void *d)
+{
+ struct qcom_mpm_priv *priv = container_of(nb, struct qcom_mpm_priv,
+ genpd_nb);
+
+ switch (action) {
+ case GENPD_NOTIFY_PRE_OFF:
+ if (handle_rpm_notification(priv))
+ return NOTIFY_BAD;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int mpm_cpu_pm_callback(struct notifier_block *nfb,
+ unsigned long action, void *v)
+{
+ struct qcom_mpm_priv *priv = container_of(nfb, struct qcom_mpm_priv, mpm_pm);
+ int cpus_in_pm;
+
+ switch (action) {
+ case CPU_PM_ENTER:
+ cpus_in_pm = atomic_inc_return(&priv->cpus_in_pm);
+ /*
+ * NOTE: comments for num_online_cpus() point out that it's
+ * only a snapshot so we need to be careful. It should be OK
+ * for us to use, though. It's important for us not to miss
+ * if we're the last CPU going down so it would only be a
+ * problem if a CPU went offline right after we did the check
+ * AND that CPU was not idle AND that CPU was the last non-idle
+ * CPU. That can't happen. CPUs would have to come out of idle
+ * before the CPU could go offline.
+ */
+ if (cpus_in_pm < num_online_cpus())
+ return NOTIFY_OK;
+ break;
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ atomic_dec(&priv->cpus_in_pm);
+ return NOTIFY_OK;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ if (handle_rpm_notification(priv))
+ return NOTIFY_BAD;
+
+ return NOTIFY_OK;
+}
+
static bool gic_hwirq_is_mapped(struct mpm_gic_map *maps, int cnt, u32 hwirq)
{
int i;
@@ -327,7 +379,6 @@ static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *pare
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct irq_domain *parent_domain;
- struct generic_pm_domain *genpd;
struct device_node *msgram_np;
struct qcom_mpm_priv *priv;
unsigned int pin_cnt;
@@ -415,26 +466,6 @@ static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *pare
if (irq < 0)
return irq;
- genpd = &priv->genpd;
- genpd->flags = GENPD_FLAG_IRQ_SAFE;
- genpd->power_off = mpm_pd_power_off;
-
- genpd->name = devm_kasprintf(dev, GFP_KERNEL, "%s", dev_name(dev));
- if (!genpd->name)
- return -ENOMEM;
-
- ret = pm_genpd_init(genpd, NULL, false);
- if (ret) {
- dev_err(dev, "failed to init genpd: %d\n", ret);
- return ret;
- }
-
- ret = of_genpd_add_provider_simple(np, genpd);
- if (ret) {
- dev_err(dev, "failed to add genpd provider: %d\n", ret);
- goto remove_genpd;
- }
-
priv->mbox_client.dev = dev;
priv->mbox_client.knows_txdone = true;
priv->mbox_chan = mbox_request_channel(&priv->mbox_client, 0);
@@ -469,14 +500,24 @@ static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *pare
goto remove_domain;
}
+ if (of_find_property(np, "power-domains", NULL)) {
+ devm_pm_runtime_enable(dev);
+ priv->genpd_nb.notifier_call = mpm_pd_power_cb;
+ ret = dev_pm_genpd_add_notifier(dev, &priv->genpd_nb);
+ } else {
+ priv->mpm_pm.notifier_call = mpm_cpu_pm_callback;
+ ret = cpu_pm_register_notifier(&priv->mpm_pm);
+ }
+
+ if (ret)
+ goto remove_domain;
+
return 0;
remove_domain:
irq_domain_remove(priv->domain);
free_mbox:
mbox_free_channel(priv->mbox_chan);
-remove_genpd:
- pm_genpd_remove(genpd);
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-13 10:25 ` [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain Sneh Mankad
@ 2026-07-15 9:46 ` Konrad Dybcio
2026-07-15 10:34 ` Stephan Gerhold
0 siblings, 1 reply; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 9:46 UTC (permalink / raw)
To: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel
On 7/13/26 12:25 PM, Sneh Mankad wrote:
> MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
> the latest wake up capable interrupts when the CPU cluster is entering the
> deepest idle state. This is done by sending IPC interrupt to RPM and is
> implemented as .power_off() callback by registering MPM as parent power
> domain to CPU cluster.
[...]
> If MPM has not registered with CPU cluster power domain, utilize the CPU PM
> notifications to manage RPM communication when the last CPU goes to power
> collapse.
I have mixed feelings about this case. The RPMH RSC driver keeps that as a
fallback for platforms which don't have PSCI OSI mode specifically.
On the other hand, there are platforms (early arm64 - pre-msm8996 and almost
all of the arm32 platforms) that don't define any CPU power domains, so
perhaps it's necessary after all..
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-15 9:46 ` Konrad Dybcio
@ 2026-07-15 10:34 ` Stephan Gerhold
2026-07-15 10:45 ` Konrad Dybcio
0 siblings, 1 reply; 21+ messages in thread
From: Stephan Gerhold @ 2026-07-15 10:34 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier, linux-arm-msm, devicetree, linux-kernel
On Wed, Jul 15, 2026 at 11:46:58AM +0200, Konrad Dybcio wrote:
> On 7/13/26 12:25 PM, Sneh Mankad wrote:
> > MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
> > the latest wake up capable interrupts when the CPU cluster is entering the
> > deepest idle state. This is done by sending IPC interrupt to RPM and is
> > implemented as .power_off() callback by registering MPM as parent power
> > domain to CPU cluster.
>
> [...]
>
> > If MPM has not registered with CPU cluster power domain, utilize the CPU PM
> > notifications to manage RPM communication when the last CPU goes to power
> > collapse.
>
> I have mixed feelings about this case. The RPMH RSC driver keeps that as a
> fallback for platforms which don't have PSCI OSI mode specifically.
>
> On the other hand, there are platforms (early arm64 - pre-msm8996 and almost
> all of the arm32 platforms) that don't define any CPU power domains, so
> perhaps it's necessary after all..
>
I don't think this fallback is relevant for the non-PSCI QC platforms,
for the following reasons:
- They don't define the MPM.
- They don't support cluster idle upstream, so they don't need to
define the MPM. They can't reach the idle state where it would become
relevant.
- The setup for cluster idle without PSCI is essentially equivalent to
OSI, except that the SPM/SAW driver needs to program the idle state
to enter. There is one SPM/SAW for every idle domain (e.g. on
MSM8939: 2x4 CPU, 2x Cluster, 1x System). You can just model the
SPM/SAW instances as power domains to get the same setup as PSCI OSI
(I had a draft for this at some point). So if someone ever implements
this, we should be able to use the same approach as for PSCI OSI.
I'm not aware of non-OSI PSCI platforms with MPM either, so I'm not sure
when this fallback would be used.
We probably do need some fallback for the old sm6375/agatii DTBs though.
Thanks,
Stephan
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-15 10:34 ` Stephan Gerhold
@ 2026-07-15 10:45 ` Konrad Dybcio
2026-07-15 10:49 ` Stephan Gerhold
0 siblings, 1 reply; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 10:45 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier, linux-arm-msm, devicetree, linux-kernel
On 7/15/26 12:34 PM, Stephan Gerhold wrote:
> On Wed, Jul 15, 2026 at 11:46:58AM +0200, Konrad Dybcio wrote:
>> On 7/13/26 12:25 PM, Sneh Mankad wrote:
>>> MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
>>> the latest wake up capable interrupts when the CPU cluster is entering the
>>> deepest idle state. This is done by sending IPC interrupt to RPM and is
>>> implemented as .power_off() callback by registering MPM as parent power
>>> domain to CPU cluster.
>>
>> [...]
>>
>>> If MPM has not registered with CPU cluster power domain, utilize the CPU PM
>>> notifications to manage RPM communication when the last CPU goes to power
>>> collapse.
>>
>> I have mixed feelings about this case. The RPMH RSC driver keeps that as a
>> fallback for platforms which don't have PSCI OSI mode specifically.
>>
>> On the other hand, there are platforms (early arm64 - pre-msm8996 and almost
>> all of the arm32 platforms) that don't define any CPU power domains, so
>> perhaps it's necessary after all..
>>
>
> I don't think this fallback is relevant for the non-PSCI QC platforms,
> for the following reasons:
>
> - They don't define the MPM.
> - They don't support cluster idle upstream, so they don't need to
> define the MPM. They can't reach the idle state where it would become
> relevant.
> - The setup for cluster idle without PSCI is essentially equivalent to
> OSI, except that the SPM/SAW driver needs to program the idle state
> to enter. There is one SPM/SAW for every idle domain (e.g. on
> MSM8939: 2x4 CPU, 2x Cluster, 1x System). You can just model the
> SPM/SAW instances as power domains to get the same setup as PSCI OSI
> (I had a draft for this at some point). So if someone ever implements
> this, we should be able to use the same approach as for PSCI OSI.
Yeah I said 'necessary' because of the arm32 platforms. This would probably
be the preferable way forward.
> I'm not aware of non-OSI PSCI platforms with MPM either, so I'm not sure
> when this fallback would be used.
I think it's generally only SC7180 and there's definitely no MPM there.
> We probably do need some fallback for the old sm6375/agatii DTBs though.
The sleep logic doesn't really matter without the platforms hitting a
specific power state anyway, so I'm not sure we actually have to (i.e.
the regressed path can't be exercised today anyway)
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-15 10:45 ` Konrad Dybcio
@ 2026-07-15 10:49 ` Stephan Gerhold
2026-07-15 11:11 ` Konrad Dybcio
0 siblings, 1 reply; 21+ messages in thread
From: Stephan Gerhold @ 2026-07-15 10:49 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier, linux-arm-msm, devicetree, linux-kernel
On Wed, Jul 15, 2026 at 12:45:48PM +0200, Konrad Dybcio wrote:
> On 7/15/26 12:34 PM, Stephan Gerhold wrote:
> > On Wed, Jul 15, 2026 at 11:46:58AM +0200, Konrad Dybcio wrote:
> >> On 7/13/26 12:25 PM, Sneh Mankad wrote:
> >>> MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
> >>> the latest wake up capable interrupts when the CPU cluster is entering the
> >>> deepest idle state. This is done by sending IPC interrupt to RPM and is
> >>> implemented as .power_off() callback by registering MPM as parent power
> >>> domain to CPU cluster.
> >>
> >> [...]
> >>
> >>> If MPM has not registered with CPU cluster power domain, utilize the CPU PM
> >>> notifications to manage RPM communication when the last CPU goes to power
> >>> collapse.
> >>
> >> I have mixed feelings about this case. The RPMH RSC driver keeps that as a
> >> fallback for platforms which don't have PSCI OSI mode specifically.
> >>
> >> On the other hand, there are platforms (early arm64 - pre-msm8996 and almost
> >> all of the arm32 platforms) that don't define any CPU power domains, so
> >> perhaps it's necessary after all..
> >>
> >
> > I don't think this fallback is relevant for the non-PSCI QC platforms,
> > for the following reasons:
> >
> > - They don't define the MPM.
> > - They don't support cluster idle upstream, so they don't need to
> > define the MPM. They can't reach the idle state where it would become
> > relevant.
> > - The setup for cluster idle without PSCI is essentially equivalent to
> > OSI, except that the SPM/SAW driver needs to program the idle state
> > to enter. There is one SPM/SAW for every idle domain (e.g. on
> > MSM8939: 2x4 CPU, 2x Cluster, 1x System). You can just model the
> > SPM/SAW instances as power domains to get the same setup as PSCI OSI
> > (I had a draft for this at some point). So if someone ever implements
> > this, we should be able to use the same approach as for PSCI OSI.
>
> Yeah I said 'necessary' because of the arm32 platforms. This would probably
> be the preferable way forward.
>
> > I'm not aware of non-OSI PSCI platforms with MPM either, so I'm not sure
> > when this fallback would be used.
>
> I think it's generally only SC7180 and there's definitely no MPM there.
>
> > We probably do need some fallback for the old sm6375/agatii DTBs though.
>
> The sleep logic doesn't really matter without the platforms hitting a
> specific power state anyway, so I'm not sure we actually have to (i.e.
> the regressed path can't be exercised today anyway)
>
So are you saying the MPM is currently assigned as parent to some dummy
idle states in sm6375/agatti.dtsi, which aren't actually triggering APSS
shutdown? Or is it just irrelevant because other power resources keep
the whole platform on (RPM clocks etc)?
If it's the latter, the question is if we might end up fixing that some
day without further device tree changes. :')
Thanks,
Stephan
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain
2026-07-15 10:49 ` Stephan Gerhold
@ 2026-07-15 11:11 ` Konrad Dybcio
0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 11:11 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier, linux-arm-msm, devicetree, linux-kernel
On 7/15/26 12:49 PM, Stephan Gerhold wrote:
> On Wed, Jul 15, 2026 at 12:45:48PM +0200, Konrad Dybcio wrote:
>> On 7/15/26 12:34 PM, Stephan Gerhold wrote:
>>> On Wed, Jul 15, 2026 at 11:46:58AM +0200, Konrad Dybcio wrote:
>>>> On 7/13/26 12:25 PM, Sneh Mankad wrote:
>>>>> MPM irqchip needs to notify RPM (Resource Power Manager) processor to read
>>>>> the latest wake up capable interrupts when the CPU cluster is entering the
>>>>> deepest idle state. This is done by sending IPC interrupt to RPM and is
>>>>> implemented as .power_off() callback by registering MPM as parent power
>>>>> domain to CPU cluster.
[...]
>>> We probably do need some fallback for the old sm6375/agatii DTBs though.
>>
>> The sleep logic doesn't really matter without the platforms hitting a
>> specific power state anyway, so I'm not sure we actually have to (i.e.
>> the regressed path can't be exercised today anyway)
>>
>
> So are you saying the MPM is currently assigned as parent to some dummy
> idle states in sm6375/agatti.dtsi, which aren't actually triggering APSS
> shutdown? Or is it just irrelevant because other power resources keep
> the whole platform on (RPM clocks etc)?
>
> If it's the latter, the question is if we might end up fixing that some
> day without further device tree changes. :')
I wouldn't call them dummy, but I'm not 100% sure they can trigger cxpc
entry..
The latter most likely also applies, although that's based on a guess
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/7] irqchip/irq-qcom-mpm: Prepare common access path for timer and pin regs
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
2026-07-13 10:25 ` [PATCH 1/7] dt-bindings: interrupt-controller: mpm: Document power-domains property Sneh Mankad
2026-07-13 10:25 ` [PATCH 2/7] irqchip/irq-qcom-mpm: Register MPM under CPU cluster power domain Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-15 9:59 ` Konrad Dybcio
2026-07-13 10:25 ` [PATCH 4/7] irqchip/irq-qcom-mpm: Program wakeup timer when CPU cluster goes to LPM Sneh Mankad
` (3 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
The vMPM layout starts with two timer registers followed by pin register
banks (ENABLE/FALLING/RISING/POLARITY/STATUS), each with reg_stride
number of entries.
Use qcom_mpm_offset() as the common addressing helper for both timer and
pin register accesses based on that layout.
vMPM has MPM_REG_* values represented as contiguous register IDs,
hence replace the macros with enum qcom_mpm_reg and modify the accessor
helpers accordingly.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
drivers/irqchip/irq-qcom-mpm.c | 48 ++++++++++++++++++++++++++++++------------
1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c
index 01fd1843172aa22760d359281e39f0d9394bab6d..763eddee99dc4cdd5edab22ce54808528f9ef165 100644
--- a/drivers/irqchip/irq-qcom-mpm.c
+++ b/drivers/irqchip/irq-qcom-mpm.c
@@ -66,11 +66,16 @@
*
*/
-#define MPM_REG_ENABLE 0
-#define MPM_REG_FALLING_EDGE 1
-#define MPM_REG_RISING_EDGE 2
-#define MPM_REG_POLARITY 3
-#define MPM_REG_STATUS 4
+#define MPM_TIMER_REGS 2
+
+enum qcom_mpm_reg {
+ MPM_REG_TIMER = 0,
+ MPM_REG_ENABLE,
+ MPM_REG_FALLING_EDGE,
+ MPM_REG_RISING_EDGE,
+ MPM_REG_POLARITY,
+ MPM_REG_STATUS,
+};
/* MPM pin map to GIC hwirq */
struct mpm_gic_map {
@@ -92,18 +97,36 @@ struct qcom_mpm_priv {
atomic_t cpus_in_pm;
};
-static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, unsigned int reg,
- unsigned int index)
+static unsigned int qcom_mpm_offset(struct qcom_mpm_priv *priv, enum qcom_mpm_reg reg,
+ unsigned int index)
+{
+ unsigned int reg_offset;
+
+ /*
+ * Per the vMPM register map, TIMER[0..1] starts at register index 0 and all pin-specific
+ * registers start after the two TIMER regs. Pin-specific register IDs start at
+ * MPM_REG_ENABLE, so subtract it to convert to a zero-based pin-register group index.
+ */
+ if (reg == MPM_REG_TIMER)
+ reg_offset = index;
+ else
+ reg_offset = MPM_TIMER_REGS +
+ (reg - MPM_REG_ENABLE) * priv->reg_stride + index;
+
+ return reg_offset * sizeof(u32);
+}
+
+static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, enum qcom_mpm_reg reg, unsigned int index)
{
- unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;
+ unsigned int offset = qcom_mpm_offset(priv, reg, index);
return readl_relaxed(priv->base + offset);
}
-static void qcom_mpm_write(struct qcom_mpm_priv *priv, unsigned int reg,
+static void qcom_mpm_write(struct qcom_mpm_priv *priv, enum qcom_mpm_reg reg,
unsigned int index, u32 val)
{
- unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;
+ unsigned int offset = qcom_mpm_offset(priv, reg, index);
writel_relaxed(val, priv->base + offset);
@@ -144,7 +167,7 @@ static void qcom_mpm_unmask(struct irq_data *d)
irq_chip_unmask_parent(d);
}
-static void mpm_set_type(struct qcom_mpm_priv *priv, bool set, unsigned int reg,
+static void mpm_set_type(struct qcom_mpm_priv *priv, bool set, enum qcom_mpm_reg reg,
unsigned int index, unsigned int shift)
{
unsigned long flags, val;
@@ -327,8 +350,7 @@ static int mpm_pd_power_cb(struct notifier_block *nb, unsigned long action, void
return NOTIFY_OK;
}
-static int mpm_cpu_pm_callback(struct notifier_block *nfb,
- unsigned long action, void *v)
+static int mpm_cpu_pm_callback(struct notifier_block *nfb, unsigned long action, void *v)
{
struct qcom_mpm_priv *priv = container_of(nfb, struct qcom_mpm_priv, mpm_pm);
int cpus_in_pm;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 3/7] irqchip/irq-qcom-mpm: Prepare common access path for timer and pin regs
2026-07-13 10:25 ` [PATCH 3/7] irqchip/irq-qcom-mpm: Prepare common access path for timer and pin regs Sneh Mankad
@ 2026-07-15 9:59 ` Konrad Dybcio
0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 9:59 UTC (permalink / raw)
To: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel
On 7/13/26 12:25 PM, Sneh Mankad wrote:
> The vMPM layout starts with two timer registers followed by pin register
> banks (ENABLE/FALLING/RISING/POLARITY/STATUS), each with reg_stride
> number of entries.
>
> Use qcom_mpm_offset() as the common addressing helper for both timer and
> pin register accesses based on that layout.
>
> vMPM has MPM_REG_* values represented as contiguous register IDs,
> hence replace the macros with enum qcom_mpm_reg and modify the accessor
> helpers accordingly.
>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> ---
[...]
> +static unsigned int qcom_mpm_offset(struct qcom_mpm_priv *priv, enum qcom_mpm_reg reg,
> + unsigned int index)
> +{
> + unsigned int reg_offset;
> +
> + /*
> + * Per the vMPM register map, TIMER[0..1] starts at register index 0 and all pin-specific
> + * registers start after the two TIMER regs. Pin-specific register IDs start at
> + * MPM_REG_ENABLE, so subtract it to convert to a zero-based pin-register group index.
> + */
> + if (reg == MPM_REG_TIMER)
> + reg_offset = index;
> + else
> + reg_offset = MPM_TIMER_REGS +
> + (reg - MPM_REG_ENABLE) * priv->reg_stride + index;
> +
> + return reg_offset * sizeof(u32);
I think this comment is superfluous given the visual representation of
the register space just a couple dozen lines above
Maybe this could be a little easier to follow written this way:
s/MPM_TIMER_REGS/MPM_NUM_TIMER_REGS
reg_offset = 0;
if (reg != MPM_REG_TIMER) {
reg_offset += MPM_NUM_TIMER_REGS;
reg_offset += (reg - MPM_REG_ENABLE) * priv->reg_stride;
}
reg_offset += index;
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 4/7] irqchip/irq-qcom-mpm: Program wakeup timer when CPU cluster goes to LPM
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
` (2 preceding siblings ...)
2026-07-13 10:25 ` [PATCH 3/7] irqchip/irq-qcom-mpm: Prepare common access path for timer and pin regs Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-13 15:18 ` Marc Zyngier
2026-07-13 10:25 ` [PATCH 5/7] arm64: dts: qcom: sm6375: Make MPM device as part of CPU cluster domain Sneh Mankad
` (2 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
The next wakeup timer value needs to be set in MPM timer as the arch timer
interrupt can not wakeup the SoC if after the deepest CPUidle states the
SoC also enters deepest low power state.
To wakeup the SoC in such scenarios the earliest wakeup time is set in MPM
timer and the Resource Power Manager (RPM processor) takes care of setting
the timer in HW.
Add MPM timer programming when CPU cluster enters power collapse.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
drivers/irqchip/irq-qcom-mpm.c | 44 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c
index 763eddee99dc4cdd5edab22ce54808528f9ef165..f43c4a1c35f78b6cdae194dc7ae88c5c307ada94 100644
--- a/drivers/irqchip/irq-qcom-mpm.c
+++ b/drivers/irqchip/irq-qcom-mpm.c
@@ -13,6 +13,7 @@
#include <linux/io.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
+#include <linux/ktime.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -25,6 +26,8 @@
#include <linux/soc/qcom/irq.h>
#include <linux/spinlock.h>
+#include <clocksource/arm_arch_timer.h>
+
/*
* This is the driver for Qualcomm MPM (MSM Power Manager) interrupt controller,
* which is commonly found on Qualcomm SoCs built on the RPM architecture.
@@ -77,6 +80,13 @@ enum qcom_mpm_reg {
MPM_REG_STATUS,
};
+#define USECS_TO_CYCLES(time_usecs) xloops_to_cycles((time_usecs) * 0x10C7UL)
+
+static inline unsigned long xloops_to_cycles(u64 xloops)
+{
+ return (xloops * loops_per_jiffy * HZ) >> 32;
+}
+
/* MPM pin map to GIC hwirq */
struct mpm_gic_map {
int pin;
@@ -84,6 +94,7 @@ struct mpm_gic_map {
};
struct qcom_mpm_priv {
+ struct device *dev;
void __iomem *base;
raw_spinlock_t lock;
struct mbox_client mbox_client;
@@ -320,6 +331,36 @@ static irqreturn_t qcom_mpm_handler(int irq, void *dev_id)
return ret;
}
+static void mpm_write_next_wakeup(struct qcom_mpm_priv *priv)
+{
+ ktime_t now, wakeup = KTIME_MAX;
+ u64 wakeup_us, wakeup_cycles = ~0;
+ u32 lo, hi;
+
+ /* Set highest time when system (timekeeping) is suspended */
+ if (system_state == SYSTEM_SUSPEND)
+ goto exit;
+
+ /* Find the relative wakeup in kernel time scale */
+ wakeup = dev_pm_genpd_get_next_hrtimer(priv->dev);
+
+ /* Find the relative wakeup in kernel time scale */
+ now = ktime_get();
+ wakeup = ktime_sub(wakeup, now);
+ wakeup_us = ktime_to_us(wakeup);
+
+ /* Convert the wakeup to arch timer scale */
+ wakeup_cycles = USECS_TO_CYCLES(wakeup_us);
+ wakeup_cycles += arch_timer_read_counter();
+
+exit:
+ lo = wakeup_cycles;
+ hi = wakeup_cycles >> 32;
+
+ qcom_mpm_write(priv, MPM_REG_TIMER, 0, lo);
+ qcom_mpm_write(priv, MPM_REG_TIMER, 1, hi);
+}
+
static int handle_rpm_notification(struct qcom_mpm_priv *priv)
{
int i, ret;
@@ -332,6 +373,7 @@ static int handle_rpm_notification(struct qcom_mpm_priv *priv)
if (ret < 0)
return ret;
+ mpm_write_next_wakeup(priv);
mbox_client_txdone(priv->mbox_chan, 0);
return 0;
}
@@ -412,6 +454,8 @@ static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *pare
if (!priv)
return -ENOMEM;
+ priv->dev = &pdev->dev;
+
ret = of_property_read_u32(np, "qcom,mpm-pin-count", &pin_cnt);
if (ret) {
dev_err(dev, "failed to read qcom,mpm-pin-count: %d\n", ret);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 4/7] irqchip/irq-qcom-mpm: Program wakeup timer when CPU cluster goes to LPM
2026-07-13 10:25 ` [PATCH 4/7] irqchip/irq-qcom-mpm: Program wakeup timer when CPU cluster goes to LPM Sneh Mankad
@ 2026-07-13 15:18 ` Marc Zyngier
0 siblings, 0 replies; 21+ messages in thread
From: Marc Zyngier @ 2026-07-13 15:18 UTC (permalink / raw)
To: Sneh Mankad
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, linux-arm-msm,
devicetree, linux-kernel
On Mon, 13 Jul 2026 11:25:44 +0100,
Sneh Mankad <sneh.mankad@oss.qualcomm.com> wrote:
>
> The next wakeup timer value needs to be set in MPM timer as the arch timer
> interrupt can not wakeup the SoC if after the deepest CPUidle states the
> SoC also enters deepest low power state.
>
> To wakeup the SoC in such scenarios the earliest wakeup time is set in MPM
> timer and the Resource Power Manager (RPM processor) takes care of setting
> the timer in HW.
>
> Add MPM timer programming when CPU cluster enters power collapse.
>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> ---
> drivers/irqchip/irq-qcom-mpm.c | 44 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c
> index 763eddee99dc4cdd5edab22ce54808528f9ef165..f43c4a1c35f78b6cdae194dc7ae88c5c307ada94 100644
> --- a/drivers/irqchip/irq-qcom-mpm.c
> +++ b/drivers/irqchip/irq-qcom-mpm.c
> @@ -13,6 +13,7 @@
> #include <linux/io.h>
> #include <linux/irqchip.h>
> #include <linux/irqdomain.h>
> +#include <linux/ktime.h>
> #include <linux/mailbox_client.h>
> #include <linux/module.h>
> #include <linux/of.h>
> @@ -25,6 +26,8 @@
> #include <linux/soc/qcom/irq.h>
> #include <linux/spinlock.h>
>
> +#include <clocksource/arm_arch_timer.h>
> +
> /*
> * This is the driver for Qualcomm MPM (MSM Power Manager) interrupt controller,
> * which is commonly found on Qualcomm SoCs built on the RPM architecture.
> @@ -77,6 +80,13 @@ enum qcom_mpm_reg {
> MPM_REG_STATUS,
> };
>
> +#define USECS_TO_CYCLES(time_usecs) xloops_to_cycles((time_usecs) * 0x10C7UL)
> +
> +static inline unsigned long xloops_to_cycles(u64 xloops)
> +{
> + return (xloops * loops_per_jiffy * HZ) >> 32;
> +}
> +
Do we really need arch-specific code to be literally copied from
arm64's delay.c, without any comment or attempt at making it generic?
Specially after having added the same stuff to rpmh-rsc.c 4 years ago?
See a pattern here?
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 5/7] arm64: dts: qcom: sm6375: Make MPM device as part of CPU cluster domain
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
` (3 preceding siblings ...)
2026-07-13 10:25 ` [PATCH 4/7] irqchip/irq-qcom-mpm: Program wakeup timer when CPU cluster goes to LPM Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-13 10:25 ` [PATCH 6/7] arm64: dts: qcom: agatti: Do not mark MPM as power domain Sneh Mankad
2026-07-13 10:25 ` [PATCH 7/7] arm64: dts: qcom: shikra: Add CPU idle states Sneh Mankad
6 siblings, 0 replies; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
Do not mark MPM device as power domain since it leads to idle-states init
failure because of probe dependencies.
Instead make it as part of CPU cluster power domain to allow RPM
notification when CPU cluster goes to power collapse.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm6375.dtsi | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi
index ccf572bb1549bf6b86b5232be216c9dfd51bb22d..5f729634e1d9b21deac42f9d55d966e528473202 100644
--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi
@@ -318,7 +318,7 @@ mpm: interrupt-controller {
mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_SMP2P>;
interrupt-controller;
#interrupt-cells = <2>;
- #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
interrupt-parent = <&intc>;
qcom,mpm-pin-count = <96>;
qcom,mpm-pin-map = <5 296>, /* Soundwire wake_irq */
@@ -505,7 +505,6 @@ cpu_pd7: power-domain-cpu7 {
cluster_pd: power-domain-cpu-cluster0 {
#power-domain-cells = <0>;
- power-domains = <&mpm>;
domain-idle-states = <&cluster_sleep_0>;
};
};
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 6/7] arm64: dts: qcom: agatti: Do not mark MPM as power domain
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
` (4 preceding siblings ...)
2026-07-13 10:25 ` [PATCH 5/7] arm64: dts: qcom: sm6375: Make MPM device as part of CPU cluster domain Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-15 10:01 ` Konrad Dybcio
2026-07-13 10:25 ` [PATCH 7/7] arm64: dts: qcom: shikra: Add CPU idle states Sneh Mankad
6 siblings, 1 reply; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
Do not mark MPM device as power domain since it leads to idle-states init
failure because of probe dependencies.
CPU cluster power domain node is kept disabled and hence CPU cluster will
never power collapse. Do not register MPM under it in this case.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/agatti.dtsi | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi
index 8a7337239b1ebe2c40d64ed670752a680085b871..05505dc3b400e923a574bc89ec9a8e7382ab803a 100644
--- a/arch/arm64/boot/dts/qcom/agatti.dtsi
+++ b/arch/arm64/boot/dts/qcom/agatti.dtsi
@@ -205,7 +205,6 @@ cpu_pd3: power-domain-cpu3 {
cluster_pd: power-domain-cpu-cluster {
#power-domain-cells = <0>;
- power-domains = <&mpm>;
domain-idle-states = <&cluster_sleep>;
};
};
@@ -281,7 +280,6 @@ mpm: interrupt-controller {
mboxes = <&apcs_glb 1>;
interrupt-controller;
#interrupt-cells = <2>;
- #power-domain-cells = <0>;
interrupt-parent = <&intc>;
qcom,mpm-pin-count = <96>;
qcom,mpm-pin-map = <2 275>, /* TSENS0 uplow */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 6/7] arm64: dts: qcom: agatti: Do not mark MPM as power domain
2026-07-13 10:25 ` [PATCH 6/7] arm64: dts: qcom: agatti: Do not mark MPM as power domain Sneh Mankad
@ 2026-07-15 10:01 ` Konrad Dybcio
0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 10:01 UTC (permalink / raw)
To: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel
On 7/13/26 12:25 PM, Sneh Mankad wrote:
> Do not mark MPM device as power domain since it leads to idle-states init
> failure because of probe dependencies.
>
> CPU cluster power domain node is kept disabled and hence CPU cluster will
> never power collapse. Do not register MPM under it in this case.
This is only the case on the RB1. How about we fix the issue instead?
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 7/7] arm64: dts: qcom: shikra: Add CPU idle states
2026-07-13 10:25 [PATCH 0/7] Register MPM under CPU cluster power domain to manage RPM notification Sneh Mankad
` (5 preceding siblings ...)
2026-07-13 10:25 ` [PATCH 6/7] arm64: dts: qcom: agatti: Do not mark MPM as power domain Sneh Mankad
@ 2026-07-13 10:25 ` Sneh Mankad
2026-07-15 10:02 ` Konrad Dybcio
6 siblings, 1 reply; 21+ messages in thread
From: Sneh Mankad @ 2026-07-13 10:25 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Shawn Guo, Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel, Sneh Mankad
Add idle states for the CPUs as well as the whole cluster. This enables
deeper-than-WFI cpuidle.
Add MPM under cluster_pd power domain.
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 94 +++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index 4e5bc9e17c8ed8914733ac9fdc9b69128b40216e..bbe198d4a476e9d3037439307a0d12ab58049de2 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -40,6 +40,8 @@ cpu0: cpu@0 {
compatible = "arm,cortex-a55";
reg = <0x0 0x0>;
enable-method = "psci";
+ power-domains = <&cpu_pd0>;
+ power-domain-names = "psci";
next-level-cache = <&l3>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
@@ -50,6 +52,8 @@ cpu1: cpu@100 {
compatible = "arm,cortex-a55";
reg = <0x0 0x100>;
enable-method = "psci";
+ power-domains = <&cpu_pd1>;
+ power-domain-names = "psci";
next-level-cache = <&l3>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
@@ -60,6 +64,8 @@ cpu2: cpu@200 {
compatible = "arm,cortex-a55";
reg = <0x0 0x200>;
enable-method = "psci";
+ power-domains = <&cpu_pd2>;
+ power-domain-names = "psci";
next-level-cache = <&l3>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
@@ -70,6 +76,8 @@ cpu3: cpu@300 {
compatible = "arm,cortex-a78c";
reg = <0x0 0x300>;
enable-method = "psci";
+ power-domains = <&cpu_pd3>;
+ power-domain-names = "psci";
next-level-cache = <&l2_3>;
capacity-dmips-mhz = <1946>;
dynamic-power-coefficient = <489>;
@@ -105,6 +113,61 @@ core0 {
};
};
+ idle-states {
+ entry-method = "psci";
+
+ little_cpu_sleep_0: cpu-sleep-0-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "little-power-down";
+ arm,psci-suspend-param = <0x40000003>;
+ entry-latency-us = <549>;
+ exit-latency-us = <901>;
+ min-residency-us = <1774>;
+ local-timer-stop;
+ };
+
+ little_cpu_sleep_1: cpu-sleep-0-1 {
+ compatible = "arm,idle-state";
+ idle-state-name = "little-pll-power-down";
+ arm,psci-suspend-param = <0x40000004>;
+ entry-latency-us = <702>;
+ exit-latency-us = <915>;
+ min-residency-us = <4001>;
+ local-timer-stop;
+ };
+
+ big_cpu_sleep_0: cpu-sleep-1-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "big-power-down";
+ arm,psci-suspend-param = <0x40000003>;
+ entry-latency-us = <523>;
+ exit-latency-us = <1244>;
+ min-residency-us = <2207>;
+ local-timer-stop;
+ };
+
+ big_cpu_sleep_1: cpu-sleep-1-1 {
+ compatible = "arm,idle-state";
+ idle-state-name = "big-pll-power-down";
+ arm,psci-suspend-param = <0x40000004>;
+ entry-latency-us = <526>;
+ exit-latency-us = <1854>;
+ min-residency-us = <5555>;
+ local-timer-stop;
+ };
+ };
+
+ domain_idle_states: domain-idle-states {
+ cluster_sleep_apss_off: cluster-sleep-0 {
+ compatible = "domain-idle-state";
+ idle-state-name = "cluster-power-down";
+ arm,psci-suspend-param = <0x41000044>;
+ entry-latency-us = <2752>;
+ exit-latency-us = <3038>;
+ min-residency-us = <6118>;
+ };
+ };
+
l3: l3-cache {
compatible = "cache";
cache-level = <3>;
@@ -144,6 +207,35 @@ pmu-a78c {
psci {
compatible = "arm,psci-1.0";
method = "smc";
+
+ cpu_pd0: power-domain-cpu0 {
+ #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
+ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+ };
+
+ cpu_pd1: power-domain-cpu1 {
+ #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
+ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+ };
+
+ cpu_pd2: power-domain-cpu2 {
+ #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
+ domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+ };
+
+ cpu_pd3: power-domain-cpu3 {
+ #power-domain-cells = <0>;
+ power-domains = <&cluster_pd>;
+ domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+ };
+
+ cluster_pd: power-domain-cluster {
+ #power-domain-cells = <0>;
+ domain-idle-states = <&cluster_sleep_apss_off>;
+ };
};
rpm: remoteproc {
@@ -217,8 +309,8 @@ mpm: interrupt-controller {
mboxes = <&apcs_glb 1>;
interrupt-controller;
#interrupt-cells = <2>;
- #power-domain-cells = <0>;
interrupt-parent = <&intc>;
+ power-domains = <&cluster_pd>;
qcom,mpm-pin-count = <96>;
qcom,mpm-pin-map = <2 275>, /* TSENS0 uplow */
<12 422>, /* DWC3 ss_phy_irq */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 7/7] arm64: dts: qcom: shikra: Add CPU idle states
2026-07-13 10:25 ` [PATCH 7/7] arm64: dts: qcom: shikra: Add CPU idle states Sneh Mankad
@ 2026-07-15 10:02 ` Konrad Dybcio
0 siblings, 0 replies; 21+ messages in thread
From: Konrad Dybcio @ 2026-07-15 10:02 UTC (permalink / raw)
To: Sneh Mankad, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Thomas Gleixner, Shawn Guo,
Marc Zyngier
Cc: linux-arm-msm, devicetree, linux-kernel
On 7/13/26 12:25 PM, Sneh Mankad wrote:
> Add idle states for the CPUs as well as the whole cluster. This enables
> deeper-than-WFI cpuidle.
>
> Add MPM under cluster_pd power domain.
>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> ---
[...]
> + domain_idle_states: domain-idle-states {
> + cluster_sleep_apss_off: cluster-sleep-0 {
> + compatible = "domain-idle-state";
> + idle-state-name = "cluster-power-down";
> + arm,psci-suspend-param = <0x41000044>;
> + entry-latency-us = <2752>;
> + exit-latency-us = <3038>;
> + min-residency-us = <6118>;
> + };
> + };
Is this really the deepest state available on Shikra?
Konrad
^ permalink raw reply [flat|nested] 21+ messages in thread