diff mbox series

[2/2] ACPI: processor idle: Check for architectural support for LPI

Message ID 20220225031255.3647599-3-mario.limonciello@amd.com
State New
Headers show
Series Avoid enabling LPI on non-ARM | expand

Commit Message

Mario Limonciello Feb. 25, 2022, 3:12 a.m. UTC
When `osc_pc_lpi_support_confirmed` is set through `_OSC` and `_LPI` is
populated then the cpuidle driver assumes that LPI is fully functional.

However currently the kernel only provides architectural support for LPI
on ARM.  This leads to high power consumption on X86 platforms that
otherwise try to enable LPI.

So probe whether or not LPI support is implemented before enabling LPI in
the kernel.  This is done by overloading `acpi_processor_ffh_lpi_probe` to
check whether it returns `-EOPNOTSUPP`. It also means that all future
implementations of `acpi_processor_ffh_lpi_probe` will need to follow
these semantics as well.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/acpi/processor_idle.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Comments

Sudeep Holla Feb. 25, 2022, 3 p.m. UTC | #1
On Thu, Feb 24, 2022 at 09:12:55PM -0600, Mario Limonciello wrote:
> When `osc_pc_lpi_support_confirmed` is set through `_OSC` and `_LPI` is
> populated then the cpuidle driver assumes that LPI is fully functional.
> 
> However currently the kernel only provides architectural support for LPI
> on ARM.  This leads to high power consumption on X86 platforms that
> otherwise try to enable LPI.
> 
> So probe whether or not LPI support is implemented before enabling LPI in
> the kernel.  This is done by overloading `acpi_processor_ffh_lpi_probe` to
> check whether it returns `-EOPNOTSUPP`. It also means that all future
> implementations of `acpi_processor_ffh_lpi_probe` will need to follow
> these semantics as well.
> 
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
> ---
>  drivers/acpi/processor_idle.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index f8e9fa82cb9b..0092fd479527 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -1080,6 +1080,11 @@ static int flatten_lpi_states(struct acpi_processor *pr,
>  	return 0;
>  }
>  
> +int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>  static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
>  {
>  	int ret, i;
> @@ -1094,6 +1099,11 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
>  	if (!acpi_has_method(handle, "_LPI"))
>  		return -EINVAL;
>  
> +	/* make sure our architecture has support */
> +	ret = acpi_processor_ffh_lpi_probe(pr->id);
> +	if (ret == -EOPNOTSUPP)
> +		return ret;
> +

You can do this check first, before even checking osc_pc_lpi_support_confirmed
and looking for _LPI method IMO as they are not useful if arch doesn't support
handling LPIs.

Either way,

Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
diff mbox series

Patch

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f8e9fa82cb9b..0092fd479527 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1080,6 +1080,11 @@  static int flatten_lpi_states(struct acpi_processor *pr,
 	return 0;
 }
 
+int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+
 static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
 {
 	int ret, i;
@@ -1094,6 +1099,11 @@  static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
 	if (!acpi_has_method(handle, "_LPI"))
 		return -EINVAL;
 
+	/* make sure our architecture has support */
+	ret = acpi_processor_ffh_lpi_probe(pr->id);
+	if (ret == -EOPNOTSUPP)
+		return ret;
+
 	flat_state_cnt = 0;
 	prev = &info[0];
 	curr = &info[1];
@@ -1139,11 +1149,6 @@  static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
 	return 0;
 }
 
-int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
-{
-	return -ENODEV;
-}
-
 int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
 	return -ENODEV;