Linux Power Management development
 help / color / mirror / Atom feed
* Re: [PATCH v3 1/2] dt-bindings: power: supply: gpio-charger: add support for fast-charge timer
From: Krzysztof Kozlowski @ 2026-03-24  8:55 UTC (permalink / raw)
  To: Dimitri Fedrau
  Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-pm, devicetree, linux-kernel, Dimitri Fedrau
In-Reply-To: <20260323-gpio-charger-timer-v3-1-885796d681a5@liebherr.com>

On Mon, Mar 23, 2026 at 05:04:06PM +0100, Dimitri Fedrau wrote:
>    charger-type:
>      enum:
> @@ -62,6 +67,10 @@ properties:
>      description: Default charge current limit. Must be listed in
>        charge-current-limit-mapping.
>  
> +  fast-charge-timer-gpios:
> +    maxItems: 1
> +    description: GPIO used for enabling/disabling the fast-charge timer
> +

So where is the solution for "and then only allow
'fast-charge-timer-gpios' for the BQ24081."?

See example-schema or other bindings for the "if:not:...then:...
fast-charge-timer-gpios: false"


Best regards,
Krzysztof


^ permalink raw reply

* [PATCH 5.15.y 2/2] cpufreq: Avoid a bad reference count on CPU node
From: Bin Lan @ 2026-03-24  8:21 UTC (permalink / raw)
  To: gregkh, stable
  Cc: linux-pm, Miquel Sabaté Solà, Viresh Kumar,
	Rafael J . Wysocki, Bin Lan
In-Reply-To: <20260324082113.6275-1-lanbincn@139.com>

From: Miquel Sabaté Solà <mikisabate@gmail.com>

[ Upstream commit c0f02536fffbbec71aced36d52a765f8c4493dc2 ]

In the parse_perf_domain function, if the call to
of_parse_phandle_with_args returns an error, then the reference to the
CPU device node that was acquired at the start of the function would not
be properly decremented.

Address this by declaring the variable with the __free(device_node)
cleanup attribute.

Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://patch.msgid.link/20240917134246.584026-1-mikisabate@gmail.com
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ Minor context conflict resolved. ]
Signed-off-by: Bin Lan <lanbincn@139.com>
---
 include/linux/cpufreq.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 8e3a1d4e0a3a..6ed4c82af367 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -1014,11 +1014,10 @@ static inline int cpufreq_table_count_valid_entries(const struct cpufreq_policy
 static inline int parse_perf_domain(int cpu, const char *list_name,
 				    const char *cell_name)
 {
-	struct device_node *cpu_np;
 	struct of_phandle_args args;
 	int ret;
 
-	cpu_np = of_cpu_device_node_get(cpu);
+	struct device_node *cpu_np __free(device_node) = of_cpu_device_node_get(cpu);
 	if (!cpu_np)
 		return -ENODEV;
 
@@ -1027,8 +1026,6 @@ static inline int parse_perf_domain(int cpu, const char *list_name,
 	if (ret < 0)
 		return ret;
 
-	of_node_put(cpu_np);
-
 	return args.args[0];
 }
 
-- 
2.43.0



^ permalink raw reply related

* [PATCH 5.15.y 1/2] of: Add cleanup.h based auto release via __free(device_node) markings
From: Bin Lan @ 2026-03-24  8:21 UTC (permalink / raw)
  To: gregkh, stable; +Cc: linux-pm, Jonathan Cameron, Rob Herring, Bin Lan

From: Jonathan Cameron <Jonathan.Cameron@huawei.com>

[ Upstream commit 9448e55d032d99af8e23487f51a542d51b2f1a48 ]

The recent addition of scope based cleanup support to the kernel
provides a convenient tool to reduce the chances of leaking reference
counts where of_node_put() should have been called in an error path.

This enables
	struct device_node *child __free(device_node) = NULL;

	for_each_child_of_node(np, child) {
		if (test)
			return test;
	}

with no need for a manual call of of_node_put().
A following patch will reduce the scope of the child variable to the
for loop, to avoid an issues with ordering of autocleanup, and make it
obvious when this assigned a non NULL value.

In this simple example the gains are small but there are some very
complex error handling cases buried in these loops that will be
greatly simplified by enabling early returns with out the need
for this manual of_node_put() call.

Note that there are coccinelle checks in
scripts/coccinelle/iterators/for_each_child.cocci to detect a failure
to call of_node_put(). This new approach does not cause false positives.
Longer term we may want to add scripting to check this new approach is
done correctly with no double of_node_put() calls being introduced due
to the auto cleanup. It may also be useful to script finding places
this new approach is useful.

Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20240225142714.286440-2-jic23@kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Bin Lan <lanbincn@139.com>
---
 include/linux/of.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 29f657101f4f..3c840c487995 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -13,6 +13,7 @@
  */
 #include <linux/types.h>
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/errno.h>
 #include <linux/kobject.h>
 #include <linux/mod_devicetable.h>
@@ -128,6 +129,7 @@ static inline struct device_node *of_node_get(struct device_node *node)
 }
 static inline void of_node_put(struct device_node *node) { }
 #endif /* !CONFIG_OF_DYNAMIC */
+DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
 
 /* Pointer for first entry in chain of all nodes. */
 extern struct device_node *of_root;
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH v8 2/2] mm/swap: remove redundant swap device reference in alloc/free
From: Kairui Song @ 2026-03-24  6:49 UTC (permalink / raw)
  To: Youngjun Park
  Cc: Rafael J . Wysocki, Andrew Morton, Chris Li, Kairui Song,
	Pavel Machek, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
	Usama Arif, linux-pm, linux-mm
In-Reply-To: <20260323160822.1409904-3-youngjun.park@lge.com>

On Tue, Mar 24, 2026 at 01:08:22AM +0800, Youngjun Park wrote:
> In the previous commit, uswsusp was modified to pin the swap device
> when the swap type is determined, ensuring the device remains valid
> throughout the hibernation I/O path.
> 
> Therefore, it is no longer necessary to repeatedly get and put the swap
> device reference for each swap slot allocation and free operation.
> 
> For hibernation via the sysfs interface, user-space tasks are frozen
> before swap allocation begins, so swapoff cannot race with allocation.
> After resume, tasks remain frozen while swap slots are freed, so
> additional reference management is not required there either.
> 
> Remove the redundant swap device get/put operations from the
> hibernation swap allocation and free paths.
> 
> Also remove the SWP_WRITEOK check before allocation, as the cluster
> allocation logic already validates the swap device state.
> 
> Update function comments to document the caller's responsibility for
> ensuring swap device stability.
> 
> Signed-off-by: Youngjun Park <youngjun.park@lge.com>
> ---
>  mm/swapfile.c | 68 +++++++++++++++++++++++++++------------------------
>  1 file changed, 36 insertions(+), 32 deletions(-)

Thanks!

Reviewed-by: Kairui Song <kasong@tencent.com>

^ permalink raw reply

* [rafael-pm:fixes] BUILD SUCCESS 786153f3385f8a88f0360ade89a2a07991807c48
From: kernel test robot @ 2026-03-24  6:13 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-acpi, linux-pm

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git fixes
branch HEAD: 786153f3385f8a88f0360ade89a2a07991807c48  Merge branches 'pm-cpufreq-fixes' and 'pm-sleep-fixes' into fixes

elapsed time: 728m

configs tested: 176
configs skipped: 1

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260324    gcc-8.5.0
arc                   randconfig-002-20260324    gcc-8.5.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                                 defconfig    gcc-15.2.0
arm                           h3600_defconfig    gcc-15.2.0
arm                   randconfig-001-20260324    gcc-8.5.0
arm                   randconfig-002-20260324    gcc-8.5.0
arm                   randconfig-003-20260324    gcc-8.5.0
arm                   randconfig-004-20260324    gcc-8.5.0
arm64                            allmodconfig    clang-19
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                 randconfig-001-20260324    gcc-13.4.0
arm64                 randconfig-002-20260324    gcc-13.4.0
arm64                 randconfig-003-20260324    gcc-13.4.0
arm64                 randconfig-004-20260324    gcc-13.4.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                  randconfig-001-20260324    gcc-13.4.0
csky                  randconfig-002-20260324    gcc-13.4.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
i386                             allmodconfig    clang-20
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386                             allyesconfig    gcc-14
i386        buildonly-randconfig-001-20260324    gcc-12
i386        buildonly-randconfig-002-20260324    gcc-12
i386        buildonly-randconfig-003-20260324    gcc-12
i386        buildonly-randconfig-004-20260324    gcc-12
i386        buildonly-randconfig-005-20260324    gcc-12
i386        buildonly-randconfig-006-20260324    gcc-12
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260324    clang-20
i386                  randconfig-002-20260324    clang-20
i386                  randconfig-003-20260324    clang-20
i386                  randconfig-004-20260324    clang-20
i386                  randconfig-005-20260324    clang-20
i386                  randconfig-006-20260324    clang-20
i386                  randconfig-007-20260324    clang-20
loongarch                        allmodconfig    clang-19
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                                defconfig    clang-19
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                           mtx1_defconfig    clang-23
mips                          rb532_defconfig    clang-18
nios2                            allmodconfig    clang-23
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
openrisc                         allmodconfig    clang-23
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                randconfig-001-20260324    gcc-12.5.0
parisc                randconfig-001-20260324    gcc-8.5.0
parisc                randconfig-002-20260324    gcc-10.5.0
parisc                randconfig-002-20260324    gcc-8.5.0
parisc64                            defconfig    clang-19
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc               randconfig-001-20260324    gcc-8.5.0
powerpc               randconfig-002-20260324    gcc-8.5.0
powerpc64             randconfig-001-20260324    gcc-14.3.0
powerpc64             randconfig-001-20260324    gcc-8.5.0
powerpc64             randconfig-002-20260324    gcc-8.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                 randconfig-001-20260324    clang-23
riscv                 randconfig-002-20260324    clang-23
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                  randconfig-001-20260324    gcc-12.5.0
s390                  randconfig-002-20260324    clang-23
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                    randconfig-001-20260324    gcc-15.2.0
sh                    randconfig-002-20260324    gcc-15.2.0
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                 randconfig-001-20260324    gcc-14
sparc                 randconfig-002-20260324    gcc-14
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260324    gcc-14
sparc64               randconfig-002-20260324    gcc-14
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260324    gcc-14
um                    randconfig-002-20260324    gcc-14
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260324    gcc-14
x86_64      buildonly-randconfig-002-20260324    gcc-14
x86_64      buildonly-randconfig-003-20260324    gcc-14
x86_64      buildonly-randconfig-004-20260324    gcc-14
x86_64      buildonly-randconfig-005-20260324    gcc-14
x86_64      buildonly-randconfig-006-20260324    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260324    clang-20
x86_64                randconfig-002-20260324    clang-20
x86_64                randconfig-003-20260324    clang-20
x86_64                randconfig-004-20260324    clang-20
x86_64                randconfig-005-20260324    clang-20
x86_64                randconfig-006-20260324    clang-20
x86_64                randconfig-011-20260324    gcc-14
x86_64                randconfig-012-20260324    gcc-14
x86_64                randconfig-013-20260324    gcc-14
x86_64                randconfig-014-20260324    gcc-14
x86_64                randconfig-015-20260324    gcc-14
x86_64                randconfig-016-20260324    gcc-14
x86_64                randconfig-071-20260324    gcc-12
x86_64                randconfig-072-20260324    gcc-12
x86_64                randconfig-073-20260324    gcc-12
x86_64                randconfig-074-20260324    gcc-12
x86_64                randconfig-075-20260324    gcc-12
x86_64                randconfig-076-20260324    gcc-12
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                           allyesconfig    clang-23
xtensa                randconfig-001-20260324    gcc-14
xtensa                randconfig-002-20260324    gcc-14

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v8 1/2] mm/swap, PM: hibernate: fix swapoff race in uswsusp by pinning swap device
From: Kairui Song @ 2026-03-24  5:53 UTC (permalink / raw)
  To: Youngjun Park
  Cc: Rafael J . Wysocki, Andrew Morton, Chris Li, Kairui Song,
	Pavel Machek, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
	Usama Arif, linux-pm, linux-mm
In-Reply-To: <20260323160822.1409904-2-youngjun.park@lge.com>

On Tue, Mar 24, 2026 at 01:08:21AM +0800, Youngjun Park wrote:
> Hibernation via uswsusp (/dev/snapshot ioctls) has a race window:
> after selecting the resume swap area but before user space is frozen,
> swapoff may run and invalidate the selected swap device.
> 
> Fix this by pinning the swap device with SWP_HIBERNATION while it is
> in use.  The pin is exclusive, which is sufficient since
> hibernate_acquire() already prevents concurrent hibernation sessions.
> 
> The kernel swsusp path (sysfs-based hibernate/resume) uses
> find_hibernation_swap_type() which is not affected by the pin.  It
> freezes user space before touching swap, so swapoff cannot race.
> 
> Introduce dedicated helpers:
> - pin_hibernation_swap_type(): Look up and pin the swap device.
>   Used by the uswsusp path.
> - find_hibernation_swap_type(): Lookup without pinning.
>   Used by the kernel swsusp path.
> - unpin_hibernation_swap_type(): Clear the hibernation pin.

Looks good to me, thanks!

Reviewed-by: Kairui Song <kasong@tencent.com>

Just one trivial nit picks below.

> +/**
> + * unpin_hibernation_swap_type - Unpin the swap device for hibernation
> + * @type: Swap type previously returned by pin_hibernation_swap_type()
> + *
> + * Clear the hibernation pin on the given swap device, allowing
> + * swapoff() to proceed normally.
> + *
> + * If @type does not refer to a valid swap device, this function
> + * does nothing.
> + */
> +void unpin_hibernation_swap_type(int type)
> +{
> +	struct swap_info_struct *si;
> +
> +	spin_lock(&swap_lock);
> +	si = swap_type_to_info(type);
> +	if (!si) {
> +		spin_unlock(&swap_lock);
> +		return;
> +	}
> +	si->flags &= ~SWP_HIBERNATION;

Will the code will be simpler if you just:

if (si)
	si->flags &= ~SWP_HIBERNATION;

Just personal taste, free feel to ignore.

And as you mentioned this is on top of swap table p3 so you based
it on mm-new - but isn't p3 already in mm-unstable? Maybe we can
have it there? Not sure how much conflict are there with PM.

The code and design looks OK.

^ permalink raw reply

* Re: [PATCH v8 3/9] dax/hmem: Request cxl_acpi and cxl_pci before walking Soft Reserved ranges
From: Koralahalli Channabasappa, Smita @ 2026-03-24  5:46 UTC (permalink / raw)
  To: Dan Williams, Smita Koralahalli, linux-cxl, linux-kernel, nvdimm,
	linux-fsdevel, linux-pm
  Cc: Ard Biesheuvel, Alison Schofield, Vishal Verma, Ira Weiny,
	Jonathan Cameron, Yazen Ghannam, Dave Jiang, Davidlohr Bueso,
	Matthew Wilcox, Jan Kara, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Li Ming, Jeff Johnson, Ying Huang, Yao Xingtao,
	Peter Zijlstra, Greg Kroah-Hartman, Nathan Fontenot, Terry Bowman,
	Robert Richter, Benjamin Cheatham, Zhijian Li, Borislav Petkov,
	Tomasz Wolski
In-Reply-To: <69c19a8c66fd3_7ee3100e3@dwillia2-mobl4.notmuch>

Hi Dan,

On 3/23/2026 12:54 PM, Dan Williams wrote:
> Smita Koralahalli wrote:
>> From: Dan Williams <dan.j.williams@intel.com>
>>
>> Ensure cxl_acpi has published CXL Window resources before HMEM walks Soft
>> Reserved ranges.
>>
>> Replace MODULE_SOFTDEP("pre: cxl_acpi") with an explicit, synchronous
>> request_module("cxl_acpi"). MODULE_SOFTDEP() only guarantees eventual
>> loading, it does not enforce that the dependency has finished init
>> before the current module runs. This can cause HMEM to start before
>> cxl_acpi has populated the resource tree, breaking detection of overlaps
>> between Soft Reserved and CXL Windows.
>>
>> Also, request cxl_pci before HMEM walks Soft Reserved ranges. Unlike
>> cxl_acpi, cxl_pci attach is asynchronous and creates dependent devices
>> that trigger further module loads. Asynchronous probe flushing
>> (wait_for_device_probe()) is added later in the series in a deferred
>> context before HMEM makes ownership decisions for Soft Reserved ranges.
>>
>> Add an additional explicit Kconfig ordering so that CXL_ACPI and CXL_PCI
>> must be initialized before DEV_DAX_HMEM. This prevents HMEM from consuming
>> Soft Reserved ranges before CXL drivers have had a chance to claim them.
>>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>> Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
>> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
>> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
>> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
>> ---
>>   drivers/dax/Kconfig     |  2 ++
>>   drivers/dax/hmem/hmem.c | 17 ++++++++++-------
>>   2 files changed, 12 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig
>> index d656e4c0eb84..3683bb3f2311 100644
>> --- a/drivers/dax/Kconfig
>> +++ b/drivers/dax/Kconfig
>> @@ -48,6 +48,8 @@ config DEV_DAX_CXL
>>   	tristate "CXL DAX: direct access to CXL RAM regions"
>>   	depends on CXL_BUS && CXL_REGION && DEV_DAX
>>   	default CXL_REGION && DEV_DAX
>> +	depends on CXL_ACPI >= DEV_DAX_HMEM
>> +	depends on CXL_PCI >= DEV_DAX_HMEM
> 
> As I learned from Keith's recent CXL_PMEM dependency fix for CXL_ACPI
> [1], this wants to be:
> 
> depends on DEV_DAX_HMEM || !DEV_DAX_HMEM
> depends on CXL_ACPI || !CXL_ACPI
> depends on CXL_PCI || !CXL_PCI
> 
> ...to make sure that DEV_DAX_CXL can never be built-in unless all of its
> dependencies are built-in.
> 
> [1]: http://lore.kernel.org/69aa341fcf526_6423c1002c@dwillia2-mobl4.notmuch
> 
> At this point I am wondering if all of the feedback I have for this
> series should just be incremental fixes. I also want to have a canned
> unit test that verifies the base expectations. That can also be
> something I reply incrementally.

Two things on the Kconfig change:

When DEV_DAX_HMEM = y and CXL_ACPI = m and CXL_PCI = m

1. Regarding switching from >= to || ! pattern:

The >= pattern disabled DEV_DAX_CXL entirely when DEV_DAX_HMEM = y and 
CXL_ACPI/CXL_PCI = m. So, HMEM unconditionally owned all ranges - the 
CXL deferral path is never entered.

With the || ! pattern, DEV_DAX_CXL is enabled, which changes the 
ownership behavior based on how the probes starts for CXL_ACPI/CXL_PCI.

On my system I see:

   [  7.379] dax_hmem_platform_probe began
   [  7.384] alloc_dev_dax_range: dax0.0
   [ 28.560] cxl acpi probe started     <- 21 seconds later

HMEM ends up owning in this case because CXL windows aren't published 
yet when HMEM probes (built-in runs before modules load and 
request_module might not work this early??), so region_intersects() 
returns DISJOINT for all CXL ranges.

But it could go the other way if CXL ACPI and PCI probe starts before 
the deferred work is queued in HMEM. (And I think this is the expected 
path if DEV_DAX_CXL is enabled..)

But do you think it is okay as of now with resource exclusion handling??

2. Separate build issue with DEV_DAX_HMEM = y,  CXL_BUS/ACPI/PCI = m and
CXL_REGION = y.

I hit this build error when I was testing the above config: (Sorry I 
should have checked this config before)..

When DEV_DAX_HMEM = y and CXL core is built as a module hmem.c calls 
cxl_region_contains_resource() which lives in cxl_core.ko causing an 
undefined reference at link time.

This happens with both the >= and || ! Kconfig patterns.

The current #ifdef CONFIG_CXL_REGION guard evaluates to true even when 
CXL_REGION is compiled into a module. Changing the guard to check 
reachability of the actual module in include/cxl/cxl.h worked for me to 
overcome the error:

-#ifdef CONFIG_CXL_REGION
+#if IS_REACHABLE(CONFIG_CXL_BUS) && defined(CONFIG_CXL_REGION)
bool cxl_region_contains_resource(struct resource *res);
#else
...

Not sure if CONFIG_CXL_BUS is the right check here or it should be more 
specifically checking on CXL_ACPI or PCI..

Thanks
Smita



^ permalink raw reply

* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
From: Mario Limonciello @ 2026-03-24  4:34 UTC (permalink / raw)
  To: Gautham R. Shenoy
  Cc: Rafael J . Wysocki, Viresh Kumar, K Prateek Nayak, linux-kernel,
	linux-pm
In-Reply-To: <acITFNYfjSMc/K1I@BLRRASHENOY1.amd.com>



On 3/23/26 11:29 PM, Gautham R. Shenoy wrote:
> Hello Mario,
> 
> On Mon, Mar 23, 2026 at 03:21:17PM -0500, Mario Limonciello (AMD) (kernel.org) wrote:
>>
>>
>> On 3/20/2026 9:43 AM, Gautham R. Shenoy wrote:
>>> Currently when amd-pstate-ut test module is loaded, it runs all the
>>> tests from amd_pstate_ut_cases[] array.
>>>
>>> Add a module parameter named "run_only" that allows users to run a
>>> single test from the array by specifying the test name string.
>>>
>>> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
>>> ---
>>>    drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
>>>    1 file changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
>>> index 447b9aa5ce40..35e453a49c0f 100644
>>> --- a/drivers/cpufreq/amd-pstate-ut.c
>>> +++ b/drivers/cpufreq/amd-pstate-ut.c
>>> @@ -35,6 +35,10 @@
>>>    #include "amd-pstate.h"
>>> +static char *run_only;
>>> +module_param(run_only, charp, 0444);
>>> +MODULE_PARM_DESC(run_only,
>>> +	"Run only the named test case (default: run all)");
>>
>> This default shows the end effect; but it doesn't make sense for this
>> parameter IMO.
>>
>> How about instead if you had a semicolon delimitted list and then defaulted
>> an empty list to mean all tests?  Something like this:
>>
>> static char *test_list;
>> module_param(test_list, charp, 0444)
>> MODULE_PARM_DESC(test_list,
>> 	"Semicolon delimitted list of tests to run (empty means run all tests)");
> 
> 
> This makes sense.
> 
>>
>>>    struct amd_pstate_ut_struct {
>>>    	const char *name;
>>> @@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
>>>    	u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
>>>    	for (i = 0; i < arr_size; i++) {
>>> -		int ret = amd_pstate_ut_cases[i].func(i);
>>> +		int ret;
>>> +
>>> +		if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
>>> +			continue;
>>> +
>>> +		ret = amd_pstate_ut_cases[i].func(i);
>>
>> If you take my suggestion then you would split this on semicolon or end of
>> string and then allow matching multiple.
> 
> How about something like the following (diff on top of this
> patch. Will fold it in and post a v4 if this looks ok)
Yeah that's good.

> 
> x8----------------------------------------x8---------------------------------------------x8
> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> index 5d87fb8a26df..5ef22a77a9c5 100644
> --- a/drivers/cpufreq/amd-pstate-ut.c
> +++ b/drivers/cpufreq/amd-pstate-ut.c
> @@ -37,10 +37,10 @@
>   
>   #include "amd-pstate.h"
>   
> -static char *run_only;
> -module_param(run_only, charp, 0444);
> -MODULE_PARM_DESC(run_only,
> -       "Run only the named test case (default: run all)");
> +static char *test_list;
> +module_param(test_list, charp, 0444);
> +MODULE_PARM_DESC(test_list,
> +       "Semicolon-delimited list of tests to run (empty means run all tests)");
>   
>   struct amd_pstate_ut_struct {
>          const char *name;
> @@ -403,6 +403,26 @@ static int amd_pstate_ut_check_freq_attrs(u32 index)
>          return ret;
>   }
>   
> +static bool test_in_list(const char *list, const char *name)
> +{
> +       size_t name_len = strlen(name);
> +       const char *p = list;
> +
> +       while (*p) {
> +               const char *sep = strchr(p, ';');
> +               size_t token_len = sep ? sep - p : strlen(p);
> +
> +               if (token_len == name_len && !strncmp(p, name, token_len))
> +                       return true;
> +
> +               if (!sep)
> +                       break;
> +               p = sep + 1;
> +       }
> +
> +       return false;
> +}
> +
>   static int __init amd_pstate_ut_init(void)
>   {
>          u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
> @@ -410,7 +430,8 @@ static int __init amd_pstate_ut_init(void)
>          for (i = 0; i < arr_size; i++) {
>                  int ret;
>   
> -               if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
> +               if (test_list && *test_list &&
> +                   !test_in_list(test_list, amd_pstate_ut_cases[i].name))
>                          continue;
>   
>                  ret = amd_pstate_ut_cases[i].func(i);
> x8----------------------------------------x8---------------------------------------------x8
> 


^ permalink raw reply

* Re: [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase
From: Gautham R. Shenoy @ 2026-03-24  4:29 UTC (permalink / raw)
  To: Mario Limonciello (AMD) (kernel.org)
  Cc: Rafael J . Wysocki, Viresh Kumar, K Prateek Nayak, linux-kernel,
	linux-pm
In-Reply-To: <0b1f1901-8ea0-4b68-8887-29e88e86ab60@kernel.org>

Hello Mario,

On Mon, Mar 23, 2026 at 03:21:17PM -0500, Mario Limonciello (AMD) (kernel.org) wrote:
> 
> 
> On 3/20/2026 9:43 AM, Gautham R. Shenoy wrote:
> > Currently when amd-pstate-ut test module is loaded, it runs all the
> > tests from amd_pstate_ut_cases[] array.
> > 
> > Add a module parameter named "run_only" that allows users to run a
> > single test from the array by specifying the test name string.
> > 
> > Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> > ---
> >   drivers/cpufreq/amd-pstate-ut.c | 11 ++++++++++-
> >   1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> > index 447b9aa5ce40..35e453a49c0f 100644
> > --- a/drivers/cpufreq/amd-pstate-ut.c
> > +++ b/drivers/cpufreq/amd-pstate-ut.c
> > @@ -35,6 +35,10 @@
> >   #include "amd-pstate.h"
> > +static char *run_only;
> > +module_param(run_only, charp, 0444);
> > +MODULE_PARM_DESC(run_only,
> > +	"Run only the named test case (default: run all)");
> 
> This default shows the end effect; but it doesn't make sense for this
> parameter IMO.
> 
> How about instead if you had a semicolon delimitted list and then defaulted
> an empty list to mean all tests?  Something like this:
> 
> static char *test_list;
> module_param(test_list, charp, 0444)
> MODULE_PARM_DESC(test_list,
> 	"Semicolon delimitted list of tests to run (empty means run all tests)");


This makes sense.

> 
> >   struct amd_pstate_ut_struct {
> >   	const char *name;
> > @@ -275,7 +279,12 @@ static int __init amd_pstate_ut_init(void)
> >   	u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
> >   	for (i = 0; i < arr_size; i++) {
> > -		int ret = amd_pstate_ut_cases[i].func(i);
> > +		int ret;
> > +
> > +		if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
> > +			continue;
> > +
> > +		ret = amd_pstate_ut_cases[i].func(i);
> 
> If you take my suggestion then you would split this on semicolon or end of
> string and then allow matching multiple.

How about something like the following (diff on top of this
patch. Will fold it in and post a v4 if this looks ok)

x8----------------------------------------x8---------------------------------------------x8
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 5d87fb8a26df..5ef22a77a9c5 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -37,10 +37,10 @@
 
 #include "amd-pstate.h"
 
-static char *run_only;
-module_param(run_only, charp, 0444);
-MODULE_PARM_DESC(run_only,
-       "Run only the named test case (default: run all)");
+static char *test_list;
+module_param(test_list, charp, 0444);
+MODULE_PARM_DESC(test_list,
+       "Semicolon-delimited list of tests to run (empty means run all tests)");
 
 struct amd_pstate_ut_struct {
        const char *name;
@@ -403,6 +403,26 @@ static int amd_pstate_ut_check_freq_attrs(u32 index)
        return ret;
 }
 
+static bool test_in_list(const char *list, const char *name)
+{
+       size_t name_len = strlen(name);
+       const char *p = list;
+
+       while (*p) {
+               const char *sep = strchr(p, ';');
+               size_t token_len = sep ? sep - p : strlen(p);
+
+               if (token_len == name_len && !strncmp(p, name, token_len))
+                       return true;
+
+               if (!sep)
+                       break;
+               p = sep + 1;
+       }
+
+       return false;
+}
+
 static int __init amd_pstate_ut_init(void)
 {
        u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases);
@@ -410,7 +430,8 @@ static int __init amd_pstate_ut_init(void)
        for (i = 0; i < arr_size; i++) {
                int ret;
 
-               if (run_only && strcmp(run_only, amd_pstate_ut_cases[i].name))
+               if (test_list && *test_list &&
+                   !test_in_list(test_list, amd_pstate_ut_cases[i].name))
                        continue;
 
                ret = amd_pstate_ut_cases[i].func(i);
x8----------------------------------------x8---------------------------------------------x8

-- 
Thanks and Regards
gautham.

^ permalink raw reply related

* Re: [PATCH 0/2] dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
From: Viresh Kumar @ 2026-03-24  4:07 UTC (permalink / raw)
  To: Gopi Krishna Menon
  Cc: rafael, daniel.lezcano, rui.zhang, lukasz.luba, robh, krzk+dt,
	vireshk, conor+dt, linux-pm, devicetree, linux-kernel,
	linux-arm-kernel, soc, daniel.baluta, simona.toaca, d-gole,
	m-chawdhry
In-Reply-To: <20260323133814.14152-1-krishnagopi487@gmail.com>

On 23-03-26, 19:08, Gopi Krishna Menon wrote:
> This patch series converts SPEAr Thermal Sensor bindings to DT schema
> and renames thermal_flags property in spear13xx.dtsi to
> st,thermal-flags to fix the unevaluated property warning in
> st/spear1340-evb.dts.
> 
> Note:
> * This patch is part of the GSoC2026 application process for device tree bindings conversions
> * https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
> 
> 
> Gopi Krishna Menon (2):
>   dt-bindings: thermal: st,thermal-spear1340: convert to dtschema
>   ARM: dts: st: spear: fix dtbs warning on spear thermal sensor
> 
>  .../bindings/thermal/spear-thermal.txt        | 14 --------
>  .../thermal/st,thermal-spear1340.yaml         | 36 +++++++++++++++++++
>  arch/arm/boot/dts/st/spear13xx.dtsi           |  2 +-
>  3 files changed, 37 insertions(+), 15 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/thermal/spear-thermal.txt
>  create mode 100644 Documentation/devicetree/bindings/thermal/st,thermal-spear1340.yaml

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* Re: [PATCH v2] cpufreq/amd-pstate: Cache the max frequency in cpudata
From: Zhongqiu Han @ 2026-03-24  3:54 UTC (permalink / raw)
  To: Mario Limonciello (AMD), Gautham R . Shenoy
  Cc: Perry Yuan, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	open list:CPU FREQUENCY SCALING FRAMEWORK, zhongqiu.han
In-Reply-To: <20260323043253.722730-1-superm1@kernel.org>

On 3/23/2026 12:32 PM, Mario Limonciello (AMD) wrote:
> The value of maximum frequency is fixed and never changes. Doing
> calculations every time based off of perf is unnecessary.
> 
> Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
> ---
> v2:
>   * Remove unused variable
> ---
>   drivers/cpufreq/amd-pstate.c | 27 +++++++++------------------
>   drivers/cpufreq/amd-pstate.h |  1 +
>   2 files changed, 10 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 5aa9fcd80cf51..9f80f8b23a43f 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -757,15 +757,13 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
>   static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on)
>   {
>   	struct amd_cpudata *cpudata = policy->driver_data;
> -	union perf_cached perf = READ_ONCE(cpudata->perf);
> -	u32 nominal_freq, max_freq;
> +	u32 nominal_freq;
>   	int ret = 0;
>   
>   	nominal_freq = READ_ONCE(cpudata->nominal_freq);
> -	max_freq = perf_to_freq(perf, cpudata->nominal_freq, perf.highest_perf);
>   
>   	if (on)
> -		policy->cpuinfo.max_freq = max_freq;
> +		policy->cpuinfo.max_freq = cpudata->max_freq;
>   	else if (policy->cpuinfo.max_freq > nominal_freq)
>   		policy->cpuinfo.max_freq = nominal_freq;
>   
> @@ -952,13 +950,15 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
>   
>   	WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
>   
> +	/* max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf */
>   	max_freq = perf_to_freq(perf, nominal_freq, perf.highest_perf);
> +	WRITE_ONCE(cpudata->max_freq, max_freq);
> +
>   	lowest_nonlinear_freq = perf_to_freq(perf, nominal_freq, perf.lowest_nonlinear_perf);
>   	WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);
>   
>   	/**
>   	 * Below values need to be initialized correctly, otherwise driver will fail to load
> -	 * max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf
>   	 * lowest_nonlinear_freq is a value between [min_freq, nominal_freq]
>   	 * Check _CPC in ACPI table objects if any values are incorrect
>   	 */
> @@ -1021,9 +1021,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
>   	policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
>   							      cpudata->nominal_freq,
>   							      perf.lowest_perf);
> -	policy->cpuinfo.max_freq = policy->max = perf_to_freq(perf,
> -							      cpudata->nominal_freq,
> -							      perf.highest_perf);
> +	policy->cpuinfo.max_freq = policy->max = cpudata->max_freq;
>   
>   	ret = amd_pstate_cppc_enable(policy);
>   	if (ret)
> @@ -1090,14 +1088,9 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
>   static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
>   					char *buf)
>   {
> -	struct amd_cpudata *cpudata;
> -	union perf_cached perf;
> -
> -	cpudata = policy->driver_data;
> -	perf = READ_ONCE(cpudata->perf);
> +	struct amd_cpudata *cpudata = policy->driver_data;
>   
> -	return sysfs_emit(buf, "%u\n",
> -			  perf_to_freq(perf, cpudata->nominal_freq, perf.highest_perf));
> +	return sysfs_emit(buf, "%u\n", cpudata->max_freq);
>   }
>   
>   static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy,
> @@ -1503,9 +1496,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
>   	policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
>   							      cpudata->nominal_freq,
>   							      perf.lowest_perf);
> -	policy->cpuinfo.max_freq = policy->max = perf_to_freq(perf,
> -							      cpudata->nominal_freq,
> -							      perf.highest_perf);
> +	policy->cpuinfo.max_freq = policy->max = cpudata->max_freq;
>   	policy->driver_data = cpudata;
>   
>   	ret = amd_pstate_cppc_enable(policy);
> diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
> index cb45fdca27a6c..485ee023d79c5 100644
> --- a/drivers/cpufreq/amd-pstate.h
> +++ b/drivers/cpufreq/amd-pstate.h
> @@ -94,6 +94,7 @@ struct amd_cpudata {
>   	u32	min_limit_freq;
>   	u32	max_limit_freq;
>   	u32	nominal_freq;
> +	u32	max_freq;

Hi Mario,

A minor finding: the new u32 max_freq field is missing a kdoc entry in
struct amd_cpudata.


>   	u32	lowest_nonlinear_freq;
>   
>   	struct amd_aperf_mperf cur;


-- 
Thx and BRs,
Zhongqiu Han

^ permalink raw reply

* Re: (subset) [PATCH v2 00/14] power: sequencing: extend WCN driver to support WCN399x device
From: Bjorn Andersson @ 2026-03-24  3:42 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bartosz Golaszewski, Marcel Holtmann,
	Luiz Augusto von Dentz, Jeff Johnson, Konrad Dybcio,
	Manivannan Sadhasivam, Vinod Koul, Balakrishna Godavarthi,
	Matthias Kaehlcke, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-kernel, devicetree, linux-bluetooth,
	linux-wireless, ath10k, linux-pm, Krzysztof Kozlowski,
	Bartosz Golaszewski, Konrad Dybcio
In-Reply-To: <20260106-wcn3990-pwrctl-v2-0-0386204328be@oss.qualcomm.com>


On Tue, 06 Jan 2026 03:01:10 +0200, Dmitry Baryshkov wrote:
> Qualcomm WCN3950, WCN3988 and WCN399x families of WiFi/BT chips preceed
> the later WCN / QCA devices, but they still incorporate a very simple
> PMU on die. It controls internal on-chip power networks, but, most
> importantly, it also requires a certain start-up procedure (first bring
> up VDD_IO, then bring up other voltages). In order to further unify code
> supporting different families of QCA / WCN chips and in order to
> maintain the required power up sequence, properly represent these chips
> in DTs and modify drivers to use power sequencing for these chips.
> 
> [...]

Applied, thanks!

[10/14] arm64: dts: qcom: qrb2210-rb1: describe WiFi/BT properly
        commit: 2d0840e31c8a6ceebc701822889424bb1927d1a7
[11/14] arm64: dts: qcom: qrb4210-rb2: describe WiFi/BT properly
        commit: 1eea8321da0fa3b80eb19802ab830bf83d304519
[12/14] arm64: dts: qcom: sda660-ifc6560: describe WiFi/BT properly
        commit: 40a5da727ebc2a8d085feda501ab7bee4c5d9608
[13/14] arm64: dts: qcom: sdm845-db845c: describe WiFi/BT properly
        commit: 77648f3a7e9be4e7090bd326b2e4a4f9265b80f3
[14/14] arm64: dts: qcom: sm8150-hdk: describe WiFi/BT properly
        commit: d545fd1caf42a8f20531ba38c671f5bf10542720

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

^ permalink raw reply

* Re: [PATCH 3/5] clk: qcom: gdsc: Support enabling interconnect path for power domain
From: Mike Tipton @ 2026-03-24  3:34 UTC (permalink / raw)
  To: Luca Weiss
  Cc: Georgi Djakov, Bjorn Andersson, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio,
	~postmarketos/upstreaming, phone-devel, linux-pm, linux-kernel,
	linux-arm-msm, linux-clk, devicetree
In-Reply-To: <20260116-milos-camcc-icc-v1-3-400b7fcd156a@fairphone.com>

On Fri, Jan 16, 2026 at 02:17:22PM +0100, Luca Weiss wrote:
> On newer SoCs like Milos the CAMSS_TOP_GDSC power domains requires the
> enablement of the multimedia NoC, otherwise the GDSC will be stuck on
> 'off'.

As mentioned in another email, the dependency should actually be in the
other direction. Where MMNOC gets stuck turning off if CAM_TOP_GDSC is
still on.

> 
> Add support for getting an interconnect path as specified in the SoC
> clock driver, and enabling/disabling that interconnect path when the
> GDSC is being enabled/disabled.
> 
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> icc_enable()/icc_disable() seems like a nice API but doesn't work
> without setting the bandwidth first, so it's not very useful for this
> driver, at least I couldn't figure out how to use it correctly.

Agreed. In cases where a driver only needs simple zero or non-zero
votes, then icc_enable()/icc_disable() don't really help vs. just using
icc_set_bw().

> ---
>  drivers/clk/qcom/gdsc.c | 19 +++++++++++++++++++
>  drivers/clk/qcom/gdsc.h |  5 +++++
>  2 files changed, 24 insertions(+)
> 
> diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
> index 7deabf8400cf..ff1acaa3e008 100644
> --- a/drivers/clk/qcom/gdsc.c
> +++ b/drivers/clk/qcom/gdsc.c
> @@ -7,6 +7,7 @@
>  #include <linux/delay.h>
>  #include <linux/err.h>
>  #include <linux/export.h>
> +#include <linux/interconnect.h>
>  #include <linux/jiffies.h>
>  #include <linux/kernel.h>
>  #include <linux/ktime.h>
> @@ -261,6 +262,8 @@ static int gdsc_enable(struct generic_pm_domain *domain)
>  	struct gdsc *sc = domain_to_gdsc(domain);
>  	int ret;
>  
> +	icc_set_bw(sc->icc_path, 1, 1);

Need to handle the error. If the BW request fails, then we shouldn't
proceed to enable the GDSC.

Additionally, setting BW here doesn't handle the case where the GDSC is
enabled as part of gdsc_init(). If we move the icc_set_bw() calls into
gdsc_toggle_logic(), then we don't have to care about how many places
could ultimately enable or disable it. Since it's a fundamental HW
dependency, then placing the BW votes in the common place where we
actually toggle the GDSC on/off seems to make the most sense.

> +
>  	if (sc->pwrsts == PWRSTS_ON)
>  		return gdsc_deassert_reset(sc);
>  
> @@ -360,6 +363,8 @@ static int gdsc_disable(struct generic_pm_domain *domain)
>  	if (sc->flags & CLAMP_IO)
>  		gdsc_assert_clamp_io(sc);
>  
> +	icc_set_bw(sc->icc_path, 0, 0);

Similar to above -- we should handle the error case and ideally move
into gdsc_toggle_logic().

> +
>  	return 0;
>  }
>  
> @@ -574,6 +579,20 @@ int gdsc_register(struct gdsc_desc *desc,
>  	if (!data->domains)
>  		return -ENOMEM;
>  
> +	for (i = 0; i < num; i++) {
> +		if (!scs[i] || !scs[i]->needs_icc)
> +			continue;
> +
> +		scs[i]->icc_path = devm_of_icc_get_by_index(dev, scs[i]->icc_path_index);

I generally prefer using string-based DT lookups rather than
index-based, i.e. using devm_of_icc_get(). I know our clock drivers have
switched to primarily using index-based lookups, but I still generally
prefer string lookups:

  1. They're self-documenting within DT rather than relying on magic indices.
  2. The property name in the driver being non-NULL can indicate whether a
     handle is expected rather than relying on things like "needs_icc".
  3. Would remove the need of adding the new devm_of_icc_get_by_index() API, in
     this case.

There's nothing fundamentally wrong with this and I won't argue hard against it
especially considering that it's consistent with how our clock handles are being
looked up on more recent targets, but I often find the string lookups to be
cleaner and more robust.

> +		if (IS_ERR(scs[i]->icc_path)) {
> +			ret = PTR_ERR(scs[i]->icc_path);
> +			if (ret != -ENODEV)
> +				return ret;
> +
> +			scs[i]->icc_path = NULL;
> +		}
> +	}
> +
>  	for (i = 0; i < num; i++) {
>  		if (!scs[i] || !scs[i]->supply)
>  			continue;
> diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
> index dd843e86c05b..92ff6bcce7b1 100644
> --- a/drivers/clk/qcom/gdsc.h
> +++ b/drivers/clk/qcom/gdsc.h
> @@ -9,6 +9,7 @@
>  #include <linux/err.h>
>  #include <linux/pm_domain.h>
>  
> +struct icc_path;
>  struct regmap;
>  struct regulator;
>  struct reset_controller_dev;
> @@ -74,6 +75,10 @@ struct gdsc {
>  
>  	const char 			*supply;
>  	struct regulator		*rsupply;
> +
> +	bool				needs_icc;
> +	unsigned int			icc_path_index;
> +	struct icc_path			*icc_path;
>  };
>  
>  struct gdsc_desc {
> 
> -- 
> 2.52.0
> 
> 

^ permalink raw reply

* Re: [PATCH v8 0/2] mm/swap, PM: hibernate: fix swapoff race in uswsusp by pinning swap device
From: Andrew Morton @ 2026-03-24  3:03 UTC (permalink / raw)
  To: YoungJun Park
  Cc: Rafael J . Wysocki, Chris Li, Kairui Song, Pavel Machek,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Usama Arif,
	linux-pm, linux-mm
In-Reply-To: <acH8IKWyv9gW9YFU@yjaykim-PowerEdge-T330>

On Tue, 24 Mar 2026 11:51:12 +0900 YoungJun Park <youngjun.park@lge.com> wrote:

> > We'll hit a conflict in linux-next and Mark will tell us and we can
> > flag that to Linus when merging into mainline, usual stuff.
> > 
> > Or we can park this until the next cycle, depends on how serious the
> > bug is.  How serious is the bug?
> 
> Hi Andrew,
> 
> In my opinion, this bug is unlikely to occur and does not appear to be serious. 
> It may be better to park this for the next cycle.

Great, thanks.  I'll await Rafael's input and let's see how much damage
Mark encounters.


^ permalink raw reply

* Re: [PATCH v8 0/2] mm/swap, PM: hibernate: fix swapoff race in uswsusp by pinning swap device
From: YoungJun Park @ 2026-03-24  2:51 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Rafael J . Wysocki, Chris Li, Kairui Song, Pavel Machek,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Usama Arif,
	linux-pm, linux-mm
In-Reply-To: <20260323154833.045b732a5865b11b5b4e539e@linux-foundation.org>

On Mon, Mar 23, 2026 at 03:48:33PM -0700, Andrew Morton wrote:
> On Tue, 24 Mar 2026 01:08:20 +0900 Youngjun Park <youngjun.park@lge.com> wrote:
> 
> > Rebased onto mm-new per Andrew's suggestion [1]. The si->flags race
> > flagged by AI review in v7 (between SWP_HIBERNATION and cont_lock in
> > add_swap_count_continuation) and the proposed fixes discussed there
> > (atomic ops for si->flags, or serializing with swap_lock) are all moot
> > on mm-new since Kairui's series removed that code path entirely.
> > kernel/power/ changes are small, so Andrew proposed carrying everything
> > through mm-new.
> > 
> > Rafael, could you ack the PM-side changes?
> 
> Please.
> 
> We'll hit a conflict in linux-next and Mark will tell us and we can
> flag that to Linus when merging into mainline, usual stuff.
> 
> Or we can park this until the next cycle, depends on how serious the
> bug is.  How serious is the bug?

Hi Andrew,

In my opinion, this bug is unlikely to occur and does not appear to be serious. 
It may be better to park this for the next cycle.

I verified the behavior using suspend-utils. Below is a recap of the
reproduction scenarios I mentioned earlier in more detail.

Pre-condition
  - swapon /dev/sdb (intended for hibernation)

Case 1

  Process 1 (test program)        Process 2
  ---------------------------     ----------------
  ioctl(SNAPSHOT_SET_SWAP_AREA)
                                   swapoff /dev/sdb
  ioctl(SNAPSHOT_ALLOC_SWAP_PAGE)

  - SNAPSHOT_ALLOC_SWAP_PAGE fails with -ENOSPC.
  - The race window where swapoff /dev/sdb can occur is extremely
    small, and such an intentional sequence is unlikely in practice.
  - If SNAPSHOT_ALLOC_SWAP_PAGE succeeds, swapoff does not occur.

Case 2

  Process 1 (test program)        Process 2
  ---------------------------     ----------------
  ioctl(SNAPSHOT_SET_SWAP_AREA)
                                   swapoff /dev/sdb
                                   swapon /dev/sdc
  freeze processes
  ioctl(SNAPSHOT_ALLOC_SWAP_PAGE)
  create snapshot image

  - In testing, snapshot boot from /dev/sdb succeeds.
  - The swap block offset may be taken from an unexpected device,
    but I/O to /dev/sdb itself succeeds.
  - Since the actual allocated swap offset is not used for writing
    the snapshot image, there is a theoretical risk of corruption if
    I/O occurs at that offset on /dev/sdb during the window.
    However, Processes are frozen before writing the snapshot image to /dev/sdb.
    Therefore, while the issue is theoretically possible, the
    probability of it occurring in practice appears extremely low.


Best regards,
Youngjun Park

^ permalink raw reply

* Re: [PATCH 2/5] dt-bindings: clock: qcom,milos-camcc: Document interconnect path
From: Mike Tipton @ 2026-03-24  2:48 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Krzysztof Kozlowski, Luca Weiss, Taniya Das, Georgi Djakov,
	Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, ~postmarketos/upstreaming,
	phone-devel, linux-pm, linux-kernel, linux-arm-msm, linux-clk,
	devicetree
In-Reply-To: <9f8619d4-43ac-4bc0-9598-c498d59a27b8@oss.qualcomm.com>

On Mon, Jan 19, 2026 at 11:28:07AM +0100, Konrad Dybcio wrote:
> 
> 
> On 1/19/26 11:20 AM, Konrad Dybcio wrote:
> > On 1/17/26 12:46 PM, Krzysztof Kozlowski wrote:
> >> On Fri, Jan 16, 2026 at 02:17:21PM +0100, Luca Weiss wrote:
> >>> Document an interconnect path for camcc that's required to enable
> >>> the CAMSS_TOP_GDSC power domain.
> >>
> >> I find it confusing. Enabling GDSC power domains is done via power
> >> domains, not via interconnects. Do not represent power domains as
> >> interconnects, it's something completely different.
> > 
> > The name of the power domains is CAMSS_TOP_GDSC (seems you misread)
> > 
> > For the power domain to successfully turn on, the MNoC needs to be
> > turned on (empirical evidence). The way to do it is to request a
> > nonzero vote on this interconnect path
> > 
> > (presumably because the GDSC or its invisible providers require
> > something connected over that bus to carry out their enable sequences).

The GDSC itself shouldn't depend on MMNOC in order to turn on properly.
It should turn on just fine without it. There *is* a dependency between
CAM_TOP_GDSC and MMNOC, but it's in the opposite direction.

For MMNOC to turn off properly when all BW votes are removed, the
CAM_TOP_GDSC must already be off. If CAM_TOP_GDSC is still on when MMNOC
starts turning off, then MMNOC will get stuck in its collapse sequence.
MMNOC waits for all HW clients to de-assert their active signals before
it'll allow itself to collapse. Most HW blocks assert this active signal
more dynamically than camera does rather than tying it to GDSC state.
The GDSC asserting active signals to RPMh that prevent NOC collapse is
unique to this particular camera GDSC.

If MMNOC BW is removed when CAM_TOP_GDSC is still enabled, then it
should reproduce as an icc_set_bw() failure on MMNOC rather than a GDSC
enable failure. The icc_set_bw(0) request would succeed because RPMh
immediately ACKs down requests, but the collapse sequence would get
stuck in the background. Later, when someone calls icc_set_bw() again
with a non-zero BW to enable MMNOC, then that request would fail because
MMNOC is still stuck in the prior collapse sequence.

Note I haven't explicitly confirmed the Milos behavior, but this has
been the HW dependency for at least several generations of chips now.
I've never seen this GDSC get stuck turning on because MMNOC if off, nor
would I be able to explain offhand why that would happen. But MMNOC
certainly does depend on this GDSC for the reasons stated above.

So, regardless of the originally stated rationale, CAM_TOP_GDSC voting
on MMNOC *is* a logical requirement to guarantee that MMNOC doesn't turn
off when the GDSC is still on. Otherwise, that requirement would be left
entirely up to consumers to understand and enforce.

^ permalink raw reply

* Re: [RFC PATCH 1/2] thermal/cpufreq_cooling: remove unused cpu_idx in get_load()
From: Xuewen Yan @ 2026-03-24  2:20 UTC (permalink / raw)
  To: Lukasz Luba
  Cc: Viresh Kumar, Xuewen Yan, rui.zhang, rafael, linux-pm,
	amit.kachhap, daniel.lezcano, linux-kernel, ke.wang, di.shen,
	jeson.gao
In-Reply-To: <2a71d446-3277-4b8e-9b29-b77ebd3a4381@arm.com>

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...

^ permalink raw reply

* Re: [PATCH v2 0/9] interconnect: qcom: let MSM8974 interconnect work again
From: Alexandre Messier @ 2026-03-24  2:09 UTC (permalink / raw)
  To: Dmitry Baryshkov, Georgi Djakov, Konrad Dybcio, Bjorn Andersson,
	Luca Weiss, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Brian Masney
  Cc: linux-arm-msm, linux-pm, devicetree, linux-kernel, Brian Masney,
	Konrad Dybcio
In-Reply-To: <20260324-msm8974-icc-v2-0-527280043ad8@oss.qualcomm.com>

On 2026-03-23 20:10, Dmitry Baryshkov wrote:
> Commit d6edc31f3a68 ("clk: qcom: smd-rpm: Separate out interconnect bus
> clocks") moved control over several RPM resources from the clk-smd-rpm
> driver to the icc-rpm.c interconnect helpers. Most of the platforms were
> fixed before that commit or shortly after. However the MSM8974 was left
> as a foster child in broken state. Fix the loose ends and reenable
> interconnects on that platform.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> Changes in v2:
> - Swapped order of clocks and clock-names properties (Konrad)
> - Corrected the ocmem comment regarding core clock (Konrad)
> - Link to v1: https://lore.kernel.org/r/20260323-msm8974-icc-v1-0-7892b8d5f2ea@oss.qualcomm.com
> 
> ---
> Dmitry Baryshkov (9):
>       dt-bindings: interconnect: qcom,msm8974: drop bus clocks
>       dt-bindings: interconnect: qcom,msm8974: use qcom,rpm-common
>       interconnect: qcom: drop unused is_on flag
>       interconnect: qcom: icc-rpm: allow overwriting get_bw callback
>       interconnect: qcom: define OCMEM bus resource
>       interconnect: qcom: let platforms declare their bugginess
>       interconnect: qcom: msm8974: switch to the main icc-rpm driver
>       interconnect: qcom: msm8974: expand DEFINE_QNODE macros
>       ARM: dts: qcom: msm8974: Drop RPM bus clocks
> 
>  .../bindings/interconnect/qcom,msm8974.yaml        |   28 +-
>  arch/arm/boot/dts/qcom/qcom-msm8974.dtsi           |   21 +-
>  drivers/interconnect/qcom/icc-rpm-clocks.c         |    6 +
>  drivers/interconnect/qcom/icc-rpm.c                |   18 +-
>  drivers/interconnect/qcom/icc-rpm.h                |    7 +-
>  drivers/interconnect/qcom/msm8974.c                | 1637 +++++++++++++++-----
>  6 files changed, 1274 insertions(+), 443 deletions(-)
> ---
> base-commit: 8e5a478b6d6a5bb0a3d52147862b15e4d826af19
> change-id: 20260322-msm8974-icc-0ac4c28e139a
> 
> Best regards,
> --  
> With best wishes
> Dmitry
> 
> 

Tried this patch series on top of 7.0-rc5, using "htc,m8", and can confirm the device boots properly now!

I do see these messages in the kernel log now:

[    0.692540] ocmem fdd00000.sram: error -ENOENT: Unable to get core clock
[    0.692582] ocmem fdd00000.sram: probe with driver ocmem failed with error -2
[   24.173125] mmcc-msm8974 fd8c0000.clock-controller: sync_state() pending due to fdd00000.sram

I do not know if that error was expected or not.

In any case:

Tested-by: Alexandre Messier <alex@me.ssier.org>

^ permalink raw reply

* Re: [PATCH v10 10/12] bpf/rqspinlock: Use smp_cond_load_acquire_timeout()
From: Kumar Kartikeya Dwivedi @ 2026-03-24  1:46 UTC (permalink / raw)
  To: Ankur Arora
  Cc: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf, arnd,
	catalin.marinas, will, peterz, akpm, mark.rutland, harisokn, cl,
	ast, rafael, daniel.lezcano, zhenglifeng1, xueshuai, rdunlap,
	david.laight.linux, joao.m.martins, boris.ostrovsky, konrad.wilk
In-Reply-To: <20260316013651.3225328-11-ankur.a.arora@oracle.com>

On Mon, 16 Mar 2026 at 02:37, Ankur Arora <ankur.a.arora@oracle.com> wrote:
>
> Switch out the conditional load interfaces used by rqspinlock
> to smp_cond_read_acquire_timeout() and its wrapper,
> atomic_cond_read_acquire_timeout().
>
> Both these handle the timeout and amortize as needed, so use the
> non-amortized RES_CHECK_TIMEOUT.
>
> RES_CHECK_TIMEOUT does double duty here -- presenting the current
> clock value, the timeout/deadlock error from clock_deadlock() to
> the cond-load and, returning the error value via ret.
>
> For correctness, we need to ensure that the error case of the
> cond-load interface always agrees with that in clock_deadlock().
>
> For the most part, this is fine because there's no independent clock,
> or double reads from the clock in cond-load -- either of which could
> lead to its internal state going out of sync from that of
> clock_deadlock().
>
> There is, however, an edge case where clock_deadlock() checks for:
>
>         if (time > ts->timeout_end)
>                 return -ETIMEDOUT;
>
> while smp_cond_load_acquire_timeout() checks for:
>
>         __time_now = (time_expr_ns);
>         if (__time_now <= 0 || __time_now >= __time_end) {
>                 VAL = READ_ONCE(*__PTR);
>                 break;
>         }
>
> This runs into a problem when (__time_now == __time_end) since
> clock_deadlock() does not treat it as a timeout condition but
> the second clause in the conditional above does.
> So, add an equality check in clock_deadlock().
>
> Finally, redefine SMP_TIMEOUT_POLL_COUNT to be 16k to be similar to
> the spin-count used in the amortized version. We only do this for
> non-arm64 as that uses a waiting implementation.
>
> Cc: bpf@vger.kernel.org
> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
> ---

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>

> [...]

^ permalink raw reply

* Re: [PATCH v10 09/12] bpf/rqspinlock: switch check_timeout() to a clock interface
From: Kumar Kartikeya Dwivedi @ 2026-03-24  1:43 UTC (permalink / raw)
  To: Ankur Arora
  Cc: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf, arnd,
	catalin.marinas, will, peterz, akpm, mark.rutland, harisokn, cl,
	ast, rafael, daniel.lezcano, zhenglifeng1, xueshuai, rdunlap,
	david.laight.linux, joao.m.martins, boris.ostrovsky, konrad.wilk
In-Reply-To: <20260316013651.3225328-10-ankur.a.arora@oracle.com>

On Mon, 16 Mar 2026 at 02:37, Ankur Arora <ankur.a.arora@oracle.com> wrote:
>
> check_timeout() gets the current time value and depending on how
> much time has passed, checks for deadlock or times out, returning 0
> or -errno on deadlock or timeout.
>
> Switch this out to a clock style interface, where it functions as a
> clock in the "lock-domain", returning the current time until a
> deadlock or timeout occurs. Once a deadlock or timeout has occurred,
> it stops functioning as a clock and returns error.
>
> Also adjust the RES_CHECK_TIMEOUT macro to discard the clock value
> when updating the explicit return status.
>
> Cc: bpf@vger.kernel.org
> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
> --

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>

>  [...]
>

^ permalink raw reply

* Re: [PATCH v10 05/12] arm64: rqspinlock: Remove private copy of smp_cond_load_acquire_timewait()
From: Kumar Kartikeya Dwivedi @ 2026-03-24  1:41 UTC (permalink / raw)
  To: Ankur Arora
  Cc: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf, arnd,
	catalin.marinas, will, peterz, akpm, mark.rutland, harisokn, cl,
	ast, rafael, daniel.lezcano, zhenglifeng1, xueshuai, rdunlap,
	david.laight.linux, joao.m.martins, boris.ostrovsky, konrad.wilk
In-Reply-To: <20260316013651.3225328-6-ankur.a.arora@oracle.com>

On Mon, 16 Mar 2026 at 02:37, Ankur Arora <ankur.a.arora@oracle.com> wrote:
>
> In preparation for defining smp_cond_load_acquire_timeout(), remove
> the private copy. Lacking this, the rqspinlock code falls back to using
> smp_cond_load_acquire().

nit: This temporarily breaks bisection (or rather, leaves things
broken until later commits), but I don't care too much.

>
> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: bpf@vger.kernel.org
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Reviewed-by: Haris Okanovic <harisokn@amazon.com>
> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
> ---

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>

>  [...]
>

^ permalink raw reply

* Re: [RFC PATCH 2/2] thermal/cpufreq_cooling: Use idle_time to get cpu_load when scx_enabled
From: Qais Yousef @ 2026-03-24  1:41 UTC (permalink / raw)
  To: Xuewen Yan
  Cc: daniel.lezcano, amit.kachhap, viresh.kumar, lukasz.luba, rafael,
	rui.zhang, linux-pm, linux-kernel, ke.wang, di.shen, jeson.gao,
	xuewen.yan94, Peter Zijlstra, Vincent Guittot
In-Reply-To: <20260320113148.7308-2-xuewen.yan@unisoc.com>

On 03/20/26 19:31, Xuewen Yan wrote:
> From: Di Shen <di.shen@unisoc.com>
> 
> Recently, while enabling sched-ext debugging, we observed abnormal behavior
> in our thermal power_allocator’s temperature control.
> Through debugging, we found that the CPU util was too low, causing
> the CPU frequency to remain unrestricted.
> 
> This issue stems from the fact that in the sched_cpu_util() function,
> when scx is enabled, cpu_util_cfs becomes zero. As a result,
> the thermal subsystem perceives an extremely low CPU utilization,
> which degrades the effectiveness of the power_allocator’s control.
> 
> However, the scx_cpuperf_target() reflects the targeted performance,
> not the utilisation. We couldn't use it.
> 
> Until a perfect solution is found, using idle_time to get the cpu load
> might be a better approach.
> 
> Co-developed-by: Xuewen Yan <xuewen.yan@unisoc.com>
> Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com>
> Signed-off-by: Di Shen <di.shen@unisoc.com>
> ---
> Previous discussion:
> https://lore.kernel.org/all/5a5d565b-33ac-4d5c-b0dd-1353324a6117@arm.com/
> 
> ---
>  drivers/thermal/cpufreq_cooling.c | 54 ++++++++++++++++++++-----------
>  1 file changed, 35 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
> index d030dbeb2973..e8fa70a95d00 100644
> --- a/drivers/thermal/cpufreq_cooling.c
> +++ b/drivers/thermal/cpufreq_cooling.c
> @@ -24,6 +24,9 @@
>  #include <linux/units.h>
>  
>  #include "thermal_trace.h"
> +#ifdef CONFIG_SCHED_CLASS_EXT
> +#include "../../kernel/sched/sched.h"
> +#endif

This is a terrible include

>  
>  /*
>   * Cooling state <-> CPUFreq frequency
> @@ -72,7 +75,7 @@ struct cpufreq_cooling_device {
>  	struct em_perf_domain *em;
>  	struct cpufreq_policy *policy;
>  	struct thermal_cooling_device_ops cooling_ops;
> -#ifndef CONFIG_SMP
> +#if !defined(CONFIG_SMP) || defined(CONFIG_SCHED_CLASS_EXT)
>  	struct time_in_idle *idle_time;
>  #endif
>  	struct freq_qos_request qos_req;
> @@ -147,23 +150,9 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
>  	return freq;
>  }
>  
> -/**
> - * get_load() - get load for a cpu
> - * @cpufreq_cdev: struct cpufreq_cooling_device for the cpu
> - * @cpu: cpu number
> - *
> - * Return: The average load of cpu @cpu in percentage since this
> - * function was last called.
> - */
> -#ifdef CONFIG_SMP
> -static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu)
> -{
> -	unsigned long util = sched_cpu_util(cpu);
> -
> -	return (util * 100) / arch_scale_cpu_capacity(cpu);
> -}
> -#else /* !CONFIG_SMP */
> -static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu)
> +#if !defined(CONFIG_SMP) || defined(CONFIG_SCHED_CLASS_EXT)
> +static u32 get_load_from_idle_time(struct cpufreq_cooling_device *cpufreq_cdev,
> +				   int cpu)
>  {
>  	u32 load;
>  	u64 now, now_idle, delta_time, delta_idle;
> @@ -183,8 +172,35 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu)
>  
>  	return load;
>  }
> -#endif /* CONFIG_SMP */
> +#endif /* !defined(CONFIG_SMP) || defined(CONFIG_SCHED_CLASS_EXT) */

More ugly ifdefs

>  
> +/**
> + * get_load() - get load for a cpu
> + * @cpufreq_cdev: struct cpufreq_cooling_device for the cpu
> + * @cpu: cpu number
> + *
> + * Return: The average load of cpu @cpu in percentage since this
> + * function was last called.
> + */
> +#ifndef CONFIG_SMP
> +static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
> +		    int cpu_idx)
> +{
> +	return get_load_from_idle_time(cpufreq_cdev, cpu, cpu_idx);
> +}
> +#else /* CONFIG_SMP */
> +static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu)
> +{
> +	unsigned long util;
> +
> +#ifdef CONFIG_SCHED_CLASS_EXT
> +	if (scx_enabled())
> +		return get_load_from_idle_time(cpufreq_cdev, cpu);
> +#endif

Instead of this scx special hack, wouldn't it be better to implement this as
a special operation mode? But then this will beg the question do we actually
need sched_cpu_util() if it can all be done based on idle time and just remove
the deps on sched_cpu_util()?

ifdefing based on scx is nasty hack, this can be done better; most likely by
decoupling the deps on util if truly the idle time is enough. If it is not
enough, then I am not sure this will solve any problem.

> +	util = sched_cpu_util(cpu);
> +	return (util * 100) / arch_scale_cpu_capacity(cpu);
> +}
> +#endif /* !CONFIG_SMP */
>  /**
>   * get_dynamic_power() - calculate the dynamic power
>   * @cpufreq_cdev:	&cpufreq_cooling_device for this cdev
> -- 
> 2.25.1
> 

^ permalink raw reply

* [PATCH v4 6/6] cpupower-info.1: describe the --perf-bias option
From: Roberto Ricci @ 2026-03-24  1:35 UTC (permalink / raw)
  To: Thomas Renninger, Shuah Khan, John B. Wyatt IV, John Kacur,
	linux-pm, linux-kernel
  Cc: Roberto Ricci
In-Reply-To: <20260324013543.4776-1-io@r-ricci.it>

The cpupower-info(1) man page only mentions the short form of the
'--perf-bias' option in the synopsys, but the long form is not documented
and its effect is not explained.

cpupower-info.c:
     {"perf-bias", optional_argument, NULL, 'b'},

Signed-off-by: Roberto Ricci <io@r-ricci.it>
---
 tools/power/cpupower/man/cpupower-info.1 | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/power/cpupower/man/cpupower-info.1 b/tools/power/cpupower/man/cpupower-info.1
index 340bcd0be7de..1f42d8c388a0 100644
--- a/tools/power/cpupower/man/cpupower-info.1
+++ b/tools/power/cpupower/man/cpupower-info.1
@@ -3,7 +3,7 @@
 cpupower\-info \- Shows processor power related kernel or hardware configurations
 .SH SYNOPSIS
 .ft B
-.B cpupower info [ \-b ]
+.B cpupower info [\fIoptions\fP]
 
 .SH DESCRIPTION
 \fBcpupower info \fP shows kernel configurations or processor hardware
@@ -13,6 +13,13 @@ Some options are platform wide, some affect single cores. By default values
 of core zero are displayed only. cpupower --cpu all cpuinfo will show the
 settings of all cores, see cpupower(1) how to choose specific cores.
 
+.SH "OPTIONS"
+.LP
+.TP
+\fB\-b\fR \fB\-\-perf-bias\fR
+Gets the current performance bias value.
+.TP
+
 .SH "SEE ALSO"
 Options are described in detail in:
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v4 5/6] cpupower-frequency-info.1: document --boost and --epp options
From: Roberto Ricci @ 2026-03-24  1:35 UTC (permalink / raw)
  To: Thomas Renninger, Shuah Khan, John B. Wyatt IV, John Kacur,
	linux-pm, linux-kernel
  Cc: Roberto Ricci
In-Reply-To: <20260324013543.4776-1-io@r-ricci.it>

`cpupower frequency-info` supports the '--boost' option since the program
was first added with commit 7fe2f6399a84 ("cpupowerutils - cpufrequtils
extended with quite some features"), but the man page lacks it.

'--epp' has been added with commit 5f567afc283f ("cpupower: Add support for
showing energy performance preference") but it has never been added to the
man page.

cpufreq-info.c:
	{"boost",	 no_argument,		 NULL,	 'b'},
	...
	{"epp",		 no_argument,		 NULL,	 'z'},

Signed-off-by: Roberto Ricci <io@r-ricci.it>
---
 tools/power/cpupower/man/cpupower-frequency-info.1 | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1
index 7fce2b2e0506..346c2a6e40f4 100644
--- a/tools/power/cpupower/man/cpupower-frequency-info.1
+++ b/tools/power/cpupower/man/cpupower-frequency-info.1
@@ -32,6 +32,12 @@ Gets the currently used cpufreq policy.
 \fB\-g\fR \fB\-\-governors\fR
 Determines available cpufreq governors.
 .TP
+\fB\-b\fR \fB\-\-boost\fR
+Gets the current boost state support.
+.TP
+\fB\-z\fR \fB\-\-epp\fR
+Gets the current EPP (energy performance preference).
+.TP
 \fB\-r\fR \fB\-\-related\-cpus\fR
 Determines which CPUs run at the same hardware frequency.
 .TP
-- 
2.53.0


^ permalink raw reply related

* [PATCH v4 4/6] cpupower-frequency-info.1: use the proper name of the --perf option
From: Roberto Ricci @ 2026-03-24  1:35 UTC (permalink / raw)
  To: Thomas Renninger, Shuah Khan, John B. Wyatt IV, John Kacur,
	linux-pm, linux-kernel
  Cc: Roberto Ricci
In-Reply-To: <20260324013543.4776-1-io@r-ricci.it>

The cpupower-frequency-info(1) man page describes a '--perf' option.
Even though this form is accepted by the program, its proper name is
'--performance'.

cpufreq-info.c:
	{"performance", no_argument,	 NULL,	 'c'},

Signed-off-by: Roberto Ricci <io@r-ricci.it>
---
 tools/power/cpupower/man/cpupower-frequency-info.1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1
index e4173417b7c6..7fce2b2e0506 100644
--- a/tools/power/cpupower/man/cpupower-frequency-info.1
+++ b/tools/power/cpupower/man/cpupower-frequency-info.1
@@ -53,7 +53,7 @@ human\-readable output for the \-f, \-w, \-s and \-y parameters.
 \fB\-n\fR \fB\-\-no-rounding\fR
 Output frequencies and latencies without rounding off values.
 .TP
-\fB\-c\fR \fB\-\-perf\fR
+\fB\-c\fR \fB\-\-performance\fR
 Get performances and frequencies capabilities of CPPC, by reading it from hardware (only available on the hardware with CPPC).
 .TP
 .SH "REMARKS"
-- 
2.53.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