* APM: Request to Test
[not found] <5118B776.6090604@linaro.org>
@ 2013-02-11 23:03 ` Len Brown
2013-02-11 23:03 ` [PATCH v2] APM idle: register apm_cpu_idle via cpuidle Len Brown
0 siblings, 1 reply; 5+ messages in thread
From: Len Brown @ 2013-02-11 23:03 UTC (permalink / raw)
To: linux-acpi, linux-pm; +Cc: linux-kernel
Thanks, Daniel, for reviewing the patch -- never would have worked...
Here is v2.
Is there anybody out there with an APM box
that can run an upstream kernel with this patch in it?
thanks,
-Len
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2] APM idle: register apm_cpu_idle via cpuidle
2013-02-11 23:03 ` APM: Request to Test Len Brown
@ 2013-02-11 23:03 ` Len Brown
2013-02-12 15:00 ` Daniel Lezcano
2013-02-18 13:30 ` Jiri Kosina
0 siblings, 2 replies; 5+ messages in thread
From: Len Brown @ 2013-02-11 23:03 UTC (permalink / raw)
To: linux-acpi, linux-pm; +Cc: linux-kernel, Len Brown, Jiri Kosina
From: Len Brown <len.brown@intel.com>
Update APM to register its local idle routine with cpuidle.
This allows us to stop exporting pm_idle to modules on x86.
The Kconfig sub-option, APM_CPU_IDLE, now depends on on CPU_IDLE.
Compile-tested only.
Signed-off-by: Len Brown <len.brown@intel.com>
Cc: Jiri Kosina <jkosina@suse.cz>
---
v2: updates from Daniel Lezcano's review
---
arch/x86/Kconfig | 1 +
arch/x86/kernel/apm_32.c | 60 +++++++++++++++++++++++++++++------------------
arch/x86/kernel/process.c | 3 ---
3 files changed, 38 insertions(+), 26 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 225543b..1b63586 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1912,6 +1912,7 @@ config APM_DO_ENABLE
this feature.
config APM_CPU_IDLE
+ depends on CPU_IDLE
bool "Make CPU Idle calls when idle"
---help---
Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index d65464e..f9f8afc 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -232,6 +232,7 @@
#include <linux/acpi.h>
#include <linux/syscore_ops.h>
#include <linux/i8253.h>
+#include <linux/cpuidle.h>
#include <asm/uaccess.h>
#include <asm/desc.h>
@@ -360,13 +361,38 @@ struct apm_user {
* idle percentage above which bios idle calls are done
*/
#ifdef CONFIG_APM_CPU_IDLE
-#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012
#define DEFAULT_IDLE_THRESHOLD 95
#else
#define DEFAULT_IDLE_THRESHOLD 100
#endif
#define DEFAULT_IDLE_PERIOD (100 / 3)
+static int apm_cpu_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index);
+
+static struct cpuidle_driver apm_idle_driver = {
+ .name = "apm_idle",
+ .owner = THIS_MODULE,
+ .en_core_tk_irqen = 1,
+ .states = {
+ { /* entry 0 is for polling */ },
+ { /* entry 1 is for APM idle */
+ .name = "APM",
+ .desc = "APM idle",
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .exit_latency = 250, /* WAG */
+ .target_residency = 500, /* WAG */
+ .enter = &apm_cpu_idle
+ },
+ },
+ .state_count = 2,
+};
+
+static struct cpuidle_device apm_cpuidle_device = {
+ .state_count = 2,
+};
+
+
/*
* Local variables
*/
@@ -377,7 +403,6 @@ static struct {
static int clock_slowed;
static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
-static int set_pm_idle;
static int suspends_pending;
static int standbys_pending;
static int ignore_sys_suspend;
@@ -884,8 +909,6 @@ static void apm_do_busy(void)
#define IDLE_CALC_LIMIT (HZ * 100)
#define IDLE_LEAKY_MAX 16
-static void (*original_pm_idle)(void) __read_mostly;
-
/**
* apm_cpu_idle - cpu idling for APM capable Linux
*
@@ -894,7 +917,8 @@ static void (*original_pm_idle)(void) __read_mostly;
* Furthermore it calls the system default idle routine.
*/
-static void apm_cpu_idle(void)
+static int apm_cpu_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
static int use_apm_idle; /* = 0 */
static unsigned int last_jiffies; /* = 0 */
@@ -904,7 +928,6 @@ static void apm_cpu_idle(void)
unsigned int jiffies_since_last_check = jiffies - last_jiffies;
unsigned int bucket;
- WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012");
recalc:
if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
use_apm_idle = 0;
@@ -950,10 +973,7 @@ recalc:
break;
}
}
- if (original_pm_idle)
- original_pm_idle();
- else
- default_idle();
+ default_idle();
local_irq_disable();
jiffies_since_last_check = jiffies - last_jiffies;
if (jiffies_since_last_check > idle_period)
@@ -963,7 +983,7 @@ recalc:
if (apm_idle_done)
apm_do_busy();
- local_irq_enable();
+ return index;
}
/**
@@ -2381,9 +2401,9 @@ static int __init apm_init(void)
if (HZ != 100)
idle_period = (idle_period * HZ) / 100;
if (idle_threshold < 100) {
- original_pm_idle = pm_idle;
- pm_idle = apm_cpu_idle;
- set_pm_idle = 1;
+ if (!cpuidle_register_driver(&apm_idle_driver))
+ if (cpuidle_register_device(&apm_cpuidle_device))
+ cpuidle_unregister_driver(&apm_idle_driver);
}
return 0;
@@ -2393,15 +2413,9 @@ static void __exit apm_exit(void)
{
int error;
- if (set_pm_idle) {
- pm_idle = original_pm_idle;
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- kick_all_cpus_sync();
- }
+ cpuidle_unregister_device(&apm_cpuidle_device);
+ cpuidle_unregister_driver(&apm_idle_driver);
+
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 2ed787f..f571a6e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -272,9 +272,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
-#ifdef CONFIG_APM_MODULE
-EXPORT_SYMBOL(pm_idle);
-#endif
#ifndef CONFIG_SMP
static inline void play_dead(void)
--
1.8.1.3.535.ga923c31
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2] APM idle: register apm_cpu_idle via cpuidle
2013-02-11 23:03 ` [PATCH v2] APM idle: register apm_cpu_idle via cpuidle Len Brown
@ 2013-02-12 15:00 ` Daniel Lezcano
2013-02-18 13:30 ` Jiri Kosina
1 sibling, 0 replies; 5+ messages in thread
From: Daniel Lezcano @ 2013-02-12 15:00 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown, Jiri Kosina
On 02/12/2013 12:03 AM, Len Brown wrote:
> From: Len Brown <len.brown@intel.com>
>
> Update APM to register its local idle routine with cpuidle.
>
> This allows us to stop exporting pm_idle to modules on x86.
>
> The Kconfig sub-option, APM_CPU_IDLE, now depends on on CPU_IDLE.
>
> Compile-tested only.
>
> Signed-off-by: Len Brown <len.brown@intel.com>
> Cc: Jiri Kosina <jkosina@suse.cz>
> ---
> v2: updates from Daniel Lezcano's review
> ---
> arch/x86/Kconfig | 1 +
> arch/x86/kernel/apm_32.c | 60 +++++++++++++++++++++++++++++------------------
> arch/x86/kernel/process.c | 3 ---
> 3 files changed, 38 insertions(+), 26 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 225543b..1b63586 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -1912,6 +1912,7 @@ config APM_DO_ENABLE
> this feature.
>
> config APM_CPU_IDLE
> + depends on CPU_IDLE
> bool "Make CPU Idle calls when idle"
> ---help---
> Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
> diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
> index d65464e..f9f8afc 100644
> --- a/arch/x86/kernel/apm_32.c
> +++ b/arch/x86/kernel/apm_32.c
> @@ -232,6 +232,7 @@
> #include <linux/acpi.h>
> #include <linux/syscore_ops.h>
> #include <linux/i8253.h>
> +#include <linux/cpuidle.h>
>
> #include <asm/uaccess.h>
> #include <asm/desc.h>
> @@ -360,13 +361,38 @@ struct apm_user {
> * idle percentage above which bios idle calls are done
> */
> #ifdef CONFIG_APM_CPU_IDLE
> -#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012
> #define DEFAULT_IDLE_THRESHOLD 95
> #else
> #define DEFAULT_IDLE_THRESHOLD 100
> #endif
> #define DEFAULT_IDLE_PERIOD (100 / 3)
>
> +static int apm_cpu_idle(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int index);
> +
> +static struct cpuidle_driver apm_idle_driver = {
> + .name = "apm_idle",
> + .owner = THIS_MODULE,
> + .en_core_tk_irqen = 1,
> + .states = {
> + { /* entry 0 is for polling */ },
> + { /* entry 1 is for APM idle */
> + .name = "APM",
> + .desc = "APM idle",
> + .flags = CPUIDLE_FLAG_TIME_VALID,
> + .exit_latency = 250, /* WAG */
> + .target_residency = 500, /* WAG */
> + .enter = &apm_cpu_idle
> + },
> + },
> + .state_count = 2,
> +};
> +
> +static struct cpuidle_device apm_cpuidle_device = {
> + .state_count = 2,
> +};
Actually this initialization is not needed because when it is set to
zero, the cpuidle_enable_device function will set it for us from the
driver's state_count.
int cpuidle_enable_device(struct cpuidle_device *dev)
{
...
if (!dev->state_count)
dev->state_count = drv->state_count;
}
It is useful to set a value when it differs from the driver's one.
Otherwise :
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> /*
> * Local variables
> */
> @@ -377,7 +403,6 @@ static struct {
> static int clock_slowed;
> static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
> static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
> -static int set_pm_idle;
> static int suspends_pending;
> static int standbys_pending;
> static int ignore_sys_suspend;
> @@ -884,8 +909,6 @@ static void apm_do_busy(void)
> #define IDLE_CALC_LIMIT (HZ * 100)
> #define IDLE_LEAKY_MAX 16
>
> -static void (*original_pm_idle)(void) __read_mostly;
> -
> /**
> * apm_cpu_idle - cpu idling for APM capable Linux
> *
> @@ -894,7 +917,8 @@ static void (*original_pm_idle)(void) __read_mostly;
> * Furthermore it calls the system default idle routine.
> */
>
> -static void apm_cpu_idle(void)
> +static int apm_cpu_idle(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int index)
> {
> static int use_apm_idle; /* = 0 */
> static unsigned int last_jiffies; /* = 0 */
> @@ -904,7 +928,6 @@ static void apm_cpu_idle(void)
> unsigned int jiffies_since_last_check = jiffies - last_jiffies;
> unsigned int bucket;
>
> - WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012");
> recalc:
> if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
> use_apm_idle = 0;
> @@ -950,10 +973,7 @@ recalc:
> break;
> }
> }
> - if (original_pm_idle)
> - original_pm_idle();
> - else
> - default_idle();
> + default_idle();
> local_irq_disable();
> jiffies_since_last_check = jiffies - last_jiffies;
> if (jiffies_since_last_check > idle_period)
> @@ -963,7 +983,7 @@ recalc:
> if (apm_idle_done)
> apm_do_busy();
>
> - local_irq_enable();
> + return index;
> }
>
> /**
> @@ -2381,9 +2401,9 @@ static int __init apm_init(void)
> if (HZ != 100)
> idle_period = (idle_period * HZ) / 100;
> if (idle_threshold < 100) {
> - original_pm_idle = pm_idle;
> - pm_idle = apm_cpu_idle;
> - set_pm_idle = 1;
> + if (!cpuidle_register_driver(&apm_idle_driver))
> + if (cpuidle_register_device(&apm_cpuidle_device))
> + cpuidle_unregister_driver(&apm_idle_driver);
> }
>
> return 0;
> @@ -2393,15 +2413,9 @@ static void __exit apm_exit(void)
> {
> int error;
>
> - if (set_pm_idle) {
> - pm_idle = original_pm_idle;
> - /*
> - * We are about to unload the current idle thread pm callback
> - * (pm_idle), Wait for all processors to update cached/local
> - * copies of pm_idle before proceeding.
> - */
> - kick_all_cpus_sync();
> - }
> + cpuidle_unregister_device(&apm_cpuidle_device);
> + cpuidle_unregister_driver(&apm_idle_driver);
> +
> if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
> && (apm_info.connection_version > 0x0100)) {
> error = apm_engage_power_management(APM_DEVICE_ALL, 0);
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 2ed787f..f571a6e 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -272,9 +272,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
> * Powermanagement idle function, if any..
> */
> void (*pm_idle)(void);
> -#ifdef CONFIG_APM_MODULE
> -EXPORT_SYMBOL(pm_idle);
> -#endif
>
> #ifndef CONFIG_SMP
> static inline void play_dead(void)
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] APM idle: register apm_cpu_idle via cpuidle
2013-02-11 23:03 ` [PATCH v2] APM idle: register apm_cpu_idle via cpuidle Len Brown
2013-02-12 15:00 ` Daniel Lezcano
@ 2013-02-18 13:30 ` Jiri Kosina
2013-02-20 17:48 ` Len Brown
1 sibling, 1 reply; 5+ messages in thread
From: Jiri Kosina @ 2013-02-18 13:30 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown
On Mon, 11 Feb 2013, Len Brown wrote:
> From: Len Brown <len.brown@intel.com>
>
> Update APM to register its local idle routine with cpuidle.
>
> This allows us to stop exporting pm_idle to modules on x86.
>
> The Kconfig sub-option, APM_CPU_IDLE, now depends on on CPU_IDLE.
>
> Compile-tested only.
I will test it on APM hardware and report back to you.
Do you then want me to take it through my tree, or are you going to push
the whole patchset as a whole?
--
Jiri Kosina
SUSE Labs
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] APM idle: register apm_cpu_idle via cpuidle
2013-02-18 13:30 ` Jiri Kosina
@ 2013-02-20 17:48 ` Len Brown
0 siblings, 0 replies; 5+ messages in thread
From: Len Brown @ 2013-02-20 17:48 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown
On 02/18/2013 08:30 AM, Jiri Kosina wrote:
> On Mon, 11 Feb 2013, Len Brown wrote:
>
>> From: Len Brown <len.brown@intel.com>
>>
>> Update APM to register its local idle routine with cpuidle.
>>
>> This allows us to stop exporting pm_idle to modules on x86.
>>
>> The Kconfig sub-option, APM_CPU_IDLE, now depends on on CPU_IDLE.
>>
>> Compile-tested only.
>
> I will test it on APM hardware and report back to you.
>
> Do you then want me to take it through my tree, or are you going to push
> the whole patchset as a whole?
Rafael took my series as a whole into his PM tree
and it is currently staged for a 3.9 pull.
But if I broke your APM box, I'm standing by
ready to fix it during the release.
Please get back to me with the test results:
dmesg | grep idle
grep . /sys/devices/system/cpu/cpu*/cpuidle/*/*
would tell us if it is working or not.
thanks!
-Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-02-20 17:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <5118B776.6090604@linaro.org>
2013-02-11 23:03 ` APM: Request to Test Len Brown
2013-02-11 23:03 ` [PATCH v2] APM idle: register apm_cpu_idle via cpuidle Len Brown
2013-02-12 15:00 ` Daniel Lezcano
2013-02-18 13:30 ` Jiri Kosina
2013-02-20 17:48 ` Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).