Linux Power Management development
 help / color / mirror / Atom feed
* [PATCH v3 1/2] dt-bindings: power: reset: cortina,gemini-power-controller: convert to DT schema
From: Khushal Chitturi @ 2026-03-30 11:01 UTC (permalink / raw)
  To: sre, robh, krzk+dt, conor+dt, ulli.kroll, linusw
  Cc: daniel.baluta, simona.toaca, d-gole, m-chawdhry, linux-pm,
	devicetree, linux-arm-kernel, linux-kernel, Khushal Chitturi
In-Reply-To: <20260330110135.10316-1-khushalchitturi@gmail.com>

Convert the Cortina Systems Gemini Poweroff Controller bindings to
DT schema.

Signed-off-by: Khushal Chitturi <khushalchitturi@gmail.com>
---
Changelog:
v2 -> v3:
- Used generic node name "poweroff" instead of "gemini-poweroff".
v1 -> v2:
- Renamed the node from "power-controller" to "gemini-poweroff" to resolve dtschema warnings.

Note:
* This patch series is part of the GSoC2026 application process for device tree bindings conversions
* https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings

 .../cortina,gemini-power-controller.yaml      | 42 +++++++++++++++++++
 .../bindings/power/reset/gemini-poweroff.txt  | 17 --------
 2 files changed, 42 insertions(+), 17 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/reset/cortina,gemini-power-controller.yaml
 delete mode 100644 Documentation/devicetree/bindings/power/reset/gemini-poweroff.txt

diff --git a/Documentation/devicetree/bindings/power/reset/cortina,gemini-power-controller.yaml b/Documentation/devicetree/bindings/power/reset/cortina,gemini-power-controller.yaml
new file mode 100644
index 000000000000..ef5e04f86be1
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/cortina,gemini-power-controller.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/reset/cortina,gemini-power-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cortina Systems Gemini Poweroff Controller
+
+maintainers:
+  - Linus Walleij <linusw@kernel.org>
+
+description: |
+  The Gemini power controller is a dedicated IP block in the Cortina Gemini SoC that
+  controls system power-down operations.
+
+properties:
+  compatible:
+    const: cortina,gemini-power-controller
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    poweroff@4b000000 {
+      compatible = "cortina,gemini-power-controller";
+      reg = <0x4b000000 0x100>;
+      interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/power/reset/gemini-poweroff.txt b/Documentation/devicetree/bindings/power/reset/gemini-poweroff.txt
deleted file mode 100644
index 7fec3e100214..000000000000
--- a/Documentation/devicetree/bindings/power/reset/gemini-poweroff.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-* Device-Tree bindings for Cortina Systems Gemini Poweroff
-
-This is a special IP block in the Cortina Gemini SoC that only
-deals with different ways to power the system down.
-
-Required properties:
-- compatible: should be "cortina,gemini-power-controller"
-- reg: should contain the physical memory base and size
-- interrupts: should contain the power management interrupt
-
-Example:
-
-power-controller@4b000000 {
-	compatible = "cortina,gemini-power-controller";
-	reg = <0x4b000000 0x100>;
-	interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
-};
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 0/2] dt-bindings: power: reset: cortina: Convert to DT schema and rename node
From: Khushal Chitturi @ 2026-03-30 11:01 UTC (permalink / raw)
  To: sre, robh, krzk+dt, conor+dt, ulli.kroll, linusw
  Cc: daniel.baluta, simona.toaca, d-gole, m-chawdhry, linux-pm,
	devicetree, linux-arm-kernel, linux-kernel, Khushal Chitturi

Convert the Cortina Systems Gemini Poweroff Controller bindings to
DT schema and update corresponding dtsi file with new node name

---
Khushal Chitturi (2):
  dt-bindings: power: reset: cortina,gemini-power-controller: convert to
    DT schema
  ARM: dts: gemini: Rename power controller node to poweroff

 .../cortina,gemini-power-controller.yaml      | 42 +++++++++++++++++++
 .../bindings/power/reset/gemini-poweroff.txt  | 17 --------
 arch/arm/boot/dts/gemini/gemini.dtsi          |  2 +-
 3 files changed, 43 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/reset/cortina,gemini-power-controller.yaml
 delete mode 100644 Documentation/devicetree/bindings/power/reset/gemini-poweroff.txt

-- 
2.53.0


^ permalink raw reply

* Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters
From: Dmitry Baryshkov @ 2026-03-30 10:59 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Richard Acayan, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Amit Kucheria, Thara Gopinath, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-pm, devicetree
In-Reply-To: <91af3fa3-85ba-44b8-8725-032f77c846de@oss.qualcomm.com>

On Mon, Mar 30, 2026 at 12:32:29PM +0200, Konrad Dybcio wrote:
> On 3/29/26 12:44 PM, Dmitry Baryshkov wrote:
> > On Fri, Mar 27, 2026 at 09:40:40PM -0400, Richard Acayan wrote:
> >> The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but
> >> some SoCs divide the CPUs into different sizes of clusters. In SDM670,
> >> the first 6 CPUs are in the little cluster and the next 2 are in the big
> >> cluster. Define the clusters in the match data and define the different
> >> cluster configuration for SDM670.
> >>
> >> Currently, this only supports 8 CPUs and tolerates linking to any CPU in
> >> the cluster.
> >>
> >> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
> >> ---
> >>  drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
> >>  1 file changed, 56 insertions(+), 13 deletions(-)
> >>
> >> +static const struct lmh_soc_data sdm670_lmh_data = {
> >> +	.enable_algos = true,
> >> +	.node_ids = {
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +	},
> >> +};
> >> +
> >> +static const struct lmh_soc_data sdm845_lmh_data = {
> >> +	.enable_algos = true,
> >> +	.node_ids = {
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +	},
> >> +};
> > 
> > These tables made me wonder, can we determine this information from the
> > DT? For example, by reading the qcom,freq-domain property. But...
> > 
> >> +
> >> +static const struct lmh_soc_data sm8150_lmh_data = {
> >> +	.enable_algos = false,
> >> +	.node_ids = {
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER0_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +		LMH_CLUSTER1_NODE_ID,
> >> +	},
> >> +};
> > 
> > ... this might be problematic, unless this entry is broken. On SM8150 we
> > have three freq domains, but up to now we were programming two clustern
> > nodes. Of course it is possible to define that node_id is 0 for freq
> > domain 0 and 1 for domains 1 and 2.
> 
> The third cluster situation on 8150 is not super good - we e.g. only have
> a single LMH irq that's shared between the big and prime cores. That
> was fixed with later SoCs (which is why it's not wired up in the DT today)

Thanks!

Anyway, from your point of view, would it be better to define mappings
in the driver (like it's done with this patch) or parse the DT?

> Funnily enough the bigger 8180 didn't have that problem because it only had
> 2 freq domains

Yep.

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH v8 02/10] dt-bindings: power: samsung: add google,gs101-pd
From: André Draszik @ 2026-03-30 10:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Ulf Hansson, Liam Girdwood, Mark Brown, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm
In-Reply-To: <b66d7230-a495-40a4-ac75-378d0727afed@kernel.org>

On Mon, 2026-03-30 at 12:55 +0200, Krzysztof Kozlowski wrote:
> On 30/03/2026 12:52, André Draszik wrote:
> > > Your patchset is organized in odd way - first patch for me, then not for
> > > me, then again two patches for me. Please keep it consistent. Or better,
> > > decouple since there are no dependencies according to cover letter.
> > 
> > I'll update the cover letter to describe the dependencies. 4 depends on 2,
> 
> 
> How 4 (soc) patch depends on 2 (pm domains)? What is exactly the dependency?

4 updates the soc-level pmu binding of gs101 to have gs101-power-domain
child-nodes, which are introduced in 2

A.

^ permalink raw reply

* Re: [PATCH v8 07/10] pmdomain: samsung: add support for google,gs101-pd
From: André Draszik @ 2026-03-30 10:55 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Ulf Hansson, Liam Girdwood, Mark Brown, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm, Marek Szyprowski
In-Reply-To: <177409897341.266364.10743294916208405425.b4-review@b4>

On Sat, 2026-03-21 at 14:16 +0100, Krzysztof Kozlowski wrote:
> On Wed, 18 Mar 2026 15:27:52 +0000, André Draszik <andre.draszik@linaro.org> wrote:
> > On Google gs101, direct mmio register access to the PMU registers
> > doesn't work and access must happen via a regmap created by the PMU
> > driver instead.
> > 
> > Add a flag to the device match data to denote this case, and obtain
> > the regmap using the parent node in DT if true, while keeping to use
> > the traditional direct mmio regmap otherwise.
> > 
> > Additionally, the status is just one bit on gs101.
> > 
> > Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > Signed-off-by: André Draszik <andre.draszik@linaro.org>
> 
> There are few reviews from Sashiko which seem legitimate. Please check
> them. If they are false positives, just reply that you carefully went
> through them.

Thanks for pointing out Sashiko, seems like a useful tool! I'll go
through it.

A.

^ permalink raw reply

* Re: [PATCH v8 02/10] dt-bindings: power: samsung: add google,gs101-pd
From: Krzysztof Kozlowski @ 2026-03-30 10:55 UTC (permalink / raw)
  To: André Draszik
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Ulf Hansson, Liam Girdwood, Mark Brown, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm
In-Reply-To: <6f0be0a71c74e7a7959e9ad02e93aff1cb8ef712.camel@linaro.org>

On 30/03/2026 12:52, André Draszik wrote:
>> Your patchset is organized in odd way - first patch for me, then not for
>> me, then again two patches for me. Please keep it consistent. Or better,
>> decouple since there are no dependencies according to cover letter.
> 
> I'll update the cover letter to describe the dependencies. 4 depends on 2,


How 4 (soc) patch depends on 2 (pm domains)? What is exactly the dependency?

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v8 05/10] pmdomain: samsung: convert to using regmap
From: André Draszik @ 2026-03-30 10:53 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Ulf Hansson, Liam Girdwood, Mark Brown, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm, Marek Szyprowski
In-Reply-To: <177409897341.266364.2957933304869869135.b4-review@b4>

On Sat, 2026-03-21 at 14:16 +0100, Krzysztof Kozlowski wrote:
> On Wed, 18 Mar 2026 15:27:50 +0000, André Draszik <andre.draszik@linaro.org> wrote:
> > diff --git a/drivers/pmdomain/samsung/exynos-pm-domains.c b/drivers/pmdomain/samsung/exynos-pm-domains.c
> > index 5c3aa8983087..68b1e7ba8729 100644
> > --- a/drivers/pmdomain/samsung/exynos-pm-domains.c
> > +++ b/drivers/pmdomain/samsung/exynos-pm-domains.c
> > @@ -120,9 +140,26 @@ static int exynos_pd_probe(struct platform_device *pdev)
> > [ ... skip 20 lines ... ]
> > +
> > +	reg_config.max_register = resource_size(res) - reg_config.reg_stride;
> > +	pd->regmap = devm_regmap_init_mmio(dev, base, &reg_config);
> > +	if (IS_ERR(pd->regmap))
> > +		return dev_err_probe(dev, PTR_ERR(base),
> > +				     "failed to init regmap\n");
> 
> PTR_ERR(pd->regmap)

Thanks!

A.

^ permalink raw reply

* Re: [PATCH v8 02/10] dt-bindings: power: samsung: add google,gs101-pd
From: André Draszik @ 2026-03-30 10:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Ulf Hansson, Liam Girdwood, Mark Brown, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm
In-Reply-To: <177409897339.266364.69715997034739052.b4-review@b4>

Hi Krzysztof,


On Sat, 2026-03-21 at 14:16 +0100, Krzysztof Kozlowski wrote:
> On Wed, 18 Mar 2026 15:27:47 +0000, André Draszik <andre.draszik@linaro.org> wrote:
> > diff --git a/Documentation/devicetree/bindings/power/pd-samsung.yaml b/Documentation/devicetree/bindings/power/pd-samsung.yaml
> > index 9c2c51133457..3f1a2dc17862 100644
> > --- a/Documentation/devicetree/bindings/power/pd-samsung.yaml
> > +++ b/Documentation/devicetree/bindings/power/pd-samsung.yaml
> > @@ -44,11 +45,28 @@ properties:
> >    power-domains:
> >      maxItems: 1
> >  
> > +  samsung,dtzpc:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      Distributed TrustZone Protection Control (DTZPC) node.
> 
> For what purpose?

It is part of the domain.

Furthermore, TZ configuration is lost as part of power-domain power
cycle, so this allows a driver to take necessary actions (inform the
EL3 firmware). I believe this handle to be similar to e.g. the existing
samsung,sysreg

> Your patchset is organized in odd way - first patch for me, then not for
> me, then again two patches for me. Please keep it consistent. Or better,
> decouple since there are no dependencies according to cover letter.

I'll update the cover letter to describe the dependencies. 4 depends on 2,
and 2 depends on 1, hence the ordering.


Cheers,
Andre

^ permalink raw reply

* Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters
From: Konrad Dybcio @ 2026-03-30 10:32 UTC (permalink / raw)
  To: Dmitry Baryshkov, Richard Acayan
  Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Amit Kucheria,
	Thara Gopinath, Bjorn Andersson, Konrad Dybcio, linux-arm-msm,
	linux-pm, devicetree
In-Reply-To: <a3rrkgvkc4zxcq5oqvws23lyjy6dinlmfgp34wzguvdxdxig5f@25atyxc7zabm>

On 3/29/26 12:44 PM, Dmitry Baryshkov wrote:
> On Fri, Mar 27, 2026 at 09:40:40PM -0400, Richard Acayan wrote:
>> The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but
>> some SoCs divide the CPUs into different sizes of clusters. In SDM670,
>> the first 6 CPUs are in the little cluster and the next 2 are in the big
>> cluster. Define the clusters in the match data and define the different
>> cluster configuration for SDM670.
>>
>> Currently, this only supports 8 CPUs and tolerates linking to any CPU in
>> the cluster.
>>
>> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
>> ---
>>  drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
>>  1 file changed, 56 insertions(+), 13 deletions(-)
>>
>> +static const struct lmh_soc_data sdm670_lmh_data = {
>> +	.enable_algos = true,
>> +	.node_ids = {
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +	},
>> +};
>> +
>> +static const struct lmh_soc_data sdm845_lmh_data = {
>> +	.enable_algos = true,
>> +	.node_ids = {
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +	},
>> +};
> 
> These tables made me wonder, can we determine this information from the
> DT? For example, by reading the qcom,freq-domain property. But...
> 
>> +
>> +static const struct lmh_soc_data sm8150_lmh_data = {
>> +	.enable_algos = false,
>> +	.node_ids = {
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER0_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +		LMH_CLUSTER1_NODE_ID,
>> +	},
>> +};
> 
> ... this might be problematic, unless this entry is broken. On SM8150 we
> have three freq domains, but up to now we were programming two clustern
> nodes. Of course it is possible to define that node_id is 0 for freq
> domain 0 and 1 for domains 1 and 2.

The third cluster situation on 8150 is not super good - we e.g. only have
a single LMH irq that's shared between the big and prime cores. That
was fixed with later SoCs (which is why it's not wired up in the DT today)

Funnily enough the bigger 8180 didn't have that problem because it only had
2 freq domains

Konrad

^ permalink raw reply

* Re: (subset) [PATCH v8 00/10] pmdomain: samsung: add support for Google GS101
From: Krzysztof Kozlowski @ 2026-03-30 10:17 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Liam Girdwood, Mark Brown, André Draszik, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm, Marek Szyprowski
In-Reply-To: <CAPDyKFrK3NLwaii-9FEmyaTzUAuVkMkLL3rWBQwQvT-M+PzEHA@mail.gmail.com>

On 30/03/2026 12:13, Ulf Hansson wrote:
> On Mon, 30 Mar 2026 at 11:54, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>> On 23/03/2026 12:13, Ulf Hansson wrote:
>>> Hi Krzysztof,
>>>
>>> On Sat, 21 Mar 2026 at 14:18, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>>
>>>>
>>>> On Wed, 18 Mar 2026 15:27:45 +0000, André Draszik wrote:
>>>>> This series adds support for the power domains on Google GS101.
>>>>>
>>>>> There are a few differences compared to SoCs already supported by this
>>>>> driver:
>>>>> * register access does not work via plain ioremap() / readl() /
>>>>>   writel().
>>>>>   Instead, the regmap created by the PMU driver must be used (which
>>>>>   uses Arm SMCC calls under the hood).
>>>>> * DTZPC: a call needs to be made before and after power domain off/on,
>>>>>   to inform the EL3 firmware of the request.
>>>>> * power domains can and are fed by a regulator rail and therefore
>>>>>   regulator control needed be implemented.
>>>>>
>>>>> [...]
>>>>
>>>> Applied, thanks!
>>>>
>>>> [01/10] dt-bindings: soc: google: add google,gs101-dtzpc
>>>>         https://git.kernel.org/krzk/linux/c/10084aeadadfab72648f6ed1cc78f7cd87b861ba
>>>> [03/10] dt-bindings: soc: samsung: exynos-pmu: move gs101-pmu into separate binding
>>>>         https://git.kernel.org/krzk/linux/c/3ec3c42b426fe5e2b48ff19c551dec50bc78788c
>>>> [04/10] dt-bindings: soc: google: gs101-pmu: allow power domains as children
>>>>         https://git.kernel.org/krzk/linux/c/c8229a5160eea145b796f54317d6e659cec9b080
>>>>
>>>> Best regards,
>>>
>>> Usually I pick up the power-domain related changes for the DT bindings
>>> and host them via an immutable branch called "dt". If needed, SOC
>>> maintainers can pull it to apply/test the corresponding DTS changes.
>>>
>>> That said, I am open to whatever you think is best here. Perhaps it's
>>> easier if you can drop the DT patches and provide your acks instead or
>>> if you can share them via an immutable branch for me to pull?
>>
>>
>> I did not pick up any pmdomain binding patches. I picked up only soc and
>> according to cover letter there are no dependencies between anything here.
> 
> As I understand it, they are all related and some even depend on each

I raised exactly that questions but no answers.

> other. I think keeping all four DT patches together makes sense.

Why? What is the dependency?

> 
> Although, as I said, if you think it's best to funnel them through
> your tree, please do and then share them via an immutable branch, so I
> can apply the pmdomain driver changes.

soc must go via my tree, but there is no reason to take the pmdomain
binding patch. So I did not take.

But anyway, I just noticed that I dropped everything: this introduces
new warnings which were nowhere addressed or explained. So regardless
how this should go, please do not apply anything - it's broken and
author is silent.


Best regards,
Krzysztof

^ permalink raw reply

* Re: (subset) [PATCH v8 00/10] pmdomain: samsung: add support for Google GS101
From: Ulf Hansson @ 2026-03-30 10:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Liam Girdwood, Mark Brown, André Draszik, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm, Marek Szyprowski
In-Reply-To: <1fbf5c54-8793-4585-be33-ded77019adb2@kernel.org>

On Mon, 30 Mar 2026 at 11:54, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 23/03/2026 12:13, Ulf Hansson wrote:
> > Hi Krzysztof,
> >
> > On Sat, 21 Mar 2026 at 14:18, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >>
> >>
> >> On Wed, 18 Mar 2026 15:27:45 +0000, André Draszik wrote:
> >>> This series adds support for the power domains on Google GS101.
> >>>
> >>> There are a few differences compared to SoCs already supported by this
> >>> driver:
> >>> * register access does not work via plain ioremap() / readl() /
> >>>   writel().
> >>>   Instead, the regmap created by the PMU driver must be used (which
> >>>   uses Arm SMCC calls under the hood).
> >>> * DTZPC: a call needs to be made before and after power domain off/on,
> >>>   to inform the EL3 firmware of the request.
> >>> * power domains can and are fed by a regulator rail and therefore
> >>>   regulator control needed be implemented.
> >>>
> >>> [...]
> >>
> >> Applied, thanks!
> >>
> >> [01/10] dt-bindings: soc: google: add google,gs101-dtzpc
> >>         https://git.kernel.org/krzk/linux/c/10084aeadadfab72648f6ed1cc78f7cd87b861ba
> >> [03/10] dt-bindings: soc: samsung: exynos-pmu: move gs101-pmu into separate binding
> >>         https://git.kernel.org/krzk/linux/c/3ec3c42b426fe5e2b48ff19c551dec50bc78788c
> >> [04/10] dt-bindings: soc: google: gs101-pmu: allow power domains as children
> >>         https://git.kernel.org/krzk/linux/c/c8229a5160eea145b796f54317d6e659cec9b080
> >>
> >> Best regards,
> >
> > Usually I pick up the power-domain related changes for the DT bindings
> > and host them via an immutable branch called "dt". If needed, SOC
> > maintainers can pull it to apply/test the corresponding DTS changes.
> >
> > That said, I am open to whatever you think is best here. Perhaps it's
> > easier if you can drop the DT patches and provide your acks instead or
> > if you can share them via an immutable branch for me to pull?
>
>
> I did not pick up any pmdomain binding patches. I picked up only soc and
> according to cover letter there are no dependencies between anything here.

As I understand it, they are all related and some even depend on each
other. I think keeping all four DT patches together makes sense.

Although, as I said, if you think it's best to funnel them through
your tree, please do and then share them via an immutable branch, so I
can apply the pmdomain driver changes.

Kind regards
Uffe

^ permalink raw reply

* Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters
From: Konrad Dybcio @ 2026-03-30 10:04 UTC (permalink / raw)
  To: Richard Acayan, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Amit Kucheria, Thara Gopinath, Bjorn Andersson, Konrad Dybcio,
	linux-arm-msm, linux-pm, devicetree
In-Reply-To: <20260328014041.83777-4-mailingradian@gmail.com>

On 3/28/26 2:40 AM, Richard Acayan wrote:
> The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but
> some SoCs divide the CPUs into different sizes of clusters. In SDM670,
> the first 6 CPUs are in the little cluster and the next 2 are in the big
> cluster. Define the clusters in the match data and define the different
> cluster configuration for SDM670.
> 
> Currently, this only supports 8 CPUs and tolerates linking to any CPU in
> the cluster.
> 
> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
> ---
>  drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
>  1 file changed, 56 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c
> index 3d072b7a4a6d..46c1e301f6c8 100644
> --- a/drivers/thermal/qcom/lmh.c
> +++ b/drivers/thermal/qcom/lmh.c
> @@ -30,14 +30,17 @@
>  
>  #define LMH_REG_DCVS_INTR_CLR		0x8
>  
> -#define LMH_ENABLE_ALGOS		1
> -
>  struct lmh_hw_data {
>  	void __iomem *base;
>  	struct irq_domain *domain;
>  	int irq;
>  };
>  
> +struct lmh_soc_data {
> +	bool enable_algos;
> +	u32 node_ids[8];

u32 clus1_start_idx or something similar denoting the first CPU index
in the second cluster?

Konrad

^ permalink raw reply

* Re: (subset) [PATCH v8 00/10] pmdomain: samsung: add support for Google GS101
From: Krzysztof Kozlowski @ 2026-03-30  9:54 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Alim Akhtar, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
	Liam Girdwood, Mark Brown, André Draszik, Peter Griffin,
	Tudor Ambarus, Juan Yescas, Will McVicker, kernel-team,
	linux-arm-kernel, linux-samsung-soc, devicetree, linux-kernel,
	linux-pm, Marek Szyprowski
In-Reply-To: <CAPDyKFoz-sm0pfvn5iSYFY0mrW38vaGRZsFvrVPqsv7BsYxeWQ@mail.gmail.com>

On 23/03/2026 12:13, Ulf Hansson wrote:
> Hi Krzysztof,
> 
> On Sat, 21 Mar 2026 at 14:18, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>>
>> On Wed, 18 Mar 2026 15:27:45 +0000, André Draszik wrote:
>>> This series adds support for the power domains on Google GS101.
>>>
>>> There are a few differences compared to SoCs already supported by this
>>> driver:
>>> * register access does not work via plain ioremap() / readl() /
>>>   writel().
>>>   Instead, the regmap created by the PMU driver must be used (which
>>>   uses Arm SMCC calls under the hood).
>>> * DTZPC: a call needs to be made before and after power domain off/on,
>>>   to inform the EL3 firmware of the request.
>>> * power domains can and are fed by a regulator rail and therefore
>>>   regulator control needed be implemented.
>>>
>>> [...]
>>
>> Applied, thanks!
>>
>> [01/10] dt-bindings: soc: google: add google,gs101-dtzpc
>>         https://git.kernel.org/krzk/linux/c/10084aeadadfab72648f6ed1cc78f7cd87b861ba
>> [03/10] dt-bindings: soc: samsung: exynos-pmu: move gs101-pmu into separate binding
>>         https://git.kernel.org/krzk/linux/c/3ec3c42b426fe5e2b48ff19c551dec50bc78788c
>> [04/10] dt-bindings: soc: google: gs101-pmu: allow power domains as children
>>         https://git.kernel.org/krzk/linux/c/c8229a5160eea145b796f54317d6e659cec9b080
>>
>> Best regards,
> 
> Usually I pick up the power-domain related changes for the DT bindings
> and host them via an immutable branch called "dt". If needed, SOC
> maintainers can pull it to apply/test the corresponding DTS changes.
> 
> That said, I am open to whatever you think is best here. Perhaps it's
> easier if you can drop the DT patches and provide your acks instead or
> if you can share them via an immutable branch for me to pull?


I did not pick up any pmdomain binding patches. I picked up only soc and
according to cover letter there are no dependencies between anything here.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v3 2/3] thermal: spacemit: k1: Add thermal sensor support
From: Troy Mitchell @ 2026-03-30  9:42 UTC (permalink / raw)
  To: Shuwei Wu, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Yixun Lan, Philipp Zabel, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti
  Cc: linux-pm, devicetree, linux-riscv, spacemit, linux-kernel,
	Troy Mitchell
In-Reply-To: <20260119-patchv2-k1-thermal-v3-2-3d82c9ebe8a4@163.com>

On Mon, Jan 19, 2026 at 10:41:22 CST, Shuwei Wu wrote:
> The thermal sensor on K1 supports monitoring five temperature zones.
> The driver registers these sensors with the thermal framework
> and supports standard operations:
> - Reading temperature (millidegree Celsius)
> - Setting high/low thresholds for interrupts
> 
> Signed-off-by: Shuwei Wu <shuweiwoo@163.com>
Thanks for your patch.

Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>

^ permalink raw reply

* Re: [PATCH v3 7/9] regulator: mt6392: Add support for MT6392 regulator
From: Chen-Yu Tsai @ 2026-03-30  9:35 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Fabien Parent, Val Packett, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sen Chu,
	Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	AngeloGioacchino Del Regno, Linus Walleij, Liam Girdwood,
	Mark Brown, Gary Bisson, Louis-Alexis Eyraud, Julien Massot,
	Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, linux-gpio
In-Reply-To: <CAORyz2J355NZH=7iQ9sTDBhAmtjP7xTpXe21_3Z9J_R5YvdXAQ@mail.gmail.com>

On Mon, Mar 30, 2026 at 3:39 PM Luca Leonardo Scorcia
<l.scorcia@gmail.com> wrote:
>
> Il giorno gio 19 mar 2026 alle ore 06:04 Chen-Yu Tsai
> <wenst@chromium.org> ha scritto:
>
> > If this PMIC is anything like the MT6358, then it has 0.01V fine
> > tuning for most if not all the LDOs. It is sometimes needed as
> > a rail may have a 0.04V boost that would otherwise be invisible
> > to the system. And then if you have something like 3.04V set in
> > the DT constraints, you end up with something the regulator driver
> > doesn't support, but the hardware does.
> >
> > Please see how it's done in the MT6358 driver. I spent a lot of
> > time on that driver to make it actually support the full range
> > of voltages, and describing the supplies.
> >
>
> I had a good look at the datasheet (MT6392 PMIC Datasheet v1.0 08 Dec.
> 2016) and unfortunately I did not see any fine tuning option in there.
> I'm sure this data sheet is not perfect as it's missing some regulator
> registers that are clearly used in the Android sources, but there's no
> mention of fine tuning in that code either. I guess it does not have
> that capability.

Well, thanks for looking. FWIW on the MT6358 / MT6366, the main voltage
control and the fine tuning are mostly in the same register. The fine
tuning is described as "calibrates output voltage" from +00mV to +100mV.

I looked into this because the LDO table shows some of the default voltages
with 0.01V precision, but the main voltage controls only have 0.1V precision.


ChenYu

> I will shortly submit v4 that hopefully addresses the rest of the comments.
>
> Thanks for your help!
> --
> Luca Leonardo Scorcia
> l.scorcia@gmail.com

^ permalink raw reply

* Re: [PATCH 1/7] dt-bindings: power: qcom-rpmpd: Split MSM8953 and SDM632
From: Konrad Dybcio @ 2026-03-30  9:24 UTC (permalink / raw)
  To: Barnabás Czémán, Dmitry Baryshkov
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Ulf Hansson, Mathieu Poirier, Konrad Dybcio, Stephan Gerhold,
	linux-arm-msm, devicetree, linux-kernel, linux-pm,
	linux-remoteproc
In-Reply-To: <39a320e472ddc6d44c950a995b577e77@mainlining.org>

On 3/28/26 9:22 AM, Barnabás Czémán wrote:
> On 2026-03-27 21:26, Dmitry Baryshkov wrote:
>> On Fri, Mar 27, 2026 at 09:11:43PM +0100, Barnabás Czémán wrote:
>>> Remove modem related bindings from MSM8953 rpmpd because MSM8953 MSS
>>> is using mss-supply as a regulator usually it is pm8953_s1.
>>> Split SDM632 bindings from MSM8953 because SDM632 is using mss-supply
>>> as a pm domain.
>>>
>>> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
>>> ---
>>>  .../devicetree/bindings/power/qcom,rpmpd.yaml        |  1 +
>>>  include/dt-bindings/power/qcom-rpmpd.h               | 20 +++++++++++++-------
>>>  2 files changed, 14 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>>> index 8174ceeab572..659936d6a46e 100644
>>> --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>>> +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
>>> @@ -48,6 +48,7 @@ properties:
>>>            - qcom,sc7280-rpmhpd
>>>            - qcom,sc8180x-rpmhpd
>>>            - qcom,sc8280xp-rpmhpd
>>> +          - qcom,sdm632-rpmpd
>>>            - qcom,sdm660-rpmpd
>>>            - qcom,sdm670-rpmhpd
>>>            - qcom,sdm845-rpmhpd
>>> diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
>>> index 4371ac941f29..2d82434b993c 100644
>>> --- a/include/dt-bindings/power/qcom-rpmpd.h
>>> +++ b/include/dt-bindings/power/qcom-rpmpd.h
>>> @@ -84,13 +84,11 @@
>>>  #define QM215_VDDMX_AO        MSM8917_VDDMX_AO
>>>
>>>  /* MSM8953 Power Domain Indexes */
>>> -#define MSM8953_VDDMD        0
>>> -#define MSM8953_VDDMD_AO    1
>>> -#define MSM8953_VDDCX        2
>>> -#define MSM8953_VDDCX_AO    3
>>> -#define MSM8953_VDDCX_VFL    4
>>> -#define MSM8953_VDDMX        5
>>> -#define MSM8953_VDDMX_AO    6
>>> +#define MSM8953_VDDCX        RPMPD_VDDCX
>>> +#define MSM8953_VDDCX_AO    RPMPD_VDDCX_AO
>>> +#define MSM8953_VDDCX_VFL    RPMPD_VDDCX_VFL
>>> +#define MSM8953_VDDMX        RPMPD_VDDMX
>>> +#define MSM8953_VDDMX_AO    RPMPD_VDDMX_AO
>>
>> Well, no. This is an ABI break. It will make previous DT to stop from
>> working. You can drop unused indices, but you can not change the values
>> used by the existing domains.
> Do these indices never can be changed?

Yes, values in include/dt-bindings are supposed to never change

Here you're e.g. changing the "msm8953 domain 0" from translating into
VDDMD to translating into VDDCX (because RPMPD_VDDCX is defined as 0)

Some other older platforms were converted to use these macros, because
the indices happened to match

Konrad

^ permalink raw reply

* Re: [PATCH v2] thermal: core: Address thermal zone removal races with resume
From: Lukasz Luba @ 2026-03-30  9:15 UTC (permalink / raw)
  To: Rafael J. Wysocki, Mauricio Faria de Oliveira
  Cc: Daniel Lezcano, LKML, Linux PM
In-Reply-To: <6267615.lOV4Wx5bFT@rafael.j.wysocki>



On 3/27/26 09:49, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Since thermal_zone_pm_complete() and thermal_zone_device_resume()
> re-initialize the poll_queue delayed work for the given thermal zone,
> the cancel_delayed_work_sync() in thermal_zone_device_unregister()
> may miss some already running work items and the thermal zone may
> be freed prematurely [1].
> 
> There are two failing scenarios that both start with
> running thermal_pm_notify_complete() right before invoking
> thermal_zone_device_unregister() for one of the thermal zones.
> 
> In the first scenario, there is a work item already running for
> the given thermal zone when thermal_pm_notify_complete() calls
> thermal_zone_pm_complete() for that thermal zone and it continues to
> run when thermal_zone_device_unregister() starts.  Since the poll_queue
> delayed work has been re-initialized by thermal_pm_notify_complete(), the
> running work item will be missed by the cancel_delayed_work_sync() in
> thermal_zone_device_unregister() and if it continues to run past the
> freeing of the thermal zone object, a use-after-free will occur.
> 
> In the second scenario, thermal_zone_device_resume() queued up by
> thermal_pm_notify_complete() runs right after the thermal_zone_exit()
> called by thermal_zone_device_unregister() has returned.  The poll_queue
> delayed work is re-initialized by it before cancel_delayed_work_sync() is
> called by thermal_zone_device_unregister(), so it may continue to run
> after the freeing of the thermal zone object, which also leads to a
> use-after-free.
> 
> Address the first failing scenario by ensuring that no thermal work
> items will be running when thermal_pm_notify_complete() is called.
> For this purpose, first move the cancel_delayed_work() call from
> thermal_zone_pm_complete() to thermal_zone_pm_prepare() to prevent
> new work from entering the workqueue going forward.  Next, switch
> over to using a dedicated workqueue for thermal events and update
> the code in thermal_pm_notify() to flush that workqueue after
> thermal_pm_notify_prepare() has returned which will take care of
> all leftover thermal work already on the workqueue (that leftover
> work would do nothing useful anyway because all of the thermal zones
> have been flagged as suspended).
> 
> The second failing scenario is addressed by adding a tz->state check
> to thermal_zone_device_resume() to prevent it from re-initializing
> the poll_queue delayed work if the thermal zone is going away.
> 
> Note that the above changes will also facilitate relocating the suspend
> and resume of thermal zones closer to the suspend and resume of devices,
> respectively.
> 
> Fixes: 5a5efdaffda5 ("thermal: core: Resume thermal zones asynchronously")
> Reported-by: Mauricio Faria de Oliveira <mfo@igalia.com>
> Closes: https://lore.kernel.org/linux-pm/20260324-thermal-core-uaf-init_delayed_work-v1-1-6611ae76a8a1@igalia.com/ [1]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> 
> v1 -> v2: Return -ENOMEM from thermal_init() when the workqueue allocation
>     fails (Sashiko)
> 
> Lukasz, Daniel, I'm quite confident about this patch, but I would appreciate
> your feedback.

My apologies for delay...

> 
> ---
>   drivers/thermal/thermal_core.c |   31 ++++++++++++++++++++++++++-----
>   1 file changed, 26 insertions(+), 5 deletions(-)
> 
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -42,6 +42,8 @@ static struct thermal_governor *def_gove
>   
>   static bool thermal_pm_suspended;
>   
> +static struct workqueue_struct *thermal_wq __ro_after_init;
> +
>   /*
>    * Governor section: set of functions to handle thermal governors
>    *
> @@ -314,7 +316,7 @@ static void thermal_zone_device_set_poll
>   	if (delay > HZ)
>   		delay = round_jiffies_relative(delay);
>   
> -	mod_delayed_work(system_freezable_power_efficient_wq, &tz->poll_queue, delay);
> +	mod_delayed_work(thermal_wq, &tz->poll_queue, delay);
>   }
>   
>   static void thermal_zone_recheck(struct thermal_zone_device *tz, int error)
> @@ -1795,6 +1797,10 @@ static void thermal_zone_device_resume(s
>   
>   	guard(thermal_zone)(tz);
>   
> +	/* If the thermal zone is going away, there's nothing to do. */
> +	if (tz->state & TZ_STATE_FLAG_EXIT)
> +		return;
> +
>   	tz->state &= ~(TZ_STATE_FLAG_SUSPENDED | TZ_STATE_FLAG_RESUMING);
>   
>   	thermal_debug_tz_resume(tz);
> @@ -1825,6 +1831,9 @@ static void thermal_zone_pm_prepare(stru
>   	}
>   
>   	tz->state |= TZ_STATE_FLAG_SUSPENDED;
> +
> +	/* Prevent new work from getting to the workqueue subsequently. */
> +	cancel_delayed_work(&tz->poll_queue);
>   }
>   
>   static void thermal_pm_notify_prepare(void)
> @@ -1843,8 +1852,6 @@ static void thermal_zone_pm_complete(str
>   {
>   	guard(thermal_zone)(tz);
>   
> -	cancel_delayed_work(&tz->poll_queue);
> -
>   	reinit_completion(&tz->resume);
>   	tz->state |= TZ_STATE_FLAG_RESUMING;
>   
> @@ -1854,7 +1861,7 @@ static void thermal_zone_pm_complete(str
>   	 */
>   	INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_resume);
>   	/* Queue up the work without a delay. */
> -	mod_delayed_work(system_freezable_power_efficient_wq, &tz->poll_queue, 0);
> +	mod_delayed_work(thermal_wq, &tz->poll_queue, 0);
>   }
>   
>   static void thermal_pm_notify_complete(void)
> @@ -1877,6 +1884,11 @@ static int thermal_pm_notify(struct noti
>   	case PM_RESTORE_PREPARE:
>   	case PM_SUSPEND_PREPARE:
>   		thermal_pm_notify_prepare();
> +		/*
> +		 * Allow any leftover thermal work items already on the
> +		 * worqueue to complete so they don't get in the way later.
> +		 */
> +		flush_workqueue(thermal_wq);
>   		break;
>   	case PM_POST_HIBERNATION:
>   	case PM_POST_RESTORE:
> @@ -1909,9 +1921,16 @@ static int __init thermal_init(void)
>   	if (result)
>   		goto error;
>   
> +	thermal_wq = alloc_workqueue("thermal_events",
> +				      WQ_FREEZABLE | WQ_POWER_EFFICIENT | WQ_PERCPU, 0);


Why we need those workqueue instances per-cpu?
It isn't a concurrent work, only one CPU can manage the cpufreq domain.

I would drop that flag and allow to have single instance and migrate
between cpus (to not wake up the one which queued the work).


> +	if (!thermal_wq) {
> +		result = -ENOMEM;
> +		goto unregister_netlink;
> +	}
> +
>   	result = thermal_register_governors();
>   	if (result)
> -		goto unregister_netlink;
> +		goto destroy_workqueue;
>   
>   	thermal_class = kzalloc_obj(*thermal_class);
>   	if (!thermal_class) {
> @@ -1938,6 +1957,8 @@ static int __init thermal_init(void)
>   
>   unregister_governors:
>   	thermal_unregister_governors();
> +destroy_workqueue:
> +	destroy_workqueue(thermal_wq);
>   unregister_netlink:
>   	thermal_netlink_exit();
>   error:
> 
> 
> 


^ permalink raw reply

* [PATCH v2 2/2] power_management: Remove unused tools
From: Petr Vorel @ 2026-03-30  9:08 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Li Wang, Cyril Hrubis, Jan Stancek, Andrea Cervesato,
	Daniel Lezcano, Rafael J . Wysocki, Zhang Rui, Lukasz Luba,
	linux-pm, helena.anna.dubel, tomasz.ossowski, Piotr Kubaj,
	automated-testing
In-Reply-To: <20260330090844.79598-1-pvorel@suse.cz>

Remove now unneeded tools and functions from pm_include.sh (see previous commit).
Also move functions from pm_include.sh used only in single shell script to it.

This removes the rest of python code in power management tests.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 testcases/kernel/power_management/Makefile    |   2 +-
 .../kernel/power_management/lib/Makefile      |  25 -
 .../power_management/lib/pm_sched_mc.py       | 835 ------------------
 .../kernel/power_management/pm_ilb_test.py    |  57 --
 .../kernel/power_management/pm_include.sh     | 311 +------
 .../power_management/pm_sched_domain.py       |  54 --
 .../kernel/power_management/runpwtests03.sh   |  10 +
 .../kernel/power_management/runpwtests06.sh   |  31 +
 8 files changed, 43 insertions(+), 1282 deletions(-)
 delete mode 100644 testcases/kernel/power_management/lib/Makefile
 delete mode 100755 testcases/kernel/power_management/lib/pm_sched_mc.py
 delete mode 100755 testcases/kernel/power_management/pm_ilb_test.py
 delete mode 100755 testcases/kernel/power_management/pm_sched_domain.py

diff --git a/testcases/kernel/power_management/Makefile b/testcases/kernel/power_management/Makefile
index 935f47eea1..4357bd9c29 100644
--- a/testcases/kernel/power_management/Makefile
+++ b/testcases/kernel/power_management/Makefile
@@ -26,4 +26,4 @@ INSTALL_TARGETS 	:= *.py *.sh
 
 MAKE_DEPS		+= $(APICMDS_DIR)/tst_kvercmp
 
-include $(top_srcdir)/include/mk/generic_trunk_target.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/power_management/lib/Makefile b/testcases/kernel/power_management/lib/Makefile
deleted file mode 100644
index 2aadac0a5b..0000000000
--- a/testcases/kernel/power_management/lib/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2015 Fujitsu Ltd.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-top_srcdir 		?= ../../../..
-
-include $(top_srcdir)/include/mk/env_pre.mk
-
-INSTALL_TARGETS 	:= *.py
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/power_management/lib/pm_sched_mc.py b/testcases/kernel/power_management/lib/pm_sched_mc.py
deleted file mode 100755
index 743b6debf3..0000000000
--- a/testcases/kernel/power_management/lib/pm_sched_mc.py
+++ /dev/null
@@ -1,835 +0,0 @@
-#!/usr/bin/env python3
-''' Reusable functions related to sched mc FVT are put together
-'''
-
-import os
-import sys
-import re
-from time import time
-
-__author__ = "Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>"
-__author__ = "Poornima Nayak <mpnayak@linux.vnet.ibm.com>"
-
-
-cpu_map = {}
-stats_start = {}
-stats_stop = {}
-stats_percentage = {}
-intr_start = []
-intr_stop = []
-cpu_count = 0
-socket_count = 0
-cpu1_max_intr = 0
-cpu2_max_intr = 0
-intr_stat_timer_0 = []
-siblings_list = []
-
-def clear_dmesg():
-    '''
-       Clears dmesg
-    '''
-    try:
-        os.system('dmesg -c >/dev/null')
-    except OSError as e:
-        print('Clearing dmesg failed', e)
-        sys.exit(1)
-
-def count_num_cpu():
-    ''' Returns number of cpu's in system
-    '''
-    try:
-        cpuinfo = open('/proc/cpuinfo', 'r')
-        global cpu_count
-        for line in cpuinfo:
-            if line.startswith('processor'):
-                cpu_count += 1
-        cpuinfo.close()
-    except IOError as e:
-        print("Could not get cpu count", e)
-        sys.exit(1)
-
-def count_num_sockets():
-    ''' Returns number of cpu's in system
-    '''
-    socket_list = []
-    global socket_count
-    try:
-        for i in range(0, cpu_count):
-            phy_pkg_file = '/sys/devices/system/cpu/cpu%s' % i
-            phy_pkg_file += '/topology/physical_package_id'
-            socket_id = open(phy_pkg_file).read().rstrip()
-            if socket_id not in socket_list:
-                socket_list.append(socket_id)
-                socket_count = socket_count + 1
-    except Exception as details:
-        print("INFO: Failed to get number of sockets in system", details)
-        sys.exit(1)
-
-def is_multi_socket():
-    '''Return 1 if the system is multi socket else return 0
-    '''
-    try:
-        if socket_count > 1:
-            return 1
-        else:
-            return 0
-    except Exception:
-        print("Failed to check if system is multi socket system")
-        sys.exit(1)
-
-def is_hyper_threaded():
-    '''Return 1 if the system is hyper threaded else return 0
-    '''
-    try:
-        file_cpuinfo = open("/proc/cpuinfo", 'r')
-        for line in file_cpuinfo:
-            if line.startswith('siblings'):
-                siblings = line.split(":")
-            if line.startswith('cpu cores'):
-                cpu_cores = line.split(":")
-                break
-        if int( siblings[1] ) / int( cpu_cores[1] )> 1:
-            file_cpuinfo.close()
-            return 1
-        else:
-            return 0
-    except Exception:
-        print("Failed to check if system is hyper-threaded")
-        sys.exit(1)
-
-def is_multi_core():
-    ''' Return true if system has sockets has multiple cores
-    '''
-
-    try:
-        file_cpuinfo = open("/proc/cpuinfo", 'r')
-        for line in file_cpuinfo:
-            if line.startswith('siblings'):
-                siblings = line.split(":")
-            if line.startswith('cpu cores'):
-                cpu_cores = line.split(":")
-                break
-
-        if int( siblings[1] ) == int( cpu_cores[1] ):
-            if int( cpu_cores[1] ) > 1:
-                multi_core = 1
-            else:
-                multi_core = 0
-        else:
-            num_of_cpus = int(siblings[1]) / int(cpu_cores[1])
-            if num_of_cpus > 1:
-                multi_core = 1
-            else:
-                multi_core = 0
-        file_cpuinfo.close()
-        return multi_core
-    except Exception:
-        print("Failed to check if system is multi core system")
-        sys.exit(1)
-
-def get_hyper_thread_count():
-    ''' Return number of threads in CPU. For eg for x3950 this function
-        would return 2. In future if 4 threads are supported in CPU, this
-        routine would return 4
-    '''
-    try:
-        file_cpuinfo = open("/proc/cpuinfo", 'r')
-        for line in file_cpuinfo:
-            if line.startswith('siblings'):
-                siblings = line.split(":")
-            if line.startswith('cpu cores'):
-                cpu_cores = line.split(":")
-                break
-        return( int( siblings[1] ) / int( cpu_cores[1] ) )
-    except Exception:
-        print("Failed to check if system is hyper-threaded")
-        sys.exit(1)
-
-def map_cpuid_pkgid():
-    ''' Routine to map physical package id to cpu id
-    '''
-    if is_hyper_threaded():
-        core_info = {}
-        try:
-            for i in range(0, cpu_count):
-                phy_pkg_file = '/sys/devices/system/cpu/cpu%s' % i
-                phy_pkg_file += '/topology/physical_package_id'
-                core_file = '/sys/devices/system/cpu/cpu%s' % i
-                core_file += '/topology/core_id'
-                core_id = open(core_file).read().rstrip()
-                cpu_phy_id = open(phy_pkg_file).read().rstrip()
-                if not cpu_phy_id in list(cpu_map.keys()):
-                    core_info = {}
-                else:
-                    core_info = cpu_map[cpu_phy_id]
-                if not core_id in list(core_info.keys()):
-                    core_info[core_id] = [i]
-                else:
-                    core_info[core_id].append(i)
-                cpu_map[cpu_phy_id] = core_info
-        except Exception as details:
-            print("Package, core & cpu map table creation failed", e)
-            sys.exit(1)
-    else:
-        for i in range(0, cpu_count):
-            try:
-                phy_pkg_file = '/sys/devices/system/cpu/cpu%s' %i
-                phy_pkg_file += '/topology/physical_package_id'
-                cpu_phy_id = open(phy_pkg_file).read().rstrip()
-                if not cpu_phy_id in list(cpu_map.keys()):
-                    cpu_map[cpu_phy_id] = [i]
-                else:
-                    cpu_map[cpu_phy_id].append(i)
-            except IOError as e:
-                print("Mapping of CPU to pkg id failed", e)
-                sys.exit(1)
-
-
-def generate_sibling_list():
-    ''' Routine to generate siblings list
-    '''
-    try:
-        for i in range(0, cpu_count):
-            siblings_file = '/sys/devices/system/cpu/cpu%s' % i
-            siblings_file += '/topology/thread_siblings_list'
-            threads_sibs = open(siblings_file).read().rstrip()
-            thread_ids = threads_sibs.split("-")
-
-            if not thread_ids in siblings_list:
-                siblings_list.append(thread_ids)
-    except Exception as details:
-        print("Exception in generate_siblings_list", details)
-        sys.exit(1)
-
-def get_siblings(cpu_id):
-    ''' Return siblings of cpu_id
-    '''
-    try:
-        cpus = ""
-        for i in range(0, len(siblings_list)):
-            for cpu in siblings_list[i]:
-                if cpu_id == cpu:
-                    for j in siblings_list[i]:
-                        # Exclude cpu_id in the list of siblings
-                        if j != cpu_id:
-                            cpus += j
-                    return cpus
-        return cpus
-    except Exception as details:
-        print("Exception in get_siblings", details)
-        sys.exit(1)
-
-def get_proc_data(stats_list):
-    ''' Read /proc/stat info and store in dictionary
-    '''
-    try:
-        file_procstat = open("/proc/stat", 'r')
-        for line in file_procstat:
-            if line.startswith('cpu'):
-                data = line.split()
-                stats_list[data[0]] = data
-        file_procstat.close()
-    except OSError as e:
-        print("Could not read statistics", e)
-        sys.exit(1)
-
-def get_proc_loc_count(loc_stats):
-    ''' Read /proc/interrupts info and store in list
-    '''
-    try:
-        file_procstat = open("/proc/interrupts", 'r')
-        for line in file_procstat:
-            if line.startswith(' LOC:') or line.startswith('LOC:'):
-                data = line.split()
-                for i in range(0, cpu_count):
-                    # To skip LOC
-                    loc_stats.append(data[i+1])
-                file_procstat.close()
-                return
-    except Exception as details:
-        print("Could not read interrupt statistics", details)
-        sys.exit(1)
-
-
-def set_sched_mc_power(sched_mc_level):
-    ''' Routine to set sched_mc_power_savings to required level
-    '''
-    try:
-        os.system('echo %s > \
-            /sys/devices/system/cpu/sched_mc_power_savings 2>/dev/null'
-            % sched_mc_level)
-
-        get_proc_data(stats_start)
-    except OSError as e:
-        print("Could not set sched_mc_power_savings to", sched_mc_level, e)
-    sys.exit(1)
-
-def set_sched_smt_power(sched_smt_level):
-    ''' Routine to set sched_smt_power_savings to required level
-    '''
-    try:
-        os.system('echo %s > \
-            /sys/devices/system/cpu/sched_smt_power_savings 2>/dev/null'
-            % sched_smt_level)
-
-        get_proc_data(stats_start)
-    except OSError as e:
-        print("Could not set sched_smt_power_savings to", sched_smt_level, e)
-    sys.exit(1)
-
-def set_timer_migration_interface(value):
-    ''' Set value of timer migration interface to a value
-        passed as argument
-    '''
-    try:
-        os.system('echo %s > \
-            /proc/sys/kernel/timer_migration 2>/dev/null' % value)
-    except OSError as e:
-        print("Could not set timer_migration to ", value, e)
-        sys.exit(1)
-
-def get_job_count(stress, workload, sched_smt):
-    ''' Returns number of jobs/threads to be triggered
-    '''
-
-    try:
-        if stress == "thread":
-            threads = get_hyper_thread_count()
-        if stress == "partial":
-            threads = cpu_count / socket_count
-            if is_hyper_threaded():
-                if workload == "ebizzy" and int(sched_smt) ==0:
-                    threads = threads / get_hyper_thread_count()
-                if workload == "kernbench" and int(sched_smt) < 2:
-                    threads = threads / get_hyper_thread_count()
-        if stress == "full":
-            threads = cpu_count
-        if stress == "single_job":
-            threads = 1
-            duration = 180
-        return threads
-    except Exception as details:
-        print("get job count failed ", details)
-        sys.exit(1)
-
-def trigger_ebizzy (sched_smt, stress, duration, background, pinned):
-    ''' Triggers ebizzy workload for sched_mc=1
-        testing
-    '''
-    try:
-        threads = get_job_count(stress, "ebizzy", sched_smt)
-        workload = "ebizzy"
-        olddir = os.getcwd()
-        path = '%s/testcases/bin' % os.environ['LTPROOT']
-        os.chdir(path)
-        workload_file = ""
-        for file_name in os.listdir('.'):
-            if file_name == workload:
-                workload_file = file_name
-                break
-        if workload_file == "":
-            print("INFO: ebizzy benchmark not found")
-            os.chdir(olddir)
-            sys.exit(1)
-        get_proc_data(stats_start)
-        get_proc_loc_count(intr_start)
-        try:
-            if background == "yes":
-                succ = os.system('./ebizzy -t%s -s4096 -S %s >/dev/null &'
-                    % (threads, duration))
-            else:
-                if pinned == "yes":
-                    succ = os.system('taskset -c %s ./ebizzy -t%s -s4096 -S %s >/dev/null'
-                        % (cpu_count -1, threads, duration))
-                else:
-                    succ = os.system('./ebizzy -t%s -s4096 -S %s >/dev/null'
-                        % (threads, duration))
-
-            if succ == 0:
-                print("INFO: ebizzy workload triggerd")
-                os.chdir(olddir)
-                #Commented bcoz it doesnt make sense to capture it when workload triggered
-                #in background
-                #get_proc_loc_count(intr_stop)
-                #get_proc_data(stats_stop)
-            else:
-                print("INFO: ebizzy workload triggerd failed")
-                os.chdir(olddir)
-                sys.exit(1)
-        except Exception as details:
-            print("Ebizzy workload trigger failed ", details)
-            sys.exit(1)
-    except Exception as details:
-        print("Ebizzy workload trigger failed ", details)
-        sys.exit(1)
-
-def trigger_kernbench (sched_smt, stress, background, pinned, perf_test):
-    ''' Trigger load on system like kernbench.
-        Copys existing copy of LTP into as LTP2 and then builds it
-        with make -j
-    '''
-    olddir = os.getcwd()
-    try:
-        threads = get_job_count(stress, "kernbench", sched_smt)
-
-        dst_path = "/root"
-        workload = "kernbench"
-        olddir = os.getcwd()
-        path = '%s/testcases/bin' % os.environ['LTPROOT']
-        os.chdir(path)
-        workload_file = ""
-        for file_name in os.listdir('.'):
-            if file_name == workload:
-                workload_file = file_name
-                break
-        if workload_file != "":
-            benchmark_path = path
-        else:
-            print("INFO: kernbench benchmark not found")
-            os.chdir(olddir)
-            sys.exit(1)
-
-        os.chdir(dst_path)
-        linux_source_dir=""
-        for file_name in os.listdir('.'):
-            if file_name.find("linux-2.6") != -1 and os.path.isdir(file_name):
-                linux_source_dir=file_name
-                break
-        if linux_source_dir != "":
-            os.chdir(linux_source_dir)
-        else:
-            print("INFO: Linux kernel source not found in /root. Workload\
-               Kernbench cannot be executed")
-            sys.exit(1)
-
-        get_proc_data(stats_start)
-        get_proc_loc_count(intr_start)
-        if pinned == "yes":
-            os.system ( 'taskset -c %s %s/kernbench -o %s -M -H -n 1 \
-                >/dev/null 2>&1 &' % (cpu_count-1, benchmark_path, threads))
-
-            # We have to delete import in future
-            import time
-            time.sleep(240)
-            stop_wkld("kernbench")
-        else:
-            if background == "yes":
-                os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1 &' \
-                    % (benchmark_path, threads))
-            else:
-                if perf_test == "yes":
-                    os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1' \
-                        % (benchmark_path, threads))
-                else:
-                    os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1 &' \
-                        % (benchmark_path, threads))
-                    # We have to delete import in future
-                    import time
-                    time.sleep(240)
-                    stop_wkld("kernbench")
-
-        print("INFO: Workload kernbench triggerd")
-        os.chdir(olddir)
-    except Exception as details:
-        print("Workload kernbench trigger failed ", details)
-        sys.exit(1)
-
-def trigger_workld(sched_smt, workload, stress, duration, background, pinned, perf_test):
-    ''' Triggers workload passed as argument. Number of threads
-        triggered is based on stress value.
-    '''
-    try:
-        if workload == "ebizzy":
-            trigger_ebizzy (sched_smt, stress, duration, background, pinned)
-        if workload == "kernbench":
-            trigger_kernbench (sched_smt, stress, background, pinned, perf_test)
-    except Exception as details:
-        print("INFO: Trigger workload failed", details)
-        sys.exit(1)
-
-def generate_report():
-    ''' Generate report of CPU utilization
-    '''
-    cpu_labels = ('cpu', 'user', 'nice', 'system', 'idle', 'iowait', 'irq',
-	'softirq', 'x', 'y')
-    if (not os.path.exists('/procstat')):
-        os.mkdir('/procstat')
-
-    get_proc_data(stats_stop)
-
-    reportfile = open('/procstat/cpu-utilisation', 'a')
-    debugfile = open('/procstat/cpu-utilisation.debug', 'a')
-    for l in stats_stop:
-        percentage_list = []
-        total = 0
-        for i in range(1, len(stats_stop[l])):
-            stats_stop[l][i] =  int(stats_stop[l][i]) - int(stats_start[l][i])
-            total += stats_stop[l][i]
-        percentage_list.append(l)
-        for i in range(1, len(stats_stop[l])):
-            percentage_list.append(float(stats_stop[l][i])*100/total)
-
-        stats_percentage[l] = percentage_list
-
-    for i in range(0, len(cpu_labels)):
-        print(cpu_labels[i], '\t', end=' ', file=debugfile)
-    print(file=debugfile)
-    for l in sorted(stats_stop.keys()):
-        print(l, '\t', end=' ', file=debugfile)
-        for i in range(1, len(stats_stop[l])):
-            print(stats_stop[l][i], '\t', end=' ', file=debugfile)
-        print(file=debugfile)
-
-    for i in range(0, len(cpu_labels)):
-        print(cpu_labels[i], '\t', end=' ', file=reportfile)
-    print(file=reportfile)
-    for l in sorted(stats_percentage.keys()):
-        print(l, '\t', end=' ', file=reportfile)
-        for i in range(1, len(stats_percentage[l])):
-            print(" %3.4f" % stats_percentage[l][i], end=' ', file=reportfile)
-        print(file=reportfile)
-
-    #Now get the package ID information
-    try:
-        print("cpu_map: ", cpu_map, file=debugfile)
-        keyvalfile = open('/procstat/keyval', 'a')
-        print("nr_packages=%d" % len(cpu_map), file=keyvalfile)
-        print("system-idle=%3.4f" % (stats_percentage['cpu'][4]), file=keyvalfile)
-        for pkg in sorted(cpu_map.keys()):
-            if is_hyper_threaded():
-                for core in sorted(cpu_map[pkg].keys()):
-                    total_idle = 0
-                    total = 0
-                    for cpu in cpu_map[pkg][core]:
-                        total_idle += stats_stop["cpu%d" % cpu][4]
-                        for i in range(1, len(stats_stop["cpu%d" % cpu])):
-                            total += stats_stop["cpu%d" % cpu][i]
-            else:
-                total_idle = 0
-                total = 0
-                for cpu in cpu_map[pkg]:
-                    total_idle += stats_stop["cpu%d" % cpu][4]
-                    for i in range(1, len(stats_stop["cpu%d" % cpu])):
-                        total += stats_stop["cpu%d" % cpu][i]
-            print("Package: ", pkg, "Idle %3.4f%%" \
-	        % (float(total_idle)*100/total), file=reportfile)
-            print("package-%s=%3.4f" % \
-		(pkg, (float(total_idle)*100/total)), file=keyvalfile)
-    except Exception as details:
-        print("Generating utilization report failed: ", details)
-        sys.exit(1)
-
-    #Add record delimiter '\n' before closing these files
-    print(file=debugfile)
-    debugfile.close()
-    print(file=reportfile)
-    reportfile.close()
-    print(file=keyvalfile)
-    keyvalfile.close()
-
-def generate_loc_intr_report():
-    ''' Generate interrupt report of CPU's
-    '''
-    try:
-        if (not os.path.exists('/procstat')):
-            os.mkdir('/procstat')
-
-        get_proc_loc_count(intr_stop)
-
-        reportfile = open('/procstat/cpu-loc_interrupts', 'a')
-        print("==============================================", file=reportfile)
-        print("     Local timer interrupt stats              ", file=reportfile)
-        print("==============================================", file=reportfile)
-
-        for i in range(0, cpu_count):
-            intr_stop[i] =  int(intr_stop[i]) - int(intr_start[i])
-            print("CPU%s: %s" %(i, intr_stop[i]), file=reportfile)
-        print(file=reportfile)
-        reportfile.close()
-    except Exception as details:
-        print("Generating interrupt report failed: ", details)
-        sys.exit(1)
-
-def record_loc_intr_count():
-    ''' Record Interrupt statistics when timer_migration
-        was disabled
-    '''
-    try:
-        global intr_start, intr_stop
-        for i in range(0, cpu_count):
-            intr_stat_timer_0.append(intr_stop[i])
-        intr_start = []
-        intr_stop = []
-    except Exception as details:
-        print("INFO: Record interrupt statistics when timer_migration=0",details)
-
-def expand_range(range_val):
-    '''
-       Expand the range of value into actual numbers
-    '''
-    ids_list = list()
-    try:
-        sep_comma = range_val.split(",")
-        for i in range(0, len(sep_comma)):
-            hyphen_values = sep_comma[i].split("-")
-            if len(hyphen_values) == 1:
-                ids_list.append(int(hyphen_values[0]))
-            else:
-                for j in range(int(hyphen_values[0]), int(hyphen_values[1])+1):
-                    ids_list.append(j)
-        return(ids_list)
-    except Exception as details:
-        print("INFO: expand_pkg_grps failed ", details)
-
-def is_quad_core():
-    '''
-       Read /proc/cpuinfo and check if system is Quad core
-    '''
-    try:
-        cpuinfo = open('/proc/cpuinfo', 'r')
-        for line in cpuinfo:
-            if line.startswith('cpu cores'):
-                cores = line.split("cpu cores")
-                num_cores = cores[1].split(":")
-                cpuinfo.close()
-                if int(num_cores[1]) == 4:
-                    return(1)
-                else:
-                    return(0)
-    except IOError as e:
-        print("Failed to get cpu core information", e)
-        sys.exit(1)
-
-def validate_cpugrp_map(cpu_group, sched_mc_level, sched_smt_level):
-    '''
-       Verify if cpugrp belong to same package
-    '''
-    modi_cpu_grp = cpu_group[:]
-    try:
-        if is_hyper_threaded():
-            for pkg in sorted(cpu_map.keys()):
-                # if CPU utilized is across package this condition will be true
-                if len(modi_cpu_grp) != len(cpu_group):
-                    break
-                for core in sorted(cpu_map[pkg].keys()):
-                    core_cpus = cpu_map[pkg][core]
-                    if core_cpus == modi_cpu_grp:
-                        return 0
-                    else:
-                        #if CPUs used across the cores
-                        for i in range(0, len(core_cpus)):
-                            if core_cpus[i] in modi_cpu_grp:
-                                modi_cpu_grp.remove(core_cpus[i])
-                                if len(modi_cpu_grp) == 0:
-                                    return 0
-                            #This code has to be deleted
-                            #else:
-                                # If sched_smt == 0 then its oky if threads run
-                                # in different cores of same package
-                                #if sched_smt_level > 0 :
-                                    #return 1
-        else:
-            for pkg in sorted(cpu_map.keys()):
-                pkg_cpus = cpu_map[pkg]
-                if len(cpu_group) == len(pkg_cpus):
-                    if pkg_cpus == cpu_group:
-                        return(0)
-                else:
-                    if int(cpus_utilized[0]) in cpu_map[pkg] or int(cpus_utilized[1]) in cpu_map[pkg]:
-                        return(0)
-
-        return(1)
-
-    except Exception as details:
-        print("Exception in validate_cpugrp_map: ", details)
-        sys.exit(1)
-
-
-def verify_sched_domain_dmesg(sched_mc_level, sched_smt_level):
-    '''
-       Read sched domain information from dmesg.
-    '''
-    cpu_group = list()
-    try:
-        dmesg_info = os.popen('dmesg').read()
-        if dmesg_info != "":
-            lines = dmesg_info.split('\n')
-            for i in range(0, len(lines)):
-                if lines[i].endswith('CPU'):
-                    groups = lines[i+1].split("groups:")
-                    group_info = groups[1]
-                    if group_info.find("(") != -1:
-                        openindex=group_info.index("(")
-                        closeindex=group_info.index(")")
-                        group_info=group_info.replace\
-                            (group_info[openindex:closeindex+1],"")
-
-                    subgroup = group_info.split(",")
-                    for j in range(0, len(subgroup)):
-                        cpu_group = expand_range(subgroup[j])
-                        status = validate_cpugrp_map(cpu_group, sched_mc_level,\
-                        sched_smt_level)
-                        if status == 1:
-                            if is_quad_core() == 1:
-                                if int(sched_mc_level) == 0:
-                                    return(0)
-                                else:
-                                    return(1)
-                            else:
-                                return(1)
-            return(0)
-        else:
-            return(1)
-    except Exception as details:
-        print("Reading dmesg failed", details)
-        sys.exit(1)
-
-def get_cpu_utilization(cpu):
-    ''' Return cpu utilization of cpu_id
-    '''
-    try:
-        for l in sorted(stats_percentage.keys()):
-            if cpu == stats_percentage[l][0]:
-                return stats_percentage[l][1]
-        return -1
-    except Exception as details:
-        print("Exception in get_cpu_utilization", details)
-        sys.exit(1)
-
-def validate_cpu_consolidation(stress, work_ld, sched_mc_level, sched_smt_level):
-    ''' Verify if cpu's on which threads executed belong to same
-    package
-    '''
-    cpus_utilized = list()
-    threads = get_job_count(stress, work_ld, sched_smt_level)
-    try:
-        for l in sorted(stats_percentage.keys()):
-            #modify threshold
-            cpu_id = stats_percentage[l][0].split("cpu")
-            if cpu_id[1] == '':
-                continue
-            if int(cpu_id[1]) in cpus_utilized:
-                continue
-            if is_hyper_threaded():
-                if work_ld == "kernbench" and sched_smt_level < sched_mc_level:
-                    siblings = get_siblings(cpu_id[1])
-                    if siblings != "":
-                        sib_list = siblings.split()
-                        utilization = int(stats_percentage[l][1])
-                        for i in range(0, len(sib_list)):
-                            utilization += int(get_cpu_utilization("cpu%s" %sib_list[i]))
-                    else:
-                        utilization = stats_percentage[l][1]
-                    if utilization > 40:
-                        cpus_utilized.append(int(cpu_id[1]))
-                        if siblings != "":
-                            for i in range(0, len(sib_list)):
-                                cpus_utilized.append(int(sib_list[i]))
-                else:
-                    # This threshold wuld be modified based on results
-                    if stats_percentage[l][1] > 40:
-                        cpus_utilized.append(int(cpu_id[1]))
-            else:
-                if work_ld == "kernbench" :
-                    if stats_percentage[l][1] > 50:
-                        cpus_utilized.append(int(cpu_id[1]))
-                else:
-                    if stats_percentage[l][1] > 70:
-                        cpus_utilized.append(int(cpu_id[1]))
-            cpus_utilized.sort()
-        print("INFO: CPU's utilized ", cpus_utilized)
-
-        # If length of CPU's utilized is not = number of jobs exit with 1
-        if len(cpus_utilized) < threads:
-            return 1
-
-        status = validate_cpugrp_map(cpus_utilized, sched_mc_level, \
-            sched_smt_level)
-        if status == 1:
-            print("INFO: CPUs utilized is not in same package or core")
-
-        return(status)
-    except Exception as details:
-        print("Exception in validate_cpu_consolidation: ", details)
-        sys.exit(1)
-
-def get_cpuid_max_intr_count():
-    '''Return the cpu id's of two cpu's with highest number of intr'''
-    try:
-        highest = 0
-        second_highest = 0
-        cpus_utilized = []
-
-        #Skipping CPU0 as it is generally high
-        for i in range(1, cpu_count):
-            if int(intr_stop[i]) > int(highest):
-                if highest != 0:
-                    second_highest = highest
-                    cpu2_max_intr = cpu1_max_intr
-                highest = int(intr_stop[i])
-                cpu1_max_intr = i
-            else:
-                if int(intr_stop[i]) > int(second_highest):
-                    second_highest = int(intr_stop[i])
-                    cpu2_max_intr = i
-        cpus_utilized.append(cpu1_max_intr)
-        cpus_utilized.append(cpu2_max_intr)
-
-        for i in range(1, cpu_count):
-            if i != cpu1_max_intr and i != cpu2_max_intr:
-                diff = second_highest - intr_stop[i]
-                ''' Threshold of difference has to be manipulated '''
-                if diff < 10000:
-                    print("INFO: Diff in interrupt count is below threshold")
-                    cpus_utilized = []
-                    return cpus_utilized
-        print("INFO: Interrupt count in other CPU's low as expected")
-        return cpus_utilized
-    except Exception as details:
-        print("Exception in get_cpuid_max_intr_count: ", details)
-        sys.exit(1)
-
-def validate_ilb (sched_mc_level, sched_smt_level):
-    ''' Validate if ilb is running in same package where work load is running
-    '''
-    try:
-        cpus_utilized = get_cpuid_max_intr_count()
-        if not cpus_utilized:
-            return 1
-
-        status = validate_cpugrp_map(cpus_utilized, sched_mc_level, sched_smt_level)
-        return status
-    except Exception as details:
-        print("Exception in validate_ilb: ", details)
-        sys.exit(1)
-
-def reset_schedmc():
-    ''' Routine to reset sched_mc_power_savings to Zero level
-    '''
-    try:
-        os.system('echo 0 > \
-            /sys/devices/system/cpu/sched_mc_power_savings 2>/dev/null')
-    except OSError as e:
-        print("Could not set sched_mc_power_savings to 0", e)
-        sys.exit(1)
-
-def reset_schedsmt():
-    ''' Routine to reset sched_smt_power_savings to Zero level
-    '''
-    try:
-        os.system('echo 0 > \
-            /sys/devices/system/cpu/sched_smt_power_savings 2>/dev/null')
-    except OSError as e:
-        print("Could not set sched_smt_power_savings to 0", e)
-        sys.exit(1)
-
-def stop_wkld(work_ld):
-    ''' Kill workload triggered in background
-    '''
-    try:
-        os.system('pkill %s 2>/dev/null' %work_ld)
-        if work_ld == "kernbench":
-            os.system('pkill make 2>/dev/null')
-    except OSError as e:
-        print("Exception in stop_wkld", e)
-        sys.exit(1)
diff --git a/testcases/kernel/power_management/pm_ilb_test.py b/testcases/kernel/power_management/pm_ilb_test.py
deleted file mode 100755
index f20717090b..0000000000
--- a/testcases/kernel/power_management/pm_ilb_test.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python3
-''' This Python script interprets interrupt values.
-    Validates Ideal load balancer runs in same package where workload is running
-'''
-
-import os
-import sys
-from optparse import OptionParser
-from pm_sched_mc import *
-
-__author__ = "Poornima Nayak <mpnayak@linux.vnet.ibm.com>"
-
-class Usage(Exception):
-    def __init__(self, msg):
-        self.msg = msg
-
-def main(argv=None):
-    if argv is None:
-        argv = sys.argv
-
-    usage = "-w"
-    parser = OptionParser(usage)
-    parser.add_option("-c", "--mc_level", dest="mc_level",
-        default=0, help="Sched mc power saving value 0/1/2")
-    parser.add_option("-t", "--smt_level", dest="smt_level",
-        default=0, help="Sched smt power saving value 0/1/2")
-    parser.add_option("-w", "--workload", dest="work_ld",
-        default="ebizzy", help="Workload can be ebizzy/kernbench")
-    (options, args) = parser.parse_args()
-
-    try:
-        count_num_cpu()
-        count_num_sockets()
-        if is_multi_socket():
-            set_sched_mc_power(options.mc_level)
-        if is_hyper_threaded():
-            set_sched_smt_power(options.smt_level)
-        map_cpuid_pkgid()
-        print("INFO: Created table mapping cpu to package")
-        background="no"
-        duration=120
-        pinned="yes"
-
-        trigger_workld(options.smt_level,options.work_ld, "single_job", duration, background, pinned, "no")
-        generate_loc_intr_report()
-        status = validate_ilb(options.mc_level, options.smt_level)
-        reset_schedmc()
-        if is_hyper_threaded():
-            reset_schedsmt()
-        return(status)
-
-    except Exception as details:
-        print("INFO: Idle Load Balancer test failed", details)
-        return(1)
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/testcases/kernel/power_management/pm_include.sh b/testcases/kernel/power_management/pm_include.sh
index b83324f607..4cc75aa9ac 100755
--- a/testcases/kernel/power_management/pm_include.sh
+++ b/testcases/kernel/power_management/pm_include.sh
@@ -1,19 +1,4 @@
-#!/bin/bash
-
-TMPDIR=/tmp
-
-PASS=0
-FAIL=1
-NOSUPPORT=2
-MISSING_FILE=3
-UNTESTED=4
-YES=0
-
-cleanup() {
-	if [ -f ${1} ] ; then
-		rm -f ${1}
-	fi
-}
+#!/bin/sh
 
 check_arch() {
 	case "$(uname -m)" in
@@ -24,297 +9,3 @@ check_arch() {
 		;;
 	esac
 }
-
-check_config_options() {
-	if ( ! ${3} "${1}" ${2} | grep -v "#" > /dev/null ) ; then
-		tst_brkm TCONF "NOSUPPORT: current system dosen't support ${1}"
-	fi
-}
-
-get_topology() {
-	declare -a cpus
-	declare -a phyid
-
-	total_cpus=`tst_ncpus`
-	(( total_cpus-=1 ))
-	for cpu in $(seq 0 "${total_cpus}" )
-	do
-		cpus[$cpu]=cpu${cpu}
-		phyid[$cpu]=$(cat \
-		/sys/devices/system/cpu/cpu${cpu}/topology/physical_package_id)
-	done
-	j=0
-	while [ "${j}" -lt "${total_cpus}" ]
-	do
-		(( k = $j + 1 ))
-		if [ ${phyid[$j]} -eq ${phyid[$k]} ] ; then
-			echo "${cpus[$j]} -P ${cpus[$k]}" | sed -e "s/cpu//g"
-		fi
-		(( j+=1 ))
-	done
-}
-
-check_cpufreq() {
-	total_cpus=`tst_ncpus`
-	(( total_cpus-=1 ))
-
-	for cpu in $(seq 0 "${total_cpus}" )
-	do
-		if [ ! -d /sys/devices/system/cpu/cpu${cpu}/cpufreq ] ; then
-			tst_brkm TCONF "NOSUPPORT: cpufreq support not " \
-				"found please check Kernel configuration " \
-				"or BIOS settings"
-		fi
-	done
-}
-
-get_supporting_freq() {
-	cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies \
-		| uniq
-}
-
-get_supporting_govr() {
-	cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_governors \
-		| uniq
-}
-
-is_hyper_threaded() {
-	siblings=`grep siblings /proc/cpuinfo | uniq | cut -f2 -d':'`
-	cpu_cores=`grep "cpu cores" /proc/cpuinfo | uniq | cut -f2 -d':'`
-	[ $siblings -gt $cpu_cores ]; echo $?
-}
-
-check_input() {
-	validity_check=${2:-valid}
-	testfile=$3
-	if [ "${validity_check}" = "invalid" ] ; then
-		PASS="Testcase FAIL - Able to execute"
-		FAIL="Testcase PASS - Unable to execute"
-	else
-		PASS="Testcase PASS"
-		FAIL="Testcase FAIL"
-	fi
-	RC=0
-	for input in ${1}
-	do
-		echo ${input} > ${test_file} 2>/dev/null
-		return_value=$?
-		output=$(cat ${test_file})
-		if [ "${return_value}" = "0" -a "${input}" = "${output}" ] ; then
-			echo "${0}: ${PASS}: echo ${input} > ${test_file}"
-			if [ "${validity_check}" = "invalid" ] ; then
-				RC=1
-			fi
-		else
-			echo "${0}: ${FAIL}: echo ${input} > ${test_file}"
-			if [ "${validity_check}" = "valid" ] ; then
-				RC=1
-			fi
-		fi
-	done
-	return $RC
-}
-
-is_multi_socket() {
-	no_of_sockets=`cat \
-		/sys/devices/system/cpu/cpu*/topology/physical_package_id \
-		| sort -u | wc -l`
-	[ $no_of_sockets -gt 1 ] ; echo $?
-}
-
-is_multi_core() {
-	siblings=`grep siblings /proc/cpuinfo | uniq | cut -f2 -d':'`
-	cpu_cores=`grep "cpu cores" /proc/cpuinfo | uniq | cut -f2 -d':'`
-	if [ $siblings -eq $cpu_cores ]; then
-		[ $cpu_cores -gt 1 ]; echo $?
-	else
-		: $(( num_of_cpus = siblings / cpu_cores ))
-		[ $num_of_cpus -gt 1 ]; echo $?
-	fi
-}
-
-is_dual_core() {
-	siblings=`grep siblings /proc/cpuinfo | uniq | cut -f2 -d':'`
-	cpu_cores=`grep "cpu cores" /proc/cpuinfo | uniq \
-			| cut -f2 -d':'`
-        if [ $siblings -eq $cpu_cores ]; then
-                [ $cpu_cores -eq 2 ]; echo $?
-        else
-                : $(( num_of_cpus = siblings / cpu_cores ))
-                [ $num_of_cpus -eq 2 ]; echo $?
-        fi
-}
-
-get_kernel_version() {
-	# Get kernel minor version
-	export kernel_version=`uname -r | awk -F. '{print $1"."$2"."$3}' \
-		| cut -f1 -d'-'`
-}
-
-get_valid_input() {
-	kernel_version=$1
-	case "$kernel_version" in
-	'2.6.26' | '2.6.27' | '2.6.28')
-			export valid_input="0 1" ;;
-		*) export valid_input="0 1 2" ;;
-	esac
-}
-
-analyze_result_hyperthreaded() {
-	sched_mc=$1
-    pass_count=$2
-    sched_smt=$3
-	PASS="Test PASS"
-	FAIL="Test FAIL"
-
-	RC=0
-	case "$sched_mc" in
-	0)
-		case "$sched_smt" in
-		0)
-			if [ $pass_count -lt 5 ]; then
-				echo "${PASS}: cpu consolidation failed for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			else
-				RC=1
-				echo "${FAIL}: cpu consolidation passed for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			fi
-			;;
-		*)
-			if [ $pass_count -lt 5 ]; then
-				RC=1
-				echo "${FAIL}: cpu consolidation for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			else
-				echo "${PASS}: cpu consolidation for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			fi
-			;;
-		esac ;;
-	*)
-		if [ $pass_count -lt 5 ]; then
-			RC=1
-			echo "${FAIL}: cpu consolidation for" \
-				"sched_mc=$sched_mc & sched_smt=$sched_smt"
-		else
-			echo "${PASS}: cpu consolidation for" \
-				"sched_mc=$sched_mc & sched_smt=$sched_smt"
-		fi
-		;;
-	esac
-	return $RC
-}
-
-analyze_package_consolidation_result() {
-	sched_mc=$1
-    pass_count=$2
-
-	if [ $# -gt 2 ]
-	then
-		sched_smt=$3
-	else
-		sched_smt=-1
-	fi
-
-	PASS="Test PASS"
-	FAIL="Test FAIL"
-
-	RC=0
-	if [ $hyper_threaded -eq $YES -a $sched_smt -gt -1 ]; then
-		analyze_result_hyperthreaded $sched_mc $pass_count $sched_smt
-	else
-		case "$sched_mc" in
-	    0)
-    	    if [ $pass_count -lt 5 ]; then
-				echo "${PASS}: cpu consolidation failed for" \
-					"sched_mc=$sched_mc"
-        	else
-				RC=1
-				echo "${FAIL}: cpu consolidation passed for" \
-					"sched_mc=$sched_mc"
-			fi
-			;;
-    	*)
-			if [ $pass_count -lt 5 ]; then
-				RC=1
-				echo "${FAIL}: consolidation at package level" \
-					"failed for sched_mc=$sched_mc"
-			else
-				echo "${PASS}: consolidation at package level" \
-					"passed for sched_mc=$sched_mc"
-			fi
-        	;;
-    	esac
-	fi
-	return $RC
-}
-
-analyze_core_consolidation_result() {
-	sched_smt=$1
-	pass_count=$2
-	PASS="Test PASS"
-	FAIL="Test FAIL"
-
-	RC=0
-	case "$sched_smt" in
-	0)
-		if [ $pass_count -lt 5 ]; then
-			echo "${PASS}: consolidation at core level failed" \
-				"when sched_smt=$sched_smt"
-		else
-			RC=1
-			echo "${FAIL}: consolidation at core level passed for" \
-				"sched_smt=$sched_smt"
-		fi ;;
-	*)
-		if [ $pass_count -lt 5 ]; then
-			RC=1
-			echo "${FAIL}: consolidation at core level failed for" \
-				"sched_smt=$sched_smt"
-		else
-			echo "${PASS}: consolidation at core level passed for" \
-				"sched_smt=$sched_smt"
-		fi ;;
-	esac
-	return $RC
-}
-
-analyze_sched_domain_result(){
-	sched_mc=$1
-	result=$2
-	sched_smt=$3
-	PASS="Test PASS"
-	FAIL="Test FAIL"
-
-	RC=0
-	if [ $hyper_threaded -eq $YES ]; then
-		if [ $sched_smt ]; then
-			if [ "$result" = 0 ];then
-				echo "${PASS}: sched domain test for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			else
-				RC=1
-				echo "${FAIL}: sched domain test for" \
-					"sched_mc=$sched_mc & sched_smt=$sched_smt"
-			fi
-		else
-			if [ "$result" = 0 ];then
-				echo "${PASS}: sched domain test for" \
-					"sched_mc=$sched_mc"
-			else
-				RC=1
-				echo "${FAIL}: sched domain test for" \
-					"sched_mc=$sched_mc"
-			fi
-		fi
-	else
-		if [ "$result" = 0 ];then
-			echo "${PASS}: sched domain test for sched_mc=$sched_mc"
-		else
-			RC=1
-			echo "${FAIL}: sched domain test for sched_mc=$sched_mc"
-		fi
-	fi
-	return $RC
-}
diff --git a/testcases/kernel/power_management/pm_sched_domain.py b/testcases/kernel/power_management/pm_sched_domain.py
deleted file mode 100755
index dddc481690..0000000000
--- a/testcases/kernel/power_management/pm_sched_domain.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-''' This Python script validates sched domain information in dmesg
-    with information in sysfs topology
-'''
-
-import os
-import sys
-from pm_sched_mc import *
-from optparse import OptionParser
-
-__author__ = "Poornima Nayak <mpnayak@linux.vnet.ibm.com>"
-
-class Usage(Exception):
-    def __init__(self, msg):
-        self.msg = msg
-
-def main(argv=None):
-    if argv is None:
-        argv = sys.argv
-
-    usage = "-w"
-    parser = OptionParser(usage)
-    parser.add_option("-c", "--mc_level", dest="mc_level", default=-1,
-        help="Sched mc power saving value 0/1/2")
-    parser.add_option("-t", "--smt_level", dest="smt_level", default=-1,
-        help="Sched smt power saving value 0/1/2")
-    (options, args) = parser.parse_args()
-
-    try:
-        clear_dmesg()
-        count_num_cpu()
-        map_cpuid_pkgid()
-
-        if is_hyper_threaded() and int(options.smt_level) >= 0:
-            set_sched_smt_power(options.smt_level)
-
-        if int(options.mc_level) >= 0:
-            set_sched_mc_power(options.mc_level)
-        if int(options.smt_level) >= 0 or int(options.mc_level) >= 0:
-            status = verify_sched_domain_dmesg(options.mc_level, options.smt_level)
-            reset_schedmc()
-            if is_hyper_threaded():
-                reset_schedsmt()
-                return(status)
-        else:
-            print("INFO: Invalid arguments given")
-            return 1
-    except Exception as details:
-        print("INFO: sched domain test failed: ", details)
-        return(1)
-
-# Run test based on the command line arguments
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/testcases/kernel/power_management/runpwtests03.sh b/testcases/kernel/power_management/runpwtests03.sh
index ebd0957e64..78e0a1b9a7 100755
--- a/testcases/kernel/power_management/runpwtests03.sh
+++ b/testcases/kernel/power_management/runpwtests03.sh
@@ -24,6 +24,16 @@ export TST_TOTAL=4
 . test.sh
 . pm_include.sh
 
+get_supporting_freq() {
+	cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies \
+		| uniq
+}
+
+get_supporting_govr() {
+	cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_governors \
+		| uniq
+}
+
 check_cpufreq_sysfs_files() {
 	total_cpus=`expr $(tst_ncpus) - 1`
 	RC=0
diff --git a/testcases/kernel/power_management/runpwtests06.sh b/testcases/kernel/power_management/runpwtests06.sh
index 16e50a670b..1638aaaf82 100755
--- a/testcases/kernel/power_management/runpwtests06.sh
+++ b/testcases/kernel/power_management/runpwtests06.sh
@@ -24,6 +24,37 @@ export TST_TOTAL=1
 . test.sh
 . pm_include.sh
 
+check_input() {
+	validity_check=${2:-valid}
+	testfile=$3
+	if [ "${validity_check}" = "invalid" ] ; then
+		PASS="Testcase FAIL - Able to execute"
+		FAIL="Testcase PASS - Unable to execute"
+	else
+		PASS="Testcase PASS"
+		FAIL="Testcase FAIL"
+	fi
+	RC=0
+	for input in ${1}
+	do
+		echo ${input} > ${test_file} 2>/dev/null
+		return_value=$?
+		output=$(cat ${test_file})
+		if [ "${return_value}" = "0" -a "${input}" = "${output}" ] ; then
+			echo "${0}: ${PASS}: echo ${input} > ${test_file}"
+			if [ "${validity_check}" = "invalid" ] ; then
+				RC=1
+			fi
+		else
+			echo "${0}: ${FAIL}: echo ${input} > ${test_file}"
+			if [ "${validity_check}" = "valid" ] ; then
+				RC=1
+			fi
+		fi
+	done
+	return $RC
+}
+
 test_timer_migration() {
 	valid_input="0 1"
 	invalid_input="3 4 5 6 7 8 a abcefg x1999 xffff -1 -00000
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 1/2] Remove now unsupported power management tests
From: Petr Vorel @ 2026-03-30  9:08 UTC (permalink / raw)
  To: ltp
  Cc: Cyril Hrubis, Li Wang, Jan Stancek, Andrea Cervesato,
	Daniel Lezcano, Rafael J . Wysocki, Zhang Rui, Lukasz Luba,
	linux-pm, helena.anna.dubel, tomasz.ossowski, Piotr Kubaj,
	automated-testing, Petr Vorel
In-Reply-To: <20260330090844.79598-1-pvorel@suse.cz>

From: Cyril Hrubis <chrubis@suse.cz>

The sched_mc_power_savings and sched_smt_power_savings sysfs knobs
were removed from kernel in:

commit 8e7fbcbc22c12414bcc9dfdd683637f58fb32759
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Mon Jan 9 11:28:35 2012 +0100

    sched: Remove stale power aware scheduling remnants and dysfunctional knobs

That went into kernel 3.5 and the minimal kernel version LTP currently
supports is 3.10.

This has been discussed in:

https://github.com/linux-test-project/ltp/pull/1016

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 runtest/power_management_tests                |   3 -
 runtest/power_management_tests_exclusive      |   6 -
 testcases/kernel/power_management/.gitignore  |   1 -
 testcases/kernel/power_management/README      |  29 ----
 .../power_management/pm_cpu_consolidation.py  | 143 ------------------
 .../power_management/pm_get_sched_values.c    |  36 -----
 .../kernel/power_management/runpwtests01.sh   |  71 ---------
 .../kernel/power_management/runpwtests02.sh   |  68 ---------
 .../kernel/power_management/runpwtests05.sh   |  76 ----------
 .../runpwtests_exclusive01.sh                 |  97 ------------
 .../runpwtests_exclusive02.sh                 |  68 ---------
 .../runpwtests_exclusive03.sh                 |  95 ------------
 .../runpwtests_exclusive04.sh                 |  58 -------
 .../runpwtests_exclusive05.sh                 |  97 ------------
 14 files changed, 848 deletions(-)
 delete mode 100644 runtest/power_management_tests_exclusive
 delete mode 100644 testcases/kernel/power_management/.gitignore
 delete mode 100755 testcases/kernel/power_management/pm_cpu_consolidation.py
 delete mode 100644 testcases/kernel/power_management/pm_get_sched_values.c
 delete mode 100755 testcases/kernel/power_management/runpwtests01.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests02.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests05.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive01.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive02.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive03.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive04.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive05.sh

diff --git a/runtest/power_management_tests b/runtest/power_management_tests
index 884e615cd8..b670da6ecf 100644
--- a/runtest/power_management_tests
+++ b/runtest/power_management_tests
@@ -1,7 +1,4 @@
 #POWER_MANAGEMENT
-runpwtests01 runpwtests01.sh
-runpwtests02 runpwtests02.sh
 runpwtests03 runpwtests03.sh
 runpwtests04 runpwtests04.sh
-#runpwtests05 runpwtests05.sh
 runpwtests06 runpwtests06.sh
diff --git a/runtest/power_management_tests_exclusive b/runtest/power_management_tests_exclusive
deleted file mode 100644
index 0eb0122476..0000000000
--- a/runtest/power_management_tests_exclusive
+++ /dev/null
@@ -1,6 +0,0 @@
-#POWER_MANAGEMENT exclusive
-runpwtests_exclusive01 runpwtests_exclusive01.sh
-runpwtests_exclusive02 runpwtests_exclusive02.sh
-runpwtests_exclusive03 runpwtests_exclusive03.sh
-runpwtests_exclusive04 runpwtests_exclusive04.sh
-runpwtests_exclusive05 runpwtests_exclusive05.sh
diff --git a/testcases/kernel/power_management/.gitignore b/testcases/kernel/power_management/.gitignore
deleted file mode 100644
index 0c2a3ed4bd..0000000000
--- a/testcases/kernel/power_management/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-pm_get_sched_values
diff --git a/testcases/kernel/power_management/README b/testcases/kernel/power_management/README
index b8d6c316e8..1b82782d85 100644
--- a/testcases/kernel/power_management/README
+++ b/testcases/kernel/power_management/README
@@ -38,13 +38,6 @@ CONFIG_CPU_IDLE
 CONFIG_CPU_IDLE_GOV_LADDER
 CONFIG_CPU_IDLE_GOV_MENU
 
-for SCHED_MC tests:
-
-CONFIG_SCHED_MC
-
-The power management test automation suite helps run the power management functionality
-(e.g: cpu frequency, cpu idle etc..) tests and report results.
-
 Test Scripts for CPU FREQUENCY:
 change_freq.sh
 change_govr.sh
@@ -53,9 +46,6 @@ check_cpufreq_sysfs_files.sh
 Test Scripts for CPU IDLE:
 will be added soon
 
-Test Scripts for SCHED_MC:
-test_sched_mc.sh
-
 Common functionality:
 pm_include.sh
 check_kv_arch.c
@@ -66,22 +56,3 @@ To run your tests you can execute the runpwtests.sh
 To run the tests individually :
 
 P.S. As of now the supporting architecture(s) are x86,x86_64
-
-Support of system:
------------------
-If you see some thing like following,
-
-Power Management    1  FAIL  :  Required kernel configuration for SCHED_MC NOT set
-or
-Power Management    1  FAIL  :  Required kernel configuration for CPU_FREQ NOT set
-
-Then either configuration is not set or the system won't support.
-
-For CPU consolidation verification ebizzy is included in utils directory of LTP.
-To run cpu consolidation test user has to provide -w <workload> -l <sched_mc_level>.
-Refer to README in LTPROOT/utils/benchmark/ebizzy-0.2 directory for details of ebizzy.
-
-To test CPU consolidation for sched_mc 2 kernbench has to run. Kernbench needs linux kernel source as input in /root directory . For example download from http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.29.4.tar.bz2. If Linux kernel source not found kernbench wiil  not execute.
-CPU consolidation testcases will not execute if number of CPU's in package is less then 2. If system is hyper threaded but number of CPU is 1 only sched_smt testcases will be excuted. For better coverage of testcases select a system which is at least quad core and then hyper threaded so that you will observe 8 CPU's in each package.
-
-Timer migration interface test will execute on kernel versions 2.6.31 and above. Timer migration functionality verification testcases will be executed only on suitable architecture like quad core or the number of CPU's in each package should be at least 4 and above
diff --git a/testcases/kernel/power_management/pm_cpu_consolidation.py b/testcases/kernel/power_management/pm_cpu_consolidation.py
deleted file mode 100755
index a01db004cb..0000000000
--- a/testcases/kernel/power_management/pm_cpu_consolidation.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env python3
-''' This Python script interprets various sched stats values.
-    Validates cpu consolidation for given sched_mc_power_saving value
-'''
-
-import os
-import sys
-import time
-from optparse import OptionParser
-from pm_sched_mc import *
-
-__author__ = "Poornima Nayak <mpnayak@linux.vnet.ibm.com>"
-
-class Usage(Exception):
-    def __init__(self, msg):
-        self.msg = msg
-
-def main(argv=None):
-    if argv is None:
-        argv = sys.argv
-
-    usage = "-w"
-    parser = OptionParser(usage)
-    parser.add_option("-v", "--variation_test", dest="vary_mc_smt",
-        default=False, action="store_true", help="Vary sched_mc & sched_smt. \
-            -c and -t inputs are initial value of sched_mc & sched_smt")
-    parser.add_option("-c", "--mc_value", dest="mc_value",
-        default=0, help="Sched mc power saving value 0/1/2")
-    parser.add_option("-t", "--smt_value", dest="smt_value",
-        default=0, help="Sched smt power saving value 0/1/2")
-    parser.add_option("-w", "--workload", dest="work_ld",
-        default="ebizzy", help="Workload can be ebizzy/kernbench")
-    parser.add_option("-s", "--stress", dest="stress",
-        default="partial", help="Load on system is full/partial [i.e 50%]/thread")
-    parser.add_option("-p", "--performance", dest="perf_test",
-        default=False, action="store_true", help="Enable performance test")
-    (options, args) = parser.parse_args()
-
-    try:
-        count_num_cpu()
-        count_num_sockets()
-        if is_hyper_threaded():
-            generate_sibling_list()
-
-        # User should set option -v to test cpu consolidation
-        # resets when sched_mc &(/) sched_smt is disabled when
-        # workload is already running in the system
-
-        if options.vary_mc_smt:
-
-            # Since same code is used for testing package consolidation and core
-            # consolidation is_multi_socket & is_hyper_threaded check is done
-            if is_multi_socket() and is_multi_core() and options.mc_value:
-                set_sched_mc_power(options.mc_value)
-
-            if is_hyper_threaded() and options.smt_value:
-                set_sched_smt_power(options.smt_value)
-
-            #Generate arguments for trigger workload, run workload in background
-            map_cpuid_pkgid()
-            background="yes"
-            duration=360
-            pinned="no"
-            if int(options.mc_value) < 2 and int(options.smt_value) < 2:
-                trigger_ebizzy (options.smt_value, "partial", duration, background, pinned)
-                work_ld="ebizzy"
-                #Wait for 120 seconds and then validate cpu consolidation works
-                #When sched_mc & sched_smt is set
-                import time
-                time.sleep(120)
-            else:
-                #Wait for 120 seconds and then validate cpu consolidation works
-                #When sched_mc & sched_smt is set
-                trigger_kernbench (options.smt_value, "partial", background, pinned, "no")
-                work_ld="kernbench"
-                import time
-                time.sleep(300)
-
-            generate_report()
-            status = validate_cpu_consolidation("partial", work_ld, options.mc_value, options.smt_value)
-            if status == 0:
-                print("INFO: Consolidation worked sched_smt &(/) sched_mc is set")
-                #Disable sched_smt & sched_mc interface values
-                if options.vary_mc_smt and options.mc_value > 0:
-                    set_sched_mc_power(0)
-                    mc_value = options.mc_value
-                else:
-                    mc_value = 0
-                if options.vary_mc_smt and options.smt_value > 0 and is_hyper_threaded():
-                    set_sched_smt_power(0)
-                    smt_value = options.smt_value
-                else:
-                    smt_value = 0
-
-                if work_ld == "kernbench":
-                    time.sleep(240)
-                else:
-                    time.sleep(120)
-
-                generate_report()
-                status = validate_cpu_consolidation("partial", work_ld, mc_value, smt_value)
-                if background == "yes":
-                    stop_wkld(work_ld)
-                #CPU consolidation should fail as sched_mc &(/) sched_smt is disabled
-                if status == 1:
-                    return(0)
-                else:
-                    return(1)
-            else:
-                print("INFO: CPU consolidation failed when sched_mc &(/) \
-sched_smt was enabled. This is pre-requisite to proceed")
-                return(status)
-        else:
-            #The else part of the code validates behaviour of sched_mc
-            # and sched_smt set to 0, 1 & 2
-            if is_multi_socket():
-                set_sched_mc_power(options.mc_value)
-            if is_hyper_threaded():
-                set_sched_smt_power(options.smt_value)
-            map_cpuid_pkgid()
-            print("INFO: Created table mapping cpu to package")
-            background="no"
-            duration=60
-            pinned ="no"
-
-            if options.perf_test:
-                perf_test="yes"
-            else:
-                perf_test="no"
-
-            trigger_workld( options.smt_value, options.work_ld, options.stress, duration, background, pinned, perf_test)
-            generate_report()
-            status = validate_cpu_consolidation(options.stress, options.work_ld,options.mc_value, options.smt_value)
-            reset_schedmc()
-            if is_hyper_threaded():
-                reset_schedsmt()
-            return(status)
-    except Exception as details:
-        print("INFO: CPU consolidation failed", details)
-        return(1)
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/testcases/kernel/power_management/pm_get_sched_values.c b/testcases/kernel/power_management/pm_get_sched_values.c
deleted file mode 100644
index e75c5852e5..0000000000
--- a/testcases/kernel/power_management/pm_get_sched_values.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/************************************************************************
-* Copyright (c) International Business Machines Corp., 2008
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
-* the GNU General Public License for more details.
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-***************************************************************************/
-#include <stdio.h>
-#include "test.h"
-
-const char *TCID = "pm_get_sched_values";
-
-int main(int argc, char **argv)
-{
-	char *param;
-	if (argc == 0)
-		return 1;
-	else {
-		param = argv[1];
-		if (strcmp(param, "sched_mc") == 0)
-			return 2;
-		if (strcmp(param, "sched_smt") == 0)
-			return 2;
-	}
-
-	return 1;
-}
diff --git a/testcases/kernel/power_management/runpwtests01.sh b/testcases/kernel/power_management/runpwtests01.sh
deleted file mode 100755
index 2caf9eab51..0000000000
--- a/testcases/kernel/power_management/runpwtests01.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management01"
-export TST_TOTAL=1
-
-. test.sh
-. pm_include.sh
-
-test_sched_mc() {
-	get_kernel_version
-	get_valid_input $kernel_version
-
-	invalid_input="3 4 5 6 7 8 a abcefg x1999 xffff -1 -00000
-	2000000000000000000000000000000000000000000000000000000000000000000
-	ox324 -0xfffffffffffffffffffff"
-	test_file="/sys/devices/system/cpu/sched_mc_power_savings"
-	if [ ! -f ${test_file} ] ; then
-		tst_brkm TBROK "MISSING_FILE: missing file ${test_file}"
-	fi
-
-	RC=0
-	echo "${0}: ---Valid test cases---"
-	check_input "${valid_input}" valid $test_file
-	RC=$?
-	echo "${0}: ---Invalid test cases---"
-	check_input "${invalid_input}" invalid $test_file
-	RC=$(( RC | $? ))
-	return $RC
-}
-
-# Checking test environment
-check_arch
-
-# Checking sched_mc sysfs interface
-multi_socket=$(is_multi_socket)
-multi_core=$(is_multi_core)
-if [ ! -f /sys/devices/system/cpu/sched_mc_power_savings ] ; then
-	tst_brkm TCONF "Required kernel configuration for SCHED_MC" \
-		"NOT set"
-else
-	if [ $multi_socket -ne 0 -a $multi_core -ne 0 ] ; then
-		tst_brkm TCONF "sched_mc_power_savings interface in system" \
-			"which is not a multi socket &(/) multi core"
-	fi
-fi
-
-if test_sched_mc ; then
-	tst_resm TPASS "SCHED_MC sysfs tests"
-else
-	tst_resm TFAIL "SCHED_MC sysfs tests"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests02.sh b/testcases/kernel/power_management/runpwtests02.sh
deleted file mode 100755
index 805befb033..0000000000
--- a/testcases/kernel/power_management/runpwtests02.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management02"
-export TST_TOTAL=1
-
-. test.sh
-. pm_include.sh
-
-test_sched_smt() {
-	get_kernel_version
-	get_valid_input $kernel_version
-
-	invalid_input="3 4 5 6 7 8 a abcefg x1999 xffff -1 -00000
-	2000000000000000000000000000000000000000000000000000000000000000000000
-	ox324 -0xfffffffffffffffffffff"
-	test_file="/sys/devices/system/cpu/sched_smt_power_savings"
-	if [ ! -f ${test_file} ] ; then
-		tst_brkm TBROK "MISSING_FILE: missing file ${test_file}"
-	fi
-
-	echo "${0}: ---Valid test cases---"
-	check_input "${valid_input}" valid $test_file
-	RC=$?
-	echo "${0}: ---Invalid test cases---"
-	check_input "${invalid_input}" invalid $test_file
-	RC=$(( RC | $? ))
-	return $RC
-}
-
-# Checking test environment
-check_arch
-
-# Check sched_smt_power_savings interface on HT machines
-hyper_threaded=$(is_hyper_threaded)
-if [ ! -f /sys/devices/system/cpu/sched_smt_power_savings ] ; then
-	tst_brkm TCONF "Required kernel configuration for SCHED_SMT NOT set"
-else
-	if [ $hyper_threaded -ne 0 ]; then
-		tst_brkm TCONF "sched_smt_power_saving interface in system" \
-			"not hyper-threaded"
-	fi
-fi
-
-if test_sched_smt ; then
-	tst_resm TPASS "SCHED_SMT sysfs test"
-else
-	tst_resm TFAIL "SCHED_SMT sysfs test"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests05.sh b/testcases/kernel/power_management/runpwtests05.sh
deleted file mode 100755
index 03b6752bf3..0000000000
--- a/testcases/kernel/power_management/runpwtests05.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management05"
-export TST_TOTAL=2
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-max_sched_mc=2
-max_sched_smt=2
-
-tst_require_cmds python3
-
-if ! grep sched_debug -qw /proc/cmdline ; then
-	tst_brkm TCONF "Kernel cmdline parameter 'sched_debug' needed," \
-		"CPU Consolidation test cannot run"
-fi
-
-hyper_threaded=$(is_hyper_threaded)
-if [ ! -f /sys/devices/system/cpu/sched_mc_power_savings \
-	-o $hyper_threaded -ne 0 ] ; then
-	tst_brkm TCONF "Required kernel configuration for SCHED_MC" \
-		"NOT set, or sched_mc_power_savings interface in system" \
-		"which is not hyper-threaded"
-fi
-
-# sched_domain test
-echo "max sched mc $max_sched_mc"
-RC=0
-for sched_mc in `seq 0 $max_sched_mc`; do
-	pm_sched_domain.py -c $sched_mc; ret=$?
-	analyze_sched_domain_result $sched_mc $ret; RC=$?
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "Sched_domain test for sched_mc"
-else
-	tst_resm TFAIL "Sched_domain test for sched_mc"
-fi
-
-# Testcase to validate sched_domain tree
-RC=0
-for sched_mc in `seq 0 $max_sched_mc`; do
-	pm_get_sched_values sched_smt; max_sched_smt=$?
-	for sched_smt in `seq 0 $max_sched_smt`; do
-		pm_sched_domain.py -c $sched_mc -t $sched_smt; ret=$?
-		analyze_sched_domain_result $sched_mc $ret $sched_smt; RC=$?
-	done
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "Sched_domain test for sched_mc & sched_smt"
-else
-	tst_resm TFAIL "Sched_domain test for sched_mc & sched_smt"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests_exclusive01.sh b/testcases/kernel/power_management/runpwtests_exclusive01.sh
deleted file mode 100755
index f309d7c196..0000000000
--- a/testcases/kernel/power_management/runpwtests_exclusive01.sh
+++ /dev/null
@@ -1,97 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management_exclusive01"
-export TST_TOTAL=2
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-max_sched_mc=2
-max_sched_smt=2
-
-tst_require_cmds python3
-
-hyper_threaded=$(is_hyper_threaded)
-multi_socket=$(is_multi_socket)
-multi_core=$(is_multi_core)
-if [ $multi_socket -ne 0 -o $multi_core -ne 0 -o \
-	$hyper_threaded -ne 0 ]; then
-	tst_brkm TCONF "System is not a multi socket & multi core" \
-		"& hyper-threaded"
-fi
-
-# Test CPU consolidation
-RC=0
-for sched_mc in `seq 0  $max_sched_mc`; do
-	sched_mc_pass_cnt=0
-	if [ $sched_mc -eq 2 ]; then
-		work_load="kernbench"
-	else
-		work_load="ebizzy"
-	fi
-	for repeat_test in `seq 1  10`; do
-		#Testcase to validate CPU consolidation for sched_mc
-		if pm_cpu_consolidation.py -c $sched_mc -w $work_load ; then
-		: $(( sched_mc_pass_cnt += 1 ))
-		fi
-	done
-	analyze_package_consolidation_result $sched_mc \
-		$sched_mc_pass_cnt; RC=$?
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "CPU consolidation test for sched_mc"
-else
-	tst_resm TFAIL "CPU consolidation test for sched_mc"
-fi
-
-RC=0
-for sched_mc in `seq 0  $max_sched_mc`; do
-	if [ $sched_mc -eq 2 ]; then
-		work_load="kernbench"
-	else
-		work_load="ebizzy"
-	fi
-	for sched_smt in `seq 0 $max_sched_smt`; do
-		sched_mc_smt_pass_cnt=0
-		for repeat_test in `seq 1  10`; do
-			# Testcase to validate CPU consolidation for
-			# for sched_mc & sched_smt with stress=50%
-			if pm_cpu_consolidation.py -c $sched_mc -t $sched_smt \
-				-w $work_load ; then
-				: $(( sched_mc_smt_pass_cnt += 1 ))
-			fi
-		done
-		analyze_package_consolidation_result $sched_mc \
-			$sched_mc_smt_pass_cnt $sched_smt; RC=$?
-	done
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "CPU consolidation test for sched_mc &" \
-		"sched_smt with stress=50%"
-else
-	tst_resm TFAIL "CPU consolidation test for sched_mc &" \
-		"sched_smt with stress=50%"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests_exclusive02.sh b/testcases/kernel/power_management/runpwtests_exclusive02.sh
deleted file mode 100755
index 547e88feaf..0000000000
--- a/testcases/kernel/power_management/runpwtests_exclusive02.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management_exclusive02"
-export TST_TOTAL=1
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-max_sched_smt=2
-
-tst_require_cmds python3
-
-hyper_threaded=$(is_hyper_threaded)
-multi_socket=$(is_multi_socket)
-multi_core=$(is_multi_core)
-if [ $hyper_threaded -ne 0 -o $multi_socket -ne 0 \
-	-o $multi_core -eq 0 ]; then
-	tst_brkm TCONF "System is a multi core but not multi" \
-		"socket & hyper-threaded"
-fi
-
-#Testcase to validate consolidation at core level
-RC=0
-for sched_smt in `seq 0 $max_sched_smt`; do
-	if [ $sched_smt -eq 2 ]; then
-		work_load="kernbench"
-	else
-		work_load="ebizzy"
-	fi
-	sched_smt_pass_cnt=0
-	stress="thread"
-	for repeat_test in `seq 1  10`; do
-		if pm_cpu_consolidation.py -t $sched_smt -w $work_load \
-			-s $stress; then
-			: $(( sched_smt_pass_cnt += 1 ))
-		fi
-	done
-	analyze_core_consolidation_result $sched_smt \
-		$sched_smt_pass_cnt; RC=$?
-done
-if [ $RC -eq 0 ]; then
-    tst_resm TPASS "Consolidation test at core level for sched_smt"
-else
-    tst_resm TFAIL "Consolidation test at core level for sched_smt"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests_exclusive03.sh b/testcases/kernel/power_management/runpwtests_exclusive03.sh
deleted file mode 100755
index 67c7243e8f..0000000000
--- a/testcases/kernel/power_management/runpwtests_exclusive03.sh
+++ /dev/null
@@ -1,95 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management_exclusive03"
-export TST_TOTAL=2
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-max_sched_mc=2
-max_sched_smt=2
-
-tst_require_cmds python3
-
-hyper_threaded=$(is_hyper_threaded)
-multi_socket=$(is_multi_socket)
-multi_core=$(is_multi_core)
-if [ $multi_socket -ne 0 -o $multi_core -ne 0 -o \
-	$hyper_threaded -ne 0 ]; then
-	tst_brkm TCONF "System is not a multi socket & multi core" \
-		"& hyper-threaded"
-fi
-
-# Verify threads consolidation stops when sched_mc &(/) sched_smt
-# is disabled.
-# Vary sched_mc from 1/2 to 0 when workload is running and
-# ensure that tasks do not consolidate to single package when
-# sched_mc is set to 0.
-RC=0
-for sched_mc in `seq 1  $max_sched_mc`; do
-	if pm_cpu_consolidation.py -v -c $sched_mc; then
-		echo "Test PASS: CPU consolidation test by varying" \
-			"sched_mc $sched_mc to 0"
-	else
-		RC=1
-		echo "Test FAIL: CPU consolidation test by varying" \
-			"sched_mc $sched_mc to 0"
-	fi
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "CPU consolidation test by varying sched_mc"
-else
-	tst_resm TFAIL "CPU consolidation test by varying sched_mc"
-fi
-
-# Vary sched_mc & sched_smt from 1 to 0 & 2 to 0 when workload
-# is running and ensure that tasks do not consolidate to single
-# package when sched_mc is set to 0.
-RC=0
-for sched_mc in `seq 1  $max_sched_mc`; do
-	for sched_smt in `seq 1  $max_sched_smt`; do
-		if [ $sched_smt -eq $sched_mc ]; then
-			if pm_cpu_consolidation.py -v -c $sched_mc \
-				-t $sched_smt; then
-				echo "Test PASS: CPU consolidation test by" \
-					"varying sched_mc & sched_smt from" \
-					"$sched_mc to 0"
-			else
-				RC=1
-				echo "Test FAIL: CPU consolidation test by" \
-					"varying sched_mc & sched_smt from" \
-					"$sched_mc to 0"
-			fi
-		fi
-	done
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "CPU consolidation test by varying" \
-		"sched_mc & sched_smt"
-else
-	tst_resm TFAIL "CPU consolidation test by varying" \
-		"sched_mc & sched_smt"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests_exclusive04.sh b/testcases/kernel/power_management/runpwtests_exclusive04.sh
deleted file mode 100755
index 46985b3be5..0000000000
--- a/testcases/kernel/power_management/runpwtests_exclusive04.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management_exclusive04"
-export TST_TOTAL=2
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-tst_require_cmds python3
-
-hyper_threaded=$(is_hyper_threaded)
-multi_socket=$(is_multi_socket)
-if [ $hyper_threaded -ne 0 -o $multi_socket -ne 0 ]; then
-	tst_brkm TCONF "System is not a multi socket & hyper-threaded"
-fi
-
-# Verify threads consolidation stops when sched_smt is
-# disabled in HT systems.
-# Vary only sched_smt from 1 to 0 when workload is running
-# and ensure that tasks do not consolidate to single core
-# when sched_smt is set to 0.
-if pm_cpu_consolidation.py -v -t 1; then
-	tst_resm TPASS "CPU consolidation test by varying sched_smt from 1 to 0"
-else
-	tst_resm TFAIL "CPU consolidation test by varying sched_smt from 1 to 0"
-fi
-
-# Vary only sched_smt from 2 to 0 when workload is running
-# and ensure that tasks do not consolidate to single core
-# when sched_smt is set to 0.
-if pm_cpu_consolidation.py -v -t 2; then
-	tst_resm TPASS "CPU consolidation test by varying sched_smt from 2 to 0"
-else
-	tst_resm TFAIL "CPU consolidation test by varying sched_smt from 2 to 0"
-fi
-
-tst_exit
diff --git a/testcases/kernel/power_management/runpwtests_exclusive05.sh b/testcases/kernel/power_management/runpwtests_exclusive05.sh
deleted file mode 100755
index 38450d1fdf..0000000000
--- a/testcases/kernel/power_management/runpwtests_exclusive05.sh
+++ /dev/null
@@ -1,97 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) International Business Machines  Corp., 2001
-# Author: Nageswara R Sastry <nasastry@in.ibm.com>
-#
-# This program is free software;  you can redistribute it and#or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-export TCID="Power_Management_exclusive05"
-export TST_TOTAL=2
-
-. test.sh
-. pm_include.sh
-
-# Checking test environment
-check_arch
-
-max_sched_mc=2
-max_sched_smt=2
-
-tst_require_cmds python3
-
-hyper_threaded=$(is_hyper_threaded)
-multi_socket=$(is_multi_socket)
-multi_core=$(is_multi_core)
-if [ $multi_socket -ne 0 -o $multi_core -ne 0 -o \
-	$hyper_threaded -ne 0 ]; then
-	tst_brkm TCONF "System is not a multi socket & multi core" \
-		"& hyper-threaded"
-fi
-
-# Verify ILB runs in same package as workload.
-RC=0
-for sched_mc in `seq 1 $max_sched_mc`; do
-	if [ $sched_mc -eq 2 ]; then
-		work_load="kernbench"
-	else
-		work_load="ebizzy"
-	fi
-
-	pm_ilb_test.py -c $sched_mc -w $work_load
-	if [ $? -eq 0 ]; then
-		echo "Test PASS: ILB & workload in same package for" \
-			"sched_mc=$sched_mc"
-	else
-		RC=1
-		echo "Test FAIL: ILB & workload did not run in same package" \
-			"for sched_mc=$sched_mc. Ensure CONFIG_NO_HZ is set"
-	fi
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "ILB & workload test in same package for sched_mc"
-else
-	tst_resm TFAIL "ILB & workload test in same package for sched_mc"
-fi
-
-RC=0
-for sched_mc in `seq 1 $max_sched_mc`; do
-	if [ $sched_mc -eq 2 ]; then
-		work_load="kernbench"
-	else
-		work_load="ebizzy"
-	fi
-	for sched_smt in `seq 1 $max_sched_smt`; do
-		pm_ilb_test.py -c $sched_mc -t sched_smt -w $work_load
-		if [ $? -eq 0 ]; then
-			echo "Test PASS: ILB & workload in same package for" \
-				"sched_mc=$sched_mc & sched_smt=$sched_smt"
-		else
-			RC=1
-			echo "Test FAIL: ILB & workload did not execute in" \
-				"same package for sched_mc=$sched_mc &" \
-				"sched_smt=$sched_smt. Ensure CONFIG_NO_HZ is set"
-		fi
-	done
-done
-if [ $RC -eq 0 ]; then
-	tst_resm TPASS "ILB & workload test in same package for" \
-		"sched_mc & sched_smt"
-else
-	tst_resm TFAIL "ILB & workload test in same package for" \
-		"sched_mc & sched_smt"
-fi
-
-tst_exit
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 0/2] power_management: remove unsupported tests
From: Petr Vorel @ 2026-03-30  9:08 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Li Wang, Cyril Hrubis, Jan Stancek, Andrea Cervesato,
	Daniel Lezcano, Rafael J . Wysocki, Zhang Rui, Lukasz Luba,
	linux-pm, helena.anna.dubel, tomasz.ossowski, Piotr Kubaj,
	automated-testing

Hi all,

after the removal there will be 3 tests in runtest/power_management_tests:
runpwtests0[346].sh [1] [2] [3] (besides recent Piotr's patch).
@power management folks: you're move than welcome to review usefulness
of these tests.

These are very simple ones, they touch just sysfs. IMHO still relevant,
if we keep them it should be cleaned and rewritten to use LTP API
(ideally C API).

Changes v1->v2:
Use 2 years old Cyril's patch [2] which removes even more tests
(runpwtests_exclusive0*.sh). Follow it with new patch removing unused tools.
My commit can be squashed, but maybe it's easier to review when separated.

Link to v1: [5].

Kind regards,
Petr

[1] https://github.com/linux-test-project/ltp/blob/4688c20c01eece869b59e05ca3dd68c43e0d6af7/testcases/kernel/power_management/runpwtests03.sh
[2] https://github.com/linux-test-project/ltp/blob/4688c20c01eece869b59e05ca3dd68c43e0d6af7/testcases/kernel/power_management/runpwtests04.sh
[3] https://github.com/linux-test-project/ltp/blob/4688c20c01eece869b59e05ca3dd68c43e0d6af7/testcases/kernel/power_management/runpwtests06.sh
[4] https://patchwork.ozlabs.org/project/ltp/patch/20240916113308.16749-1-chrubis@suse.cz/
[5] https://patchwork.ozlabs.org/project/ltp/patch/20260318132639.18818-3-pvorel@suse.cz/

Cyril Hrubis (1):
  Remove now unsupported power management tests

Petr Vorel (1):
  power_management: Remove unused tools

 runtest/power_management_tests                |   3 -
 runtest/power_management_tests_exclusive      |   6 -
 testcases/kernel/power_management/.gitignore  |   1 -
 testcases/kernel/power_management/Makefile    |   2 +-
 testcases/kernel/power_management/README      |  29 -
 .../kernel/power_management/lib/Makefile      |  25 -
 .../power_management/lib/pm_sched_mc.py       | 835 ------------------
 .../power_management/pm_cpu_consolidation.py  | 143 ---
 .../power_management/pm_get_sched_values.c    |  36 -
 .../kernel/power_management/pm_ilb_test.py    |  57 --
 .../kernel/power_management/pm_include.sh     | 311 +------
 .../power_management/pm_sched_domain.py       |  54 --
 .../kernel/power_management/runpwtests01.sh   |  71 --
 .../kernel/power_management/runpwtests02.sh   |  68 --
 .../kernel/power_management/runpwtests03.sh   |  10 +
 .../kernel/power_management/runpwtests05.sh   |  76 --
 .../kernel/power_management/runpwtests06.sh   |  31 +
 .../runpwtests_exclusive01.sh                 |  97 --
 .../runpwtests_exclusive02.sh                 |  68 --
 .../runpwtests_exclusive03.sh                 |  95 --
 .../runpwtests_exclusive04.sh                 |  58 --
 .../runpwtests_exclusive05.sh                 |  97 --
 22 files changed, 43 insertions(+), 2130 deletions(-)
 delete mode 100644 runtest/power_management_tests_exclusive
 delete mode 100644 testcases/kernel/power_management/.gitignore
 delete mode 100644 testcases/kernel/power_management/lib/Makefile
 delete mode 100755 testcases/kernel/power_management/lib/pm_sched_mc.py
 delete mode 100755 testcases/kernel/power_management/pm_cpu_consolidation.py
 delete mode 100644 testcases/kernel/power_management/pm_get_sched_values.c
 delete mode 100755 testcases/kernel/power_management/pm_ilb_test.py
 delete mode 100755 testcases/kernel/power_management/pm_sched_domain.py
 delete mode 100755 testcases/kernel/power_management/runpwtests01.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests02.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests05.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive01.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive02.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive03.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive04.sh
 delete mode 100755 testcases/kernel/power_management/runpwtests_exclusive05.sh

-- 
2.53.0


^ permalink raw reply

* Re: [RFC PATCH 1/2] thermal/cpufreq_cooling: remove unused cpu_idx in get_load()
From: Lukasz Luba @ 2026-03-30  8:56 UTC (permalink / raw)
  To: Qais Yousef
  Cc: Xuewen Yan, Viresh Kumar, Xuewen Yan, rui.zhang, rafael, linux-pm,
	amit.kachhap, daniel.lezcano, linux-kernel, ke.wang, di.shen,
	jeson.gao, Peter Zijlstra, Vincent Guittot
In-Reply-To: <20260328080940.hhfeqisvr4lpx4yk@airbuntu>



On 3/28/26 08:09, Qais Yousef wrote:
> On 03/26/26 09:21, Lukasz Luba wrote:
>>
>>
>> On 3/26/26 09:05, Qais Yousef wrote:
>>> On 03/24/26 10:46, Lukasz Luba wrote:
>>>>
>>>> On 3/24/26 02:20, Xuewen Yan wrote:
>>>>> On Mon, Mar 23, 2026 at 9:25 PM Lukasz Luba <lukasz.luba@arm.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 3/23/26 11:06, Viresh Kumar wrote:
>>>>>>> On 23-03-26, 10:52, Lukasz Luba wrote:
>>>>>>>>> How is that okay ? What am I missing ?
>>>>>>>
>>>>>>> I was missing !SMP :)
>>>>>>>
>>>>>>>> Right, there is a mix of two things.
>>>>>>>> The 'i' left but should be removed as well, since
>>>>>>>> this is !SMP code with only 1 cpu and i=0.
>>>>>
>>>>> That's also why we sent out patch 1/2; after all, it is always 0 on
>>>>> !SMP systems.
>>>>>
>>>>>>>>
>>>>>>>> The whole split which has been made for getting
>>>>>>>> the load or utilization from CPU(s) needs to be
>>>>>>>> cleaned. The compiled code looks different since
>>>>>>>> it knows there is non-SMP config used.
>>>>>>>
>>>>>>> Right, we are allocating that for num_cpus (which should be 1 CPU
>>>>>>> anyway). The entire thing must be cleaned.
>>>>>>>
>>>>>>>> Do you want to clean that or I should do this?
>>>>>>>
>>>>>>> It would be helpful if you can do it :)
>>>>>>>
>>>>>>
>>>>>> OK, I will. Thanks for your involvement Viresh!
>>>>>>
>>>>>> Xuewen please wait with your v2, I will send
>>>>>> a redesign of this left code today.
>>>>>
>>>>> Okay, and Qais's point is also worth considering: do we actually need
>>>>> sched_cpu_util()?
>>>>> The way I see it, generally speaking, the request_power derived from
>>>>> idle_time might be higher than what we get from sched_cpu_util().
>>>>> Take this scenario as an example:
>>>>> Consider a CPU running at the lowest frequency with 50% idle time,
>>>>> versus one running at the highest frequency with the same 50% idle
>>>>> time.
>>>>> In this case, using idle_time yields the same load value for both.
>>>>> However, sched_cpu_util() would report a lower load when the CPU
>>>>> frequency is low. This results in a smaller request_power...
>>>
>>> Invariance will cause settling time to stretch longer, but it should settle to
>>> the correct value eventually. But generally another case against util is that
>>> it has grown to be a description of compute demand more than true idleness of
>>> the system.
>>>
>>>>
>>>> Right, there are 2 things to consider:
>>>> 1. what is the utilization when the CPU still have idle time, e.g.
>>>>      this 50% that you mentioned
>>>> 2. what is the utilization when there is no idle time and CPU
>>>>      is fully busy (and starts throttling due to heat)
>>>
>>> Hmm I think what you're trying to say here we need to distinguish between two
>>> cases 50% or fully busy? I think how idle the system is a better question to
>>> ask rather than what is the utilization (given the ubiquity of the signal
>>> nowadays)
>>
>> Yes, these two cases, which are different and util signal is not the
>> best for that idleness one.
>>
>>
>>>
>>>>
>>>> In this thermal fwk we are mostly in the 2nd case. In that case the
>>>
>>> But from power allocator perspective (which I think is the context, right?),
>>> you want to know if you can shift power?
>>
>> I would like to know the avg power in the last X ms window, then
>> allocate, shift, set.
>>
>>>
>>>> utilization on CPU's runqueue goes to 1024 no mater the CPU's frequency.
>>>> We know which highest frequency was allowed to run and we pick the power
>>>> value from EM for it. That's why the estimation is not that bad (apart
>>>> from power variation for different flavors of workloads: heavy SIMD vs.
>>>> normal integer/load).
>>>>
>>>> In 1st case scenario we might underestimate the power, but that
>>>> is not the thermal stress situation anyway, so the max OPP is
>>>> still allowed.
>>>>
>>>> So far it is hard to find the best power model to use and robust CPU
>>>> load mechanisms. Adding more complexity and creating some
>>>> over-engineered code in the kernel to maintain might not have sense.
>>>> The thermal solutions are solved in the Firmware nowadays since the
>>>> kernel won't react that fast for some rapid changes.
>>>>
>>>> We have to balance the complexity here.
>>>
>>> I am not verse in all the details, so not sure what complexity you are
>>> referring to. IMHO the idle time is a more stable view for how much a breathing
>>> room the cpu has. It also deals better with long decay of blocked load
>>> over-estimating the utilization. AFAICS just sample the idle over a window when
>>> you need to take a decision and you'd solve several problems in one go.
>>
>> We have issues in estimating power in that X ms window due to fast
>> frequency changes. You know how often we can change the frequency,
>> almost per-task enqueue (and e.g. uclamp pushes that even harder).
>>
>> Simple approach for assuming that the frequency we see now on CPU
>> has been there for the whole Xms period is 'not the best'.
>> The util information w/o uclamp information is not helping
>> much (even we we would try to derive the freq out of it).
>>
>> Now even more complex - the FW can change the freq way often
>> than the kernel. So the question is how far we have to push
>> the whole kernel and those frameworks to deal with those new
>> platforms.
>>
>> Then add the power variation due to different computation types
>> e.g. SIMD heavy vs simple logging task (high power vs. low power
>> usage at the same OPP).
>>
>> IMHO we have to find a balance since even more complex models
>> in kernel won't be able to handle that.
>>
>> I have been experimenting with the Active Stats patch set for
>> quite a while, but then FW came into the equation and complicated
>> the situation. It will be still better for such platform
>> where FW doesn't change the freq, so this approach based on
>> idle stats is worth to add IMO.
> 
> Hmm isn't this orthogonal? It seems cpu util is used today to estimate how busy
> (or idle) the cpu is. You can decouple the dep on util (and scheduler in
> general) and monitor system idleness.
> 
> Anyway. Please don't add this ifdefry and the strange deps on scx. This is
> a recipe for shooting ourselves in the foot.

I cannot agree more. Those ifdefs should be moved away. I've discussed
this design at last LPC25 thermal conference. I suggested that I'll
combine the power estimation here and in the DTPM, since they use the
same model (both based on util).

Let's fix the model first and make it more robust, then I will combine
the two.


^ permalink raw reply

* [char-misc v4] mei: me: reduce the scope on unexpected reset
From: Alexander Usyskin @ 2026-03-30  8:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, Rafael J . Wysocki, linux-pm,
	linux-kernel, Rafael J . Wysocki, Todd Brandt

After commit 2cedb296988c ("mei: me: trigger link reset if hw ready is unexpected")
some devices started to show long resume times (5-7 seconds).
This happens as mei falsely detects unready hardware,
starts parallel link reset flow and triggers link reset timeouts
in the resume callback.

Address it by performing detection of unready hardware only
when driver is in the MEI_DEV_ENABLED state instead of blacklisting
states as done in the original patch.
This eliminates active waitqueue check as in MEI_DEV_ENABLED state
there will be no active waitqueue.

Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221023
Tested-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Fixes: 2cedb296988c ("mei: me: trigger link reset if hw ready is unexpected")
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---

V4: extend commit message, add Rafael's r-b

V3: reword commit message, add Rafael and PM list

V2: rebase over v7.0-rc4

 drivers/misc/mei/hw-me.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index d4612c659784..1e4a41ac428f 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1337,19 +1337,13 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
 	/*  check if we need to start the dev */
 	if (!mei_host_is_ready(dev)) {
 		if (mei_hw_is_ready(dev)) {
-			/* synchronized by dev mutex */
-			if (waitqueue_active(&dev->wait_hw_ready)) {
-				dev_dbg(&dev->dev, "we need to start the dev.\n");
-				dev->recvd_hw_ready = true;
-				wake_up(&dev->wait_hw_ready);
-			} else if (dev->dev_state != MEI_DEV_UNINITIALIZED &&
-				   dev->dev_state != MEI_DEV_POWERING_DOWN &&
-				   dev->dev_state != MEI_DEV_POWER_DOWN) {
+			if (dev->dev_state == MEI_DEV_ENABLED) {
 				dev_dbg(&dev->dev, "Force link reset.\n");
 				schedule_work(&dev->reset_work);
 			} else {
-				dev_dbg(&dev->dev, "Ignore this interrupt in state = %d\n",
-					dev->dev_state);
+				dev_dbg(&dev->dev, "we need to start the dev.\n");
+				dev->recvd_hw_ready = true;
+				wake_up(&dev->wait_hw_ready);
 			}
 		} else {
 			dev_dbg(&dev->dev, "Spurious Interrupt\n");
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4 9/9] arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
From: Luca Leonardo Scorcia @ 2026-03-30  8:29 UTC (permalink / raw)
  To: linux-mediatek
  Cc: Val Packett, Luca Leonardo Scorcia, Dmitry Torokhov, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sen Chu, Sean Wang,
	Macpaul Lin, Lee Jones, Matthias Brugger,
	AngeloGioacchino Del Regno, Linus Walleij, Liam Girdwood,
	Mark Brown, Julien Massot, Louis-Alexis Eyraud, Gary Bisson,
	Fabien Parent, Chen Zhong, linux-input, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260330083429.359819-1-l.scorcia@gmail.com>

From: Val Packett <val@packett.cool>

Add the dts to be included by all boards using the MT6392 PMIC.

Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
 arch/arm64/boot/dts/mediatek/mt6392.dtsi | 73 ++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6392.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/mt6392.dtsi b/arch/arm64/boot/dts/mediatek/mt6392.dtsi
new file mode 100644
index 000000000000..750ee9b2856f
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6392.dtsi
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2024 Val Packett <val@packett.cool>
+ */
+
+#include <dt-bindings/input/input.h>
+
+&pwrap {
+	pmic: pmic {
+		compatible = "mediatek,mt6392", "mediatek,mt6323";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		keys {
+			compatible = "mediatek,mt6392-keys";
+
+			key-power {
+				linux,keycodes = <KEY_POWER>;
+				wakeup-source;
+			};
+
+			key-home {
+				linux,keycodes = <KEY_HOME>;
+				wakeup-source;
+			};
+		};
+
+		pio6392: pinctrl {
+			compatible = "mediatek,mt6392-pinctrl";
+
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		rtc {
+			compatible = "mediatek,mt6392-rtc",
+				"mediatek,mt6323-rtc";
+		};
+
+		mt6392regulators: regulators {
+			/* Fixed supply defined in the data sheet */
+			avddldo-supply = <&mt6392_vsys_reg>;
+
+			mt6392_vcore_reg: vcore { };
+			mt6392_vproc_reg: vproc { };
+			mt6392_vsys_reg: vsys { };
+			mt6392_vaud28_reg: vaud28 { };
+			mt6392_vxo22_reg: vxo22 { };
+			mt6392_vaud22_reg: vaud22 { };
+			mt6392_vadc18_reg: vadc18 { };
+			mt6392_vcama_reg: vcama { };
+			mt6392_vcn35_reg: vcn35 { };
+			mt6392_vio28_reg: vio28 { };
+			mt6392_vusb_reg: vusb { };
+			mt6392_vmc_reg: vmc { };
+			mt6392_vmch_reg: vmch { };
+			mt6392_vemc3v3_reg: vemc3v3 { };
+			mt6392_vcamaf_reg: vcamaf { };
+			mt6392_vgp1_reg: vgp1 { };
+			mt6392_vgp2_reg: vgp2 { };
+			mt6392_vefuse_reg: vefuse { };
+			mt6392_vm25_reg: vm25 { };
+			mt6392_vdig18_reg: vdig18 { };
+			mt6392_vm_reg: vm { };
+			mt6392_vio18_reg: vio18 { };
+			mt6392_vcn18_reg: vcn18 { };
+			mt6392_vcamd_reg: vcamd { };
+			mt6392_vcamio_reg: vcamio { };
+			mt6392_vrtc_reg: vrtc {	};
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4 8/9] pinctrl: mediatek: mt6397: Add MediaTek MT6392
From: Luca Leonardo Scorcia @ 2026-03-30  8:29 UTC (permalink / raw)
  To: linux-mediatek
  Cc: Luca Leonardo Scorcia, AngeloGioacchino Del Regno,
	Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	Linus Walleij, Liam Girdwood, Mark Brown, Louis-Alexis Eyraud,
	Val Packett, Julien Massot, Gary Bisson, Fabien Parent,
	Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, linux-gpio
In-Reply-To: <20260330083429.359819-1-l.scorcia@gmail.com>

Add support for the MT6392 pinctrl device, which is very similar to
MT6397 with a handful of different property values and its own pins
definition.

Update the MT6397 driver to retrieve device data from the match table and
use it for driver init.

Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/pinctrl/mediatek/pinctrl-mt6397.c     | 37 ++++++++++-
 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h | 64 +++++++++++++++++++
 2 files changed, 99 insertions(+), 2 deletions(-)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
index 03d0f65d7bcc..8ba02e70595c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6397.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
@@ -12,10 +12,32 @@
 #include <linux/mfd/mt6397/core.h>
 
 #include "pinctrl-mtk-common.h"
+#include "pinctrl-mtk-mt6392.h"
 #include "pinctrl-mtk-mt6397.h"
 
 #define MT6397_PIN_REG_BASE  0xc000
 
+static const struct mtk_pinctrl_devdata mt6392_pinctrl_data = {
+	.pins = mtk_pins_mt6392,
+	.npins = ARRAY_SIZE(mtk_pins_mt6392),
+	.dir_offset = (MT6397_PIN_REG_BASE + 0x000),
+	.ies_offset = MTK_PINCTRL_NOT_SUPPORT,
+	.smt_offset = MTK_PINCTRL_NOT_SUPPORT,
+	.pullen_offset = (MT6397_PIN_REG_BASE + 0x020),
+	.pullsel_offset = (MT6397_PIN_REG_BASE + 0x040),
+	.dout_offset = (MT6397_PIN_REG_BASE + 0x080),
+	.din_offset = (MT6397_PIN_REG_BASE + 0x0a0),
+	.pinmux_offset = (MT6397_PIN_REG_BASE + 0x0c0),
+	.type1_start = 7,
+	.type1_end = 7,
+	.port_shf = 3,
+	.port_mask = 0x3,
+	.port_align = 2,
+	.mode_mask = 0xf,
+	.mode_per_reg = 5,
+	.mode_shf = 4,
+};
+
 static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = {
 	.pins = mtk_pins_mt6397,
 	.npins = ARRAY_SIZE(mtk_pins_mt6397),
@@ -40,13 +62,24 @@ static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = {
 static int mt6397_pinctrl_probe(struct platform_device *pdev)
 {
 	struct mt6397_chip *mt6397;
+	const struct mtk_pinctrl_devdata *data;
+
+	data = device_get_match_data(&pdev->dev);
+	if (!data)
+		return -ENOENT;
 
 	mt6397 = dev_get_drvdata(pdev->dev.parent);
-	return mtk_pctrl_init(pdev, &mt6397_pinctrl_data, mt6397->regmap);
+	return mtk_pctrl_init(pdev, data, mt6397->regmap);
 }
 
 static const struct of_device_id mt6397_pctrl_match[] = {
-	{ .compatible = "mediatek,mt6397-pinctrl", },
+	{
+		.compatible = "mediatek,mt6392-pinctrl",
+		.data = &mt6392_pinctrl_data
+	}, {
+		.compatible = "mediatek,mt6397-pinctrl",
+		.data = &mt6397_pinctrl_data
+	},
 	{ }
 };
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
new file mode 100644
index 000000000000..e7241af28fdb
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PINCTRL_MTK_MT6392_H
+#define __PINCTRL_MTK_MT6392_H
+
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-mtk-common.h"
+
+static const struct mtk_desc_pin mtk_pins_mt6392[] = {
+	MTK_PIN(PINCTRL_PIN(0, "INT"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO0"),
+		MTK_FUNCTION(1, "INT"),
+		MTK_FUNCTION(5, "TEST_CK2"),
+		MTK_FUNCTION(6, "TEST_IN1"),
+		MTK_FUNCTION(7, "TEST_OUT1")
+	),
+	MTK_PIN(PINCTRL_PIN(1, "SRCLKEN"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO1"),
+		MTK_FUNCTION(1, "SRCLKEN"),
+		MTK_FUNCTION(5, "TEST_CK0"),
+		MTK_FUNCTION(6, "TEST_IN2"),
+		MTK_FUNCTION(7, "TEST_OUT2")
+	),
+	MTK_PIN(PINCTRL_PIN(2, "RTC_32K1V8"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO2"),
+		MTK_FUNCTION(1, "RTC_32K1V8"),
+		MTK_FUNCTION(5, "TEST_CK1"),
+		MTK_FUNCTION(6, "TEST_IN3"),
+		MTK_FUNCTION(7, "TEST_OUT3")
+	),
+	MTK_PIN(PINCTRL_PIN(3, "SPI_CLK"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO3"),
+		MTK_FUNCTION(1, "SPI_CLK")
+	),
+	MTK_PIN(PINCTRL_PIN(4, "SPI_CSN"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO4"),
+		MTK_FUNCTION(1, "SPI_CSN")
+	),
+	MTK_PIN(PINCTRL_PIN(5, "SPI_MOSI"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO5"),
+		MTK_FUNCTION(1, "SPI_MOSI")
+	),
+	MTK_PIN(PINCTRL_PIN(6, "SPI_MISO"),
+		NULL, "mt6392",
+		MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
+		MTK_FUNCTION(0, "GPIO6"),
+		MTK_FUNCTION(1, "SPI_MISO"),
+		MTK_FUNCTION(6, "TEST_IN4"),
+		MTK_FUNCTION(7, "TEST_OUT4")
+	),
+};
+
+#endif /* __PINCTRL_MTK_MT6392_H */
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4 7/9] regulator: Add MediaTek MT6392 regulator
From: Luca Leonardo Scorcia @ 2026-03-30  8:29 UTC (permalink / raw)
  To: linux-mediatek
  Cc: Fabien Parent, Val Packett, Luca Leonardo Scorcia,
	AngeloGioacchino Del Regno, Dmitry Torokhov, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sen Chu, Sean Wang,
	Macpaul Lin, Lee Jones, Matthias Brugger, Linus Walleij,
	Liam Girdwood, Mark Brown, Julien Massot, Louis-Alexis Eyraud,
	Gary Bisson, Chen Zhong, linux-input, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260330083429.359819-1-l.scorcia@gmail.com>

From: Fabien Parent <parent.f@gmail.com>

The MT6392 is a regulator found on boards based on the MediaTek
MT8167, MT8516, and probably other SoCs. It is a so called PMIC and
connects as a slave to a SoC using SPI, wrapped inside PWRAP.

Signed-off-by: Fabien Parent <parent.f@gmail.com>
Co-developed-by: Val Packett <val@packett.cool>
Signed-off-by: Val Packett <val@packett.cool>
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/regulator/Kconfig                  |   9 +
 drivers/regulator/Makefile                 |   1 +
 drivers/regulator/mt6392-regulator.c       | 509 +++++++++++++++++++++
 include/linux/regulator/mt6392-regulator.h |  42 ++
 4 files changed, 561 insertions(+)
 create mode 100644 drivers/regulator/mt6392-regulator.c
 create mode 100644 include/linux/regulator/mt6392-regulator.h

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index d10b6f9243d5..7ae06634a12b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1000,6 +1000,15 @@ config REGULATOR_MT6380
 	  This driver supports the control of different power rails of device
 	  through regulator interface.
 
+config REGULATOR_MT6392
+	tristate "MediaTek MT6392 PMIC"
+	depends on MFD_MT6397
+	help
+	  Say y here to select this option to enable the power regulator of
+	  MediaTek MT6392 PMIC.
+	  This driver supports the control of different power rails of device
+	  through regulator interface.
+
 config REGULATOR_MT6397
 	tristate "MediaTek MT6397 PMIC"
 	depends on MFD_MT6397
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 35639f3115fd..e5f1fa91b967 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
 obj-$(CONFIG_REGULATOR_MT6363) += mt6363-regulator.o
 obj-$(CONFIG_REGULATOR_MT6370) += mt6370-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
+obj-$(CONFIG_REGULATOR_MT6392)	+= mt6392-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
diff --git a/drivers/regulator/mt6392-regulator.c b/drivers/regulator/mt6392-regulator.c
new file mode 100644
index 000000000000..6e0278bded92
--- /dev/null
+++ b/drivers/regulator/mt6392-regulator.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2020 MediaTek Inc.
+// Copyright (c) 2020 BayLibre, SAS.
+// Author: Chen Zhong <chen.zhong@mediatek.com>
+// Author: Fabien Parent <fparent@baylibre.com>
+//
+// Based on mt6397-regulator.c
+
+#include <linux/module.h>
+#include <linux/linear_range.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6392/registers.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6392-regulator.h>
+#include <linux/regulator/of_regulator.h>
+#include <dt-bindings/regulator/mediatek,mt6392-regulator.h>
+
+/*
+ * MT6392 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ * @vselon_reg: Register sections for hardware control mode of bucks
+ * @vselctrl_reg: Register for controlling the buck control mode.
+ * @vselctrl_mask: Mask for query buck's voltage control mode.
+ */
+struct mt6392_regulator_info {
+	struct regulator_desc desc;
+	u32 qi;
+	u32 vselon_reg;
+	u32 vselctrl_reg;
+	u32 vselctrl_mask;
+	u32 modeset_reg;
+	u32 modeset_mask;
+};
+
+#define MT6392_BUCK(match, vreg, supply, min, max, step, volt_ranges,	\
+		enreg, vosel_reg, vosel_mask, voselon_reg, vosel_ctrl,	\
+		_modeset_reg, _modeset_mask, rampdelay)			\
+[MT6392_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.supply_name = supply,					\
+		.of_match = of_match_ptr(match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.ops = &mt6392_volt_range_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6392_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = ((max) - (min)) / (step) + 1,		\
+		.linear_ranges = volt_ranges,				\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),		\
+		.vsel_reg = vosel_reg,					\
+		.vsel_mask = vosel_mask,				\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(0),					\
+		.ramp_delay = rampdelay,				\
+	},								\
+	.qi = BIT(13),							\
+	.vselon_reg = voselon_reg,					\
+	.vselctrl_reg = vosel_ctrl,					\
+	.vselctrl_mask = BIT(1),					\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6392_LDO(match, vreg, supply, ldo_volt_table, enreg, enbit,	\
+		vosel_reg, vosel_mask, _modeset_reg, _modeset_mask,	\
+		entime)							\
+[MT6392_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.supply_name = supply,					\
+		.of_match = of_match_ptr(match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.ops = &mt6392_volt_table_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6392_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = ARRAY_SIZE(ldo_volt_table),		\
+		.volt_table = ldo_volt_table,				\
+		.vsel_reg = vosel_reg,					\
+		.vsel_mask = vosel_mask,				\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+		.enable_time = entime,					\
+	},								\
+	.qi = BIT(15),							\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6392_LDO_LINEAR(match, vreg, supply, min, max, step,		\
+		volt_ranges, enreg, enbit, vosel_reg, vosel_mask,	\
+		_modeset_reg, _modeset_mask, entime)			\
+[MT6392_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.supply_name = supply,					\
+		.of_match = of_match_ptr(match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.ops = &mt6392_volt_ldo_range_ops,			\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6392_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = ((max) - (min)) / (step) + 1,		\
+		.linear_ranges = volt_ranges,				\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),		\
+		.vsel_reg = vosel_reg,					\
+		.vsel_mask = vosel_mask,				\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+		.enable_time = entime,					\
+	},								\
+	.qi = BIT(15),							\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6392_REG_FIXED(match, vreg, supply, enreg, enbit, volt,	\
+		_modeset_reg, _modeset_mask, entime)			\
+[MT6392_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.supply_name = supply,					\
+		.of_match = of_match_ptr(match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.ops = &mt6392_volt_fixed_ops,				\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6392_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = 1,					\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+		.enable_time = entime,					\
+		.min_uV = volt,						\
+	},								\
+	.qi = BIT(15),							\
+	.modeset_reg = _modeset_reg,					\
+	.modeset_mask = _modeset_mask,					\
+}
+
+#define MT6392_REG_FIXED_NO_MODE(match, vreg, supply, enreg, enbit,	\
+	volt, entime)							\
+[MT6392_ID_##vreg] = {							\
+	.desc = {							\
+		.name = #vreg,						\
+		.supply_name = supply,					\
+		.of_match = of_match_ptr(match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.ops = &mt6392_volt_fixed_no_mode_ops,			\
+		.type = REGULATOR_VOLTAGE,				\
+		.id = MT6392_ID_##vreg,					\
+		.owner = THIS_MODULE,					\
+		.n_voltages = 1,					\
+		.enable_reg = enreg,					\
+		.enable_mask = BIT(enbit),				\
+		.enable_time = entime,					\
+		.min_uV = volt,						\
+	},								\
+	.qi = BIT(15),							\
+}
+
+static const struct linear_range buck_volt_range1[] = {
+	REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
+};
+
+static const struct linear_range buck_volt_range2[] = {
+	REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
+};
+
+static const u32 ldo_volt_table1[] = {
+	1800000, 1900000, 2000000, 2200000,
+};
+
+static const u32 ldo_volt_table1b[] = {
+	1500000, 1800000, 2500000, 2800000,
+};
+
+static const struct linear_range ldo_volt_range2[] = {
+	REGULATOR_LINEAR_RANGE(3300000, 0, 3, 100000),
+};
+
+static const u32 ldo_volt_table3[] = {
+	1800000, 3300000,
+};
+
+static const u32 ldo_volt_table4[] = {
+	3000000, 3300000,
+};
+
+static const u32 ldo_volt_table5[] = {
+	1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table6[] = {
+	1240000, 1390000,
+};
+
+static const u32 ldo_volt_table7[] = {
+	1200000, 1300000, 1500000, 1800000,
+};
+
+static const u32 ldo_volt_table8[] = {
+	1800000, 2000000,
+};
+
+static int mt6392_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	int ret, val = 0;
+	struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		val = MT6392_BUCK_MODE_FORCE_PWM;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		val = MT6392_BUCK_MODE_AUTO;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val <<= ffs(info->modeset_mask) - 1;
+
+	ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+				 info->modeset_mask, val);
+
+	return ret;
+}
+
+static unsigned int mt6392_buck_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	unsigned int mode;
+	int ret;
+	struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+	ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
+	if (ret < 0)
+		return ret;
+
+	val &= info->modeset_mask;
+	val >>= ffs(info->modeset_mask) - 1;
+
+	if (val & 0x1)
+		mode = REGULATOR_MODE_FAST;
+	else
+		mode = REGULATOR_MODE_NORMAL;
+
+	return mode;
+}
+
+static int mt6392_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	int ret, val = 0;
+	struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+	switch (mode) {
+	case REGULATOR_MODE_STANDBY:
+		val = MT6392_LDO_MODE_LP;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		val = MT6392_LDO_MODE_NORMAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val <<= ffs(info->modeset_mask) - 1;
+
+	ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+				 info->modeset_mask, val);
+
+	return ret;
+}
+
+static unsigned int mt6392_ldo_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	unsigned int mode;
+	int ret;
+	struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+	ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
+	if (ret < 0)
+		return ret;
+
+	val &= info->modeset_mask;
+	val >>= ffs(info->modeset_mask) - 1;
+
+	if (val & 0x1)
+		mode = REGULATOR_MODE_STANDBY;
+	else
+		mode = REGULATOR_MODE_NORMAL;
+
+	return mode;
+}
+
+static const struct regulator_ops mt6392_volt_range_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6392_buck_set_mode,
+	.get_mode = mt6392_buck_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_table_ops = {
+	.list_voltage = regulator_list_voltage_table,
+	.map_voltage = regulator_map_voltage_iterate,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6392_ldo_set_mode,
+	.get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_ldo_range_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6392_ldo_set_mode,
+	.get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_fixed_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.set_mode = mt6392_ldo_set_mode,
+	.get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_fixed_no_mode_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+};
+
+/* The array is indexed by id(MT6392_ID_XXX) */
+static struct mt6392_regulator_info mt6392_regulators[] = {
+	MT6392_BUCK("vproc", VPROC, "vproc", 700000, 1493750, 6250,
+		    buck_volt_range1, MT6392_VPROC_CON7, MT6392_VPROC_CON9, 0x7f,
+		    MT6392_VPROC_CON10, MT6392_VPROC_CON5, MT6392_VPROC_CON2, 0x100,
+		    12500),
+	MT6392_BUCK("vsys", VSYS, "vsys", 1400000, 2987500, 12500,
+		    buck_volt_range2, MT6392_VSYS_CON7, MT6392_VSYS_CON9, 0x7f,
+		    MT6392_VSYS_CON10, MT6392_VSYS_CON5, MT6392_VSYS_CON2, 0x100,
+		    25000),
+	MT6392_BUCK("vcore", VCORE, "vcore", 700000, 1493750, 6250,
+		    buck_volt_range1, MT6392_VCORE_CON7, MT6392_VCORE_CON9, 0x7f,
+		    MT6392_VCORE_CON10, MT6392_VCORE_CON5, MT6392_VCORE_CON2, 0x100,
+		    12500),
+	MT6392_REG_FIXED("vxo22", VXO22, "ldo1", MT6392_ANALDO_CON1, 10, 2200000,
+			 MT6392_ANALDO_CON1, 0x2, 110),
+	MT6392_LDO("vaud22", VAUD22, "ldo1", ldo_volt_table1,
+		   MT6392_ANALDO_CON2, 14, MT6392_ANALDO_CON8, 0x60,
+		   MT6392_ANALDO_CON2, 0x2, 264),
+	MT6392_REG_FIXED_NO_MODE("vcama", VCAMA, "ldo1", MT6392_ANALDO_CON4, 15,
+				 2800000, 264),
+	MT6392_REG_FIXED("vaud28", VAUD28, "ldo1", MT6392_ANALDO_CON23, 14, 2800000,
+			 MT6392_ANALDO_CON23, 0x2, 264),
+	MT6392_REG_FIXED("vadc18", VADC18, "ldo1", MT6392_ANALDO_CON25, 14, 1800000,
+			 MT6392_ANALDO_CON25, 0x2, 264),
+	MT6392_LDO_LINEAR("vcn35", VCN35, "ldo2", 3300000, 3600000, 100000,
+			  ldo_volt_range2, MT6392_ANALDO_CON21, 12,
+			  MT6392_ANALDO_CON16, 0xC, MT6392_ANALDO_CON21, 0x2, 264),
+	MT6392_REG_FIXED("vio28", VIO28, "ldo2", MT6392_DIGLDO_CON0, 14, 2800000,
+			 MT6392_DIGLDO_CON0, 0x2, 264),
+	MT6392_REG_FIXED("vusb", VUSB, "ldo3", MT6392_DIGLDO_CON2, 14, 3300000,
+			 MT6392_DIGLDO_CON2, 0x2, 264),
+	MT6392_LDO("vmc", VMC, "ldo2", ldo_volt_table3,
+		   MT6392_DIGLDO_CON3, 12, MT6392_DIGLDO_CON24, 0x10,
+		   MT6392_DIGLDO_CON3, 0x2, 264),
+	MT6392_LDO("vmch", VMCH, "ldo2", ldo_volt_table4,
+		   MT6392_DIGLDO_CON5, 14, MT6392_DIGLDO_CON26, 0x80,
+		   MT6392_DIGLDO_CON5, 0x2, 264),
+	MT6392_LDO("vemc3v3", VEMC3V3, "ldo3", ldo_volt_table4,
+		   MT6392_DIGLDO_CON6, 14, MT6392_DIGLDO_CON27, 0x80,
+		   MT6392_DIGLDO_CON6, 0x2, 264),
+	MT6392_LDO("vgp1", VGP1, "ldo3", ldo_volt_table5,
+		   MT6392_DIGLDO_CON7, 15, MT6392_DIGLDO_CON28, 0xE0,
+		   MT6392_DIGLDO_CON7, 0x2, 264),
+	MT6392_LDO("vgp2", VGP2, "ldo3", ldo_volt_table5,
+		   MT6392_DIGLDO_CON8, 15, MT6392_DIGLDO_CON29, 0xE0,
+		   MT6392_DIGLDO_CON8, 0x2, 264),
+	MT6392_REG_FIXED("vcn18", VCN18, "avddldo", MT6392_DIGLDO_CON11, 14, 1800000,
+			 MT6392_DIGLDO_CON11, 0x2, 264),
+	MT6392_LDO("vcamaf", VCAMAF, "ldo3", ldo_volt_table5,
+		   MT6392_DIGLDO_CON31, 15, MT6392_DIGLDO_CON32, 0xE0,
+		   MT6392_DIGLDO_CON31, 0x2, 264),
+	MT6392_LDO("vm", VM, "avddldo", ldo_volt_table6,
+		   MT6392_DIGLDO_CON47, 14, MT6392_DIGLDO_CON48, 0x30,
+		   MT6392_DIGLDO_CON47, 0x2, 264),
+	MT6392_REG_FIXED("vio18", VIO18, "avddldo", MT6392_DIGLDO_CON49, 14, 1800000,
+			 MT6392_DIGLDO_CON49, 0x2, 264),
+	MT6392_LDO("vcamd", VCAMD, "avddldo", ldo_volt_table7,
+		   MT6392_DIGLDO_CON51, 14, MT6392_DIGLDO_CON52, 0x60,
+		   MT6392_DIGLDO_CON51, 0x2, 264),
+	MT6392_REG_FIXED("vcamio", VCAMIO, "avddldo", MT6392_DIGLDO_CON53, 14, 1800000,
+			 MT6392_DIGLDO_CON53, 0x2, 264),
+	MT6392_REG_FIXED("vm25", VM25, "ldo3", MT6392_DIGLDO_CON55, 14, 2500000,
+			 MT6392_DIGLDO_CON55, 0x2, 264),
+	MT6392_LDO("vefuse", VEFUSE, "ldo2", ldo_volt_table8,
+		   MT6392_DIGLDO_CON57, 14, MT6392_DIGLDO_CON58, 0x10,
+		   MT6392_DIGLDO_CON57, 0x2, 264),
+	MT6392_REG_FIXED_NO_MODE("vdig18", VDIG18, "ldo2", MT6392_DIGLDO_CON12, 15,
+				 1800000, 264),
+	MT6392_REG_FIXED_NO_MODE("vrtc", VRTC, "ldo1", MT6392_DIGLDO_CON15, 15,
+				 2800000, 264)
+};
+
+static int mt6392_set_buck_vosel_reg(struct platform_device *pdev)
+{
+	struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+	int i;
+	u32 regval;
+
+	for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+		if (mt6392_regulators[i].vselctrl_reg) {
+			if (regmap_read(mt6392->regmap,
+					mt6392_regulators[i].vselctrl_reg,
+					&regval) < 0) {
+				dev_err(&pdev->dev,
+					"Failed to read buck ctrl\n");
+				return -EIO;
+			}
+
+			if (regval & mt6392_regulators[i].vselctrl_mask) {
+				mt6392_regulators[i].desc.vsel_reg =
+				mt6392_regulators[i].vselon_reg;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int mt6392_regulator_probe(struct platform_device *pdev)
+{
+	struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_config config = {};
+	struct regulator_dev *rdev;
+	int i;
+
+	pdev->dev.of_node = pdev->dev.parent->of_node;
+
+	/* Query buck controller to select activated voltage register part */
+	if (mt6392_set_buck_vosel_reg(pdev))
+		return -EIO;
+
+	config.dev = mt6392->dev;
+	config.regmap = mt6392->regmap;
+	for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+		config.driver_data = &mt6392_regulators[i];
+
+		rdev = devm_regulator_register(&pdev->dev,
+					       &mt6392_regulators[i].desc,
+					       &config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "failed to register %s\n",
+				mt6392_regulators[i].desc.name);
+			return PTR_ERR(rdev);
+		}
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id mt6392_platform_ids[] = {
+	{"mt6392-regulator", 0},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6392_platform_ids);
+
+static struct platform_driver mt6392_regulator_driver = {
+	.driver = {
+		.name = "mt6392-regulator",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.probe = mt6392_regulator_probe,
+	.id_table = mt6392_platform_ids,
+};
+
+module_platform_driver(mt6392_regulator_driver);
+
+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6392 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regulator/mt6392-regulator.h b/include/linux/regulator/mt6392-regulator.h
new file mode 100644
index 000000000000..0eccd085b062
--- /dev/null
+++ b/include/linux/regulator/mt6392-regulator.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __LINUX_REGULATOR_MT6392_H
+#define __LINUX_REGULATOR_MT6392_H
+
+enum {
+	MT6392_ID_VPROC = 0,
+	MT6392_ID_VSYS,
+	MT6392_ID_VCORE,
+	MT6392_ID_VXO22,
+	MT6392_ID_VAUD22,
+	MT6392_ID_VCAMA,
+	MT6392_ID_VAUD28,
+	MT6392_ID_VADC18,
+	MT6392_ID_VCN35,
+	MT6392_ID_VIO28,
+	MT6392_ID_VUSB = 10,
+	MT6392_ID_VMC,
+	MT6392_ID_VMCH,
+	MT6392_ID_VEMC3V3,
+	MT6392_ID_VGP1,
+	MT6392_ID_VGP2,
+	MT6392_ID_VCN18,
+	MT6392_ID_VCAMAF,
+	MT6392_ID_VM,
+	MT6392_ID_VIO18,
+	MT6392_ID_VCAMD,
+	MT6392_ID_VCAMIO,
+	MT6392_ID_VM25,
+	MT6392_ID_VEFUSE,
+	MT6392_ID_VDIG18,
+	MT6392_ID_VRTC,
+	MT6392_ID_RG_MAX,
+};
+
+#define MT6392_MAX_REGULATOR	MT6392_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6392_H */
-- 
2.43.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox