* Re: [linux-pm] [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Pavel Vasilyev @ 2012-08-06 16:00 UTC (permalink / raw)
To: Alan Stern
Cc: Pavel Machek, Len Brown, linux-acpi, linux-pm, linux-kernel,
Len Brown
In-Reply-To: <Pine.LNX.4.44L0.1208061028160.1649-100000@iolanthe.rowland.org>
06.08.2012 18:36, Alan Stern пишет:
> On Mon, 6 Aug 2012, Pavel Machek wrote:
>
>> On Thu 2012-07-26 21:39:38, Len Brown wrote:
>>> ...both give the number of chars in the string
>>> without the '\0', as strncmp() wants,
>>> but sizeof() is compile-time.
>>
>> What about introducing something like streq() to do this
>> automatically? This is ugly....
>>
>> #define streq(a, b) ... if (_buildin_constant(b)) ...
>>
>> ?
>>
>>> - if (!strncmp(val, "enable", strlen("enable"))) {
>>> + if (!strncmp(val, "enable", sizeof("enable") - 1)) {
>
> While you're at it, there's no point using strncmp when you know the
> length of one of the strings beforehand. Just use memcmp, and don't
> subtract 1 from the sizeof value.
http://www.gossamer-threads.com/lists/engine?do=post_attachment;postatt_id=41157;list=linux
:)
--
Pavel.
^ permalink raw reply
* Re: [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Alan Stern @ 2012-08-06 14:36 UTC (permalink / raw)
To: Pavel Machek
Cc: Len Brown, linux-kernel, linux-acpi, Pavel Vasilyev, linux-pm
In-Reply-To: <20120806102114.GA31404@elf.ucw.cz>
On Mon, 6 Aug 2012, Pavel Machek wrote:
> On Thu 2012-07-26 21:39:38, Len Brown wrote:
> > ...both give the number of chars in the string
> > without the '\0', as strncmp() wants,
> > but sizeof() is compile-time.
>
> What about introducing something like streq() to do this
> automatically? This is ugly....
>
> #define streq(a, b) ... if (_buildin_constant(b)) ...
>
> ?
>
> > - if (!strncmp(val, "enable", strlen("enable"))) {
> > + if (!strncmp(val, "enable", sizeof("enable") - 1)) {
While you're at it, there's no point using strncmp when you know the
length of one of the strings beforehand. Just use memcmp, and don't
subtract 1 from the sizeof value.
Alan Stern
^ permalink raw reply
* Re: [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Andreas Schwab @ 2012-08-06 10:26 UTC (permalink / raw)
To: Len Brown
Cc: Alan Stern, linux-acpi, linux-pm, linux-kernel, Len Brown,
Pavel Vasilyev
In-Reply-To: <5011F15A.3060007@kernel.org>
Len Brown <lenb@kernel.org> writes:
> ...both give the number of chars in the string
> without the '\0', as strncmp() wants,
> but sizeof() is compile-time.
Does this actually change anything? The compiler is able to expand
strlen at compile time if the argument is a constant, provided that that
builtin strlen isn't disabled.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [linux-pm] [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Pavel Machek @ 2012-08-06 10:21 UTC (permalink / raw)
To: Len Brown
Cc: Alan Stern, linux-acpi, linux-pm, linux-kernel, Len Brown,
Pavel Vasilyev
In-Reply-To: <5011F15A.3060007@kernel.org>
On Thu 2012-07-26 21:39:38, Len Brown wrote:
> ...both give the number of chars in the string
> without the '\0', as strncmp() wants,
> but sizeof() is compile-time.
What about introducing something like streq() to do this
automatically? This is ugly....
#define streq(a, b) ... if (_buildin_constant(b)) ...
?
> - if (!strncmp(val, "enable", strlen("enable"))) {
> + if (!strncmp(val, "enable", sizeof("enable") - 1)) {
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Is there a way to read instantaneous chip power?
From: Jae W. Lee @ 2012-08-02 4:20 UTC (permalink / raw)
To: linux-pm
[-- Attachment #1: Type: text/plain, Size: 277 bytes --]
Hi all,
Is there an API available to read instantaneous chip power, preferably in
userland? I know there are ways to read CPU temperature, but how about
power? I am primarily interested in ARM platform but information on other
platforms will be appreciated, too.
Thanks,
Jae
[-- Attachment #2: Type: text/html, Size: 353 bytes --]
^ permalink raw reply
* Re: [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: richard -rw- weinberger @ 2012-07-30 14:41 UTC (permalink / raw)
To: Ian Campbell
Cc: Len Brown, Alan Stern, linux-acpi, linux-pm, Pavel Vasilyev,
linux-kernel, Len Brown
In-Reply-To: <1343658373.15432.18.camel@zakaz.uk.xensource.com>
On Mon, Jul 30, 2012 at 4:26 PM, Ian Campbell <ijc@hellion.org.uk> wrote:
> I thought gcc optimised strlen("string literal") into a compile time
> constant too. It does in a little userspace test I just wrote, but I
> didn't look at its behaviour with the kernel's strlen.
It depends whether you use the built-in strlen() or not.
AFAIK the kernel does not use the built-in variant.
--
Thanks,
//richard
^ permalink raw reply
* Re: [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Ian Campbell @ 2012-07-30 14:26 UTC (permalink / raw)
To: Len Brown
Cc: Alan Stern, linux-acpi, linux-pm, Pavel Vasilyev, linux-kernel,
Len Brown
In-Reply-To: <5011F15A.3060007@kernel.org>
On Thu, 2012-07-26 at 21:39 -0400, Len Brown wrote:
> ...both give the number of chars in the string
> without the '\0', as strncmp() wants,
> but sizeof() is compile-time.
I thought gcc optimised strlen("string literal") into a compile time
constant too. It does in a little userspace test I just wrote, but I
didn't look at its behaviour with the kernel's strlen.
Ian.
^ permalink raw reply
* Re: [PATCH 2/4] x86 idle APM: delete apm_cpu_idle()
From: Len Brown @ 2012-07-29 2:21 UTC (permalink / raw)
To: Alan Cox; +Cc: Jiri Kosina, linux-pm, x86, linux-kernel
In-Reply-To: <20120728111148.39ff7230@ultron>
On 07/28/2012 06:11 AM, Alan Cox wrote:
> On Fri, 27 Jul 2012 18:42:53 -0400
> Len Brown <lenb@kernel.org> wrote:
>
>> From: Len Brown <len.brown@intel.com>
>>
>> The APM idle feature to call into the BIOS
>> is known to break some machines, and it has dubious benefit
>> on the (decades old) machines it doesn't break.
>
> You mean "doesn't fit my current plan" I think. I see almost no bugzilla
> APM reports. It's been solid for years.
Hm, I thought it was actually you that mentioned that this particular
feature of APM caused some systems to fail...
Unfortunately quiet bugzilla doesn't tell us the difference between
"solid as a rock and used by millions of users every day"
and "nobody anywhere running new software on this old hardware".
> It makes a big difference on older systems as it drops the clock. If we
> are going to drop this we should probaly also drop APM support entirely
> and 386/486 support.
Do you have an APM system that boots a 2012 kernel?
Are you willing to test new kernels on it?
> If not IMHO it should stay. Various embedded platforms are still using
> ancient hardware setups.
>
> This is a small stable piece of code that has required no maintainance in
> years
>
> Furthermore we have a feature removal process. Mark it down to be removed
> in July 2013 if there are no objections, and then wait as per proper
> process.
>
> NAK
At your request 16 months ago, we did exactly that.
Further, we added build-time and run-time warnings and all they did
was cause distro mis-merges and requests to remove the warnings.
16 months ago we came within inches of dropping APM entirely,
as Stephen said he hadn't maintained it for a long time.
Jiri volunteered to look after it, and Pavel offered
that he had 1 surviving machine someplace that actually
supports APM, though I don't know if boots.
I don't dispute that there may be some APM systems running someplace,
but if nobody is going to test a 2012 kernel on such hardware,
then we are kidding ourselves if we say we "support" today's kernel on it.
Also, the whole idea was even if we do support such HW, this patch
is supposed to make that HW more stable, not less stable.
-Len
^ permalink raw reply
* Re: [PATCH 2/4] x86 idle APM: delete apm_cpu_idle()
From: Alan Cox @ 2012-07-28 10:11 UTC (permalink / raw)
To: Len Brown; +Cc: Len Brown, linux-pm, x86, linux-kernel
In-Reply-To: <f8c928c1d43f5c4d1342bd05ca29c8ea788726b8.1343428708.git.len.brown@intel.com>
On Fri, 27 Jul 2012 18:42:53 -0400
Len Brown <lenb@kernel.org> wrote:
> From: Len Brown <len.brown@intel.com>
>
> The APM idle feature to call into the BIOS
> is known to break some machines, and it has dubious benefit
> on the (decades old) machines it doesn't break.
You mean "doesn't fit my current plan" I think. I see almost no bugzilla
APM reports. It's been solid for years.
It makes a big difference on older systems as it drops the clock. If we
are going to drop this we should probaly also drop APM support entirely
and 386/486 support.
If not IMHO it should stay. Various embedded platforms are still using
ancient hardware setups.
This is a small stable piece of code that has required no maintainance in
years
Furthermore we have a feature removal process. Mark it down to be removed
in July 2013 if there are no objections, and then wait as per proper
process.
NAK
Alan
^ permalink raw reply
* [PATCH 4/4] PM: cleanup: stop mandating that platforms export (pm_idle)()
From: Len Brown @ 2012-07-27 22:42 UTC (permalink / raw)
To: x86, linux-pm, linux-kernel
Cc: Jonas Bonn, Len Brown, #, Tony Luck, Mike Frysinger, Michal Simek,
David Howells, Mikael Starvik, Russell King, David S. Miller
In-Reply-To: <06ed885aac76cc68bd1ca1f32c8dcab7bcca1940.1343428708.git.len.brown@intel.com>
From: Len Brown <len.brown@intel.com>
(pm_idle)() was originally used on x86 to vector bewteen
ACPI and APM. With the advent of CPU_IDLE, that reason
for pm_idle to exist vanished.
But x86 APM still scribbled on pm_idle from a module,
so pm_idle didn't go away. Worse, it was declared in pm.h,
and so it spread to other architectures as dead code.
But today, APM no longer scribbles on pm_idle, so
x86 no longer requires pm_idle to be visible to modules,
or global at all.
Here we remove pm_idle from pm.h, to stop the mandate
that all architectures define it.
This deletes dead code from most architectures,
while some continue using their own internal pm_idle.
At the end of the day, pm_idle...
becomes static in sh, was global
becomes static in x86, was EXPORT_SYMBOL
becomes as global in sparc, was EXPORT_SYMBOL
continues as static in m32r (no pm.h use there)
and is deleted from all other places in the kernel.
Signed-off-by: Len Brown <len.brown@intel.com>
Cc: x86@kernel.org # x86
Cc: Mike Frysinger <vapier@gentoo.org> # blackfin
Cc: Jonas Bonn <jonas@southpole.se> # openrisc
Cc: Tony Luck <tony.luck@intel.com> # ia64
Cc: David Howells <dhowells@redhat.com> # mn10300
Cc: Mikael Starvik <starvik@axis.com> # cris
Cc: Michal Simek <monstr@monstr.eu> # microblaze
Cc: Paul Mundt <lethal@linux-sh.org> # sh
Cc: David S. Miller <davem@davemloft.net> # sparc
Cc: Russell King <linux@arm.linux.org.uk> # ARM
Cc: Rafael J. Wysocki <rjw@sisk.pl> # PM
---
arch/arm/kernel/process.c | 12 +++---------
arch/blackfin/kernel/process.c | 9 +--------
arch/cris/kernel/process.c | 17 ++---------------
arch/ia64/include/asm/processor.h | 2 --
arch/ia64/kernel/process.c | 10 ++--------
arch/ia64/kernel/setup.c | 1 -
arch/microblaze/kernel/process.c | 8 +-------
arch/mn10300/kernel/process.c | 16 ++--------------
arch/openrisc/kernel/idle.c | 5 -----
arch/sh/kernel/idle.c | 2 +-
arch/sparc/include/asm/setup.h | 1 +
arch/sparc/kernel/process_32.c | 1 -
arch/unicore32/kernel/process.c | 5 -----
arch/x86/kernel/process.c | 5 +----
include/linux/pm.h | 1 -
kernel/smp.c | 4 ++--
16 files changed, 16 insertions(+), 83 deletions(-)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 19c95ea..6af852e 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -172,14 +172,8 @@ static void default_idle(void)
local_irq_enable();
}
-void (*pm_idle)(void) = default_idle;
-EXPORT_SYMBOL(pm_idle);
-
/*
- * The idle thread, has rather strange semantics for calling pm_idle,
- * but this is what x86 does and we need to do the same, so that
- * things like cpuidle get called in the same way. The only difference
- * is that we always respect 'hlt_counter' to prevent low power idle.
+ * Respect 'hlt_counter' to prevent low power idle.
*/
void cpu_idle(void)
{
@@ -210,10 +204,10 @@ void cpu_idle(void)
} else if (!need_resched()) {
stop_critical_timings();
if (cpuidle_idle_call())
- pm_idle();
+ default_idle();
start_critical_timings();
/*
- * pm_idle functions must always
+ * idle functions must always
* return with IRQs enabled.
*/
WARN_ON(irqs_disabled());
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 62bcea7..892402a 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -42,9 +42,6 @@ unsigned long l1_stack_len;
/*
* Powermanagement idle function, if any..
*/
-void (*pm_idle)(void) = NULL;
-EXPORT_SYMBOL(pm_idle);
-
void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
@@ -81,18 +78,14 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
- void (*idle)(void) = pm_idle;
-
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
cpu_die();
#endif
- if (!idle)
- idle = default_idle;
tick_nohz_idle_enter();
rcu_idle_enter();
while (!need_resched())
- idle();
+ default_idle();
rcu_idle_exit();
tick_nohz_idle_exit();
preempt_enable_no_resched();
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 66fd017..ff20d39 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -54,12 +54,8 @@ void enable_hlt(void)
EXPORT_SYMBOL(enable_hlt);
/*
- * The following aren't currently used.
+ * The following is currently used.
*/
-void (*pm_idle)(void);
-
-extern void default_idle(void);
-
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@@ -75,16 +71,7 @@ void cpu_idle (void)
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
- void (*idle)(void);
- /*
- * Mark this as an RCU critical section so that
- * synchronize_kernel() in the unload path waits
- * for our completion.
- */
- idle = pm_idle;
- if (!idle)
- idle = default_idle;
- idle();
+ default_idle();
}
schedule_preempt_disabled();
}
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
index 832dd37..dea1ed3 100644
--- a/arch/ia64/include/asm/processor.h
+++ b/arch/ia64/include/asm/processor.h
@@ -717,8 +717,6 @@ extern unsigned long boot_option_idle_override;
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT,
IDLE_NOMWAIT, IDLE_POLL};
-void default_idle(void);
-
#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
#endif /* !__ASSEMBLY__ */
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index dd6fc14..e7c651c 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -56,8 +56,6 @@ void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
EXPORT_SYMBOL(boot_option_idle_override);
-void (*pm_idle) (void);
-EXPORT_SYMBOL(pm_idle);
void (*pm_power_off) (void);
EXPORT_SYMBOL(pm_power_off);
@@ -229,7 +227,7 @@ update_pal_halt_status(int status)
/*
* We use this if we don't have any better idle routine..
*/
-void
+static void
default_idle (void)
{
local_irq_enable();
@@ -291,7 +289,6 @@ cpu_idle (void)
}
if (!need_resched()) {
- void (*idle)(void);
#ifdef CONFIG_SMP
min_xtp();
#endif
@@ -299,10 +296,7 @@ cpu_idle (void)
if (mark_idle)
(*mark_idle)(1);
- idle = pm_idle;
- if (!idle)
- idle = default_idle;
- (*idle)();
+ default_idle();
if (mark_idle)
(*mark_idle)(0);
#ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index aaefd9b..2029cc0 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -1051,7 +1051,6 @@ cpu_init (void)
max_num_phys_stacked = num_phys_stacked;
}
platform_cpu_init();
- pm_idle = default_idle;
}
void __init
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 1944e00..508d225 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -40,7 +40,6 @@ void show_regs(struct pt_regs *regs)
regs->msr, regs->ear, regs->esr, regs->fsr);
}
-void (*pm_idle)(void);
void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
@@ -97,15 +96,10 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
- void (*idle)(void) = pm_idle;
-
- if (!idle)
- idle = default_idle;
-
tick_nohz_idle_enter();
rcu_idle_enter();
while (!need_resched())
- idle();
+ default_idle();
rcu_idle_exit();
tick_nohz_idle_exit();
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index 7dab0cd..6312a31 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -36,12 +36,6 @@
#include "internal.h"
/*
- * power management idle function, if any..
- */
-void (*pm_idle)(void);
-EXPORT_SYMBOL(pm_idle);
-
-/*
* return saved PC of a blocked thread.
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
@@ -108,18 +102,12 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
for (;;) {
while (!need_resched()) {
- void (*idle)(void);
-
smp_rmb();
- idle = pm_idle;
- if (!idle) {
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
- idle = poll_idle;
+ poll_idle();
#else /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
- idle = default_idle;
+ default_idle();
#endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
- }
- idle();
}
schedule_preempt_disabled();
diff --git a/arch/openrisc/kernel/idle.c b/arch/openrisc/kernel/idle.c
index 7d618fe..5e8a3b6 100644
--- a/arch/openrisc/kernel/idle.c
+++ b/arch/openrisc/kernel/idle.c
@@ -39,11 +39,6 @@
void (*powersave) (void) = NULL;
-static inline void pm_idle(void)
-{
- barrier();
-}
-
void cpu_idle(void)
{
set_thread_flag(TIF_POLLING_NRFLAG);
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 0c91016..f063b92 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -22,7 +22,7 @@
#include <asm/smp.h>
#include <asm/bl_bit.h>
-void (*pm_idle)(void);
+static void (*pm_idle)(void);
static int hlt_counter;
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 8a83699..33bef87 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -34,6 +34,7 @@ extern void sun_do_break(void);
extern int stop_a_enabled;
extern int scons_pwroff;
+extern void (*pm_idle)(void);
#endif /* __KERNEL__ */
#endif /* _SPARC_SETUP_H */
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index cb36e82..1c702bd 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -44,7 +44,6 @@
* Set in pm platform drivers (apc.c and pmc.c)
*/
void (*pm_idle)(void);
-EXPORT_SYMBOL(pm_idle);
/*
* Power-off handler instantiation for pm.h compliance
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b6f0458..3841ef97 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -45,11 +45,6 @@ static const char * const processor_modes[] = {
"UK18", "UK19", "UK1A", "EXTN", "UK1C", "UK1D", "UK1E", "SUSR"
};
-/*
- * The idle thread, has rather strange semantics for calling pm_idle,
- * but this is what x86 does and we need to do the same, so that
- * things like cpuidle get called in the same way.
- */
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 165f870..c385cfa 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -372,10 +372,7 @@ EXPORT_SYMBOL(boot_option_idle_override);
/*
* Powermanagement idle function, if any..
*/
-void (*pm_idle)(void);
-#ifdef CONFIG_APM_MODULE
-EXPORT_SYMBOL(pm_idle);
-#endif
+static void (*pm_idle)(void);
static inline int hlt_use_halt(void)
{
diff --git a/include/linux/pm.h b/include/linux/pm.h
index f067e60..6b92c37 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -31,7 +31,6 @@
/*
* Callbacks for platform drivers to implement.
*/
-extern void (*pm_idle)(void);
extern void (*pm_power_off)(void);
extern void (*pm_power_off_prepare)(void);
diff --git a/kernel/smp.c b/kernel/smp.c
index d0ae5b2..ede77e4 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -803,11 +803,11 @@ static void do_nothing(void *unused)
/**
* kick_all_cpus_sync - Force all cpus out of idle
*
- * Used to synchronize the update of pm_idle function pointer. It's
+ * Used to synchronize the update of idle function pointer. It's
* called after the pointer is updated and returns after the dummy
* callback function has been executed on all cpus. The execution of
* the function can only happen on the remote cpus after they have
- * left the idle function which had been called via pm_idle function
+ * left the idle function which had been called via idle function
* pointer. So it's guaranteed that nothing uses the previous pointer
* anymore.
*/
--
1.7.12.rc0
^ permalink raw reply related
* [PATCH 3/4] x86, idle: make default_idle() static
From: Len Brown @ 2012-07-27 22:42 UTC (permalink / raw)
To: x86, linux-pm, linux-kernel; +Cc: Len Brown
In-Reply-To: <06ed885aac76cc68bd1ca1f32c8dcab7bcca1940.1343428708.git.len.brown@intel.com>
From: Len Brown <len.brown@intel.com>
default_idle() was public and exported to modules
for the benefit of APM. But APM no longer touches
default_idle(), so default_idle() can now be private.
Cc: x86@kernel.org
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/include/asm/processor.h | 1 -
arch/x86/kernel/process.c | 5 +----
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 39bc577..b02e48c 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -979,7 +979,6 @@ extern bool cpu_has_amd_erratum(const int *);
extern unsigned long arch_align_stack(unsigned long sp);
extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
-void default_idle(void);
bool set_pm_idle_to_default(void);
void stop_this_cpu(void *dummy);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 735279e..165f870 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -479,7 +479,7 @@ void cpu_idle(void)
* We use this if we don't have any better
* idle routine..
*/
-void default_idle(void)
+static void default_idle(void)
{
if (hlt_use_halt()) {
trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
@@ -504,9 +504,6 @@ void default_idle(void)
cpu_relax();
}
}
-#ifdef CONFIG_APM_MODULE
-EXPORT_SYMBOL(default_idle);
-#endif
bool set_pm_idle_to_default(void)
{
--
1.7.12.rc0
^ permalink raw reply related
* [PATCH 2/4] x86 idle APM: delete apm_cpu_idle()
From: Len Brown @ 2012-07-27 22:42 UTC (permalink / raw)
To: x86, linux-pm, linux-kernel; +Cc: Len Brown
In-Reply-To: <06ed885aac76cc68bd1ca1f32c8dcab7bcca1940.1343428708.git.len.brown@intel.com>
From: Len Brown <len.brown@intel.com>
The APM idle feature to call into the BIOS
is known to break some machines, and it has dubious benefit
on the (decades old) machines it doesn't break.
After this patch, systems running in APM mode will
simply run default_idle() and HALT, rather than calling
into the BIOS from their idle loop.
This also deletes the last modular use use of (pm_idle)()
and default_idle().
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/Kconfig | 11 ---
arch/x86/kernel/apm_32.c | 232 -----------------------------------------------
2 files changed, 243 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c70684f..7da1e35 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1847,17 +1847,6 @@ config APM_DO_ENABLE
T400CDT. This is off by default since most machines do fine without
this feature.
-config APM_CPU_IDLE
- bool "Make CPU Idle calls when idle"
- ---help---
- Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
- On some machines, this can activate improved power savings, such as
- a slowed CPU clock rate, when the machine is idle. These idle calls
- are made after the idle loop has run for some length of time (e.g.,
- 333 mS). On some machines, this will cause a hang at boot time or
- whenever the CPU becomes idle. (On machines with more than one CPU,
- this option does nothing.)
-
config APM_DISPLAY_BLANK
bool "Enable console blanking using APM"
---help---
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 3a89ca3..31b4196 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -175,8 +175,6 @@
* Ignore first resume after we generate our own resume event
* after a suspend (Thomas Hood)
* Daemonize now gets rid of our controlling terminal (sfr).
- * CONFIG_APM_CPU_IDLE now just affects the default value of
- * idle_threshold (sfr).
* Change name of kernel apm daemon (as it no longer idles) (sfr).
* 1.16ac: Fix up SMP support somewhat. You can now force SMP on and we
* make _all_ APM calls on the CPU#0. Fix unsafe sign bug.
@@ -260,12 +258,6 @@ extern int (*console_blank_hook)(int);
* [no-]smp Use apm even on an SMP box
* bounce[-_]interval=<n> number of ticks to ignore suspend
* bounces
- * idle[-_]threshold=<n> System idle percentage above which to
- * make APM BIOS idle calls. Set it to
- * 100 to disable.
- * idle[-_]period=<n> Period (in 1/100s of a second) over
- * which the idle percentage is
- * calculated.
*/
/* KNOWN PROBLEM MACHINES:
@@ -355,26 +347,12 @@ struct apm_user {
#define APM_BIOS_MAGIC 0x4101
/*
- * idle percentage above which bios idle calls are done
- */
-#ifdef CONFIG_APM_CPU_IDLE
-#define DEFAULT_IDLE_THRESHOLD 95
-#else
-#define DEFAULT_IDLE_THRESHOLD 100
-#endif
-#define DEFAULT_IDLE_PERIOD (100 / 3)
-
-/*
* Local variables
*/
static struct {
unsigned long offset;
unsigned short segment;
} apm_bios_entry;
-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;
@@ -804,165 +782,6 @@ static int set_system_power_state(u_short state)
}
/**
- * apm_do_idle - perform power saving
- *
- * This function notifies the BIOS that the processor is (in the view
- * of the OS) idle. It returns -1 in the event that the BIOS refuses
- * to handle the idle request. On a success the function returns 1
- * if the BIOS did clock slowing or 0 otherwise.
- */
-
-static int apm_do_idle(void)
-{
- u32 eax;
- u8 ret = 0;
- int idled = 0;
- int polling;
- int err = 0;
-
- polling = !!(current_thread_info()->status & TS_POLLING);
- if (polling) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- }
- if (!need_resched()) {
- idled = 1;
- ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
- }
- if (polling)
- current_thread_info()->status |= TS_POLLING;
-
- if (!idled)
- return 0;
-
- if (ret) {
- static unsigned long t;
-
- /* This always fails on some SMP boards running UP kernels.
- * Only report the failure the first 5 times.
- */
- if (++t < 5) {
- printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
- t = jiffies;
- }
- return -1;
- }
- clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
- return clock_slowed;
-}
-
-/**
- * apm_do_busy - inform the BIOS the CPU is busy
- *
- * Request that the BIOS brings the CPU back to full performance.
- */
-
-static void apm_do_busy(void)
-{
- u32 dummy;
- int err;
-
- if (clock_slowed || ALWAYS_CALL_BUSY) {
- (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
- clock_slowed = 0;
- }
-}
-
-/*
- * If no process has really been interested in
- * the CPU for some time, we want to call BIOS
- * power management - we probably want
- * to conserve power.
- */
-#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
- *
- * This is the idling function the kernel executes when APM is available. It
- * tries to do BIOS powermanagement based on the average system idle time.
- * Furthermore it calls the system default idle routine.
- */
-
-static void apm_cpu_idle(void)
-{
- static int use_apm_idle; /* = 0 */
- static unsigned int last_jiffies; /* = 0 */
- static unsigned int last_stime; /* = 0 */
-
- int apm_idle_done = 0;
- unsigned int jiffies_since_last_check = jiffies - last_jiffies;
- unsigned int bucket;
-
-recalc:
- if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- } else if (jiffies_since_last_check > idle_period) {
- unsigned int idle_percentage;
-
- idle_percentage = current->stime - last_stime;
- idle_percentage *= 100;
- idle_percentage /= jiffies_since_last_check;
- use_apm_idle = (idle_percentage > idle_threshold);
- if (apm_info.forbid_idle)
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- }
-
- bucket = IDLE_LEAKY_MAX;
-
- while (!need_resched()) {
- if (use_apm_idle) {
- unsigned int t;
-
- t = jiffies;
- switch (apm_do_idle()) {
- case 0:
- apm_idle_done = 1;
- if (t != jiffies) {
- if (bucket) {
- bucket = IDLE_LEAKY_MAX;
- continue;
- }
- } else if (bucket) {
- bucket--;
- continue;
- }
- break;
- case 1:
- apm_idle_done = 1;
- break;
- default: /* BIOS refused */
- break;
- }
- }
- if (original_pm_idle)
- original_pm_idle();
- else
- default_idle();
- local_irq_disable();
- jiffies_since_last_check = jiffies - last_jiffies;
- if (jiffies_since_last_check > idle_period)
- goto recalc;
- }
-
- if (apm_idle_done)
- apm_do_busy();
-
- local_irq_enable();
-}
-
-/**
* apm_power_off - ask the BIOS to power off
*
* Handle the power off sequence. This is the one piece of code we
@@ -1869,12 +1688,6 @@ static int __init apm_setup(char *str)
if ((strncmp(str, "bounce-interval=", 16) == 0) ||
(strncmp(str, "bounce_interval=", 16) == 0))
bounce_interval = simple_strtol(str + 16, NULL, 0);
- if ((strncmp(str, "idle-threshold=", 15) == 0) ||
- (strncmp(str, "idle_threshold=", 15) == 0))
- idle_threshold = simple_strtol(str + 15, NULL, 0);
- if ((strncmp(str, "idle-period=", 12) == 0) ||
- (strncmp(str, "idle_period=", 12) == 0))
- idle_period = simple_strtol(str + 12, NULL, 0);
invert = (strncmp(str, "no-", 3) == 0) ||
(strncmp(str, "no_", 3) == 0);
if (invert)
@@ -1886,7 +1699,6 @@ static int __init apm_setup(char *str)
power_off = !invert;
if (strncmp(str, "smp", 3) == 0) {
smp = !invert;
- idle_threshold = 100;
}
if ((strncmp(str, "allow-ints", 10) == 0) ||
(strncmp(str, "allow_ints", 10) == 0))
@@ -1987,17 +1799,6 @@ static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
return 0;
}
-/* Some APM bioses hang on APM idle calls */
-static int __init apm_likes_to_melt(const struct dmi_system_id *d)
-{
- if (apm_info.forbid_idle == 0) {
- apm_info.forbid_idle = 1;
- printk(KERN_INFO "%s machine detected. "
- "Disabling APM idle calls.\n", d->ident);
- }
- return 0;
-}
-
/*
* Check for clue free BIOS implementations who use
* the following QA technique
@@ -2138,16 +1939,6 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
},
- { /* APM idle hangs */
- apm_likes_to_melt, "Jabil AMD",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
- },
- { /* APM idle hangs */
- apm_likes_to_melt, "AMI Bios",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
- },
{ /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
swab_apm_power_in_minutes, "Sony VAIO",
{ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -2377,14 +2168,6 @@ static int __init apm_init(void)
if (misc_register(&apm_device))
printk(KERN_WARNING "apm: Could not register misc device.\n");
- 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;
- }
-
return 0;
}
@@ -2392,15 +2175,6 @@ 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();
- }
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0);
@@ -2437,12 +2211,6 @@ MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
module_param(realmode_power_off, bool, 0444);
MODULE_PARM_DESC(realmode_power_off,
"Switch to real mode before powering off");
-module_param(idle_threshold, int, 0444);
-MODULE_PARM_DESC(idle_threshold,
- "System idle percentage above which to make APM BIOS idle calls");
-module_param(idle_period, int, 0444);
-MODULE_PARM_DESC(idle_period,
- "Period (in sec/100) over which to caculate the idle percentage");
module_param(smp, bool, 0444);
MODULE_PARM_DESC(smp,
"Set this to enable APM use on an SMP platform. Use with caution on older systems");
--
1.7.12.rc0
^ permalink raw reply related
* [PATCH 1/4] Revert "x86 idle APM: deprecate CONFIG_APM_CPU_IDLE" to prepare for actual removal
From: Len Brown @ 2012-07-27 22:42 UTC (permalink / raw)
To: x86, linux-pm, linux-kernel; +Cc: Len Brown, Jiri Kosina
In-Reply-To: <1343428975-3897-1-git-send-email-lenb@kernel.org>
From: Len Brown <len.brown@intel.com>
Remove warning that perplex users about removal of CONFIG_APM_CPU_IDLE in 2012.
This allows applying the original removal patch cleanly.
In retrospect, adding this warning was a mistake.
We should have shipped the removal patch 16 months ago.
cc: x86@kernel.org
cc: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
Documentation/feature-removal-schedule.txt | 10 ++++++++++
arch/x86/kernel/apm_32.c | 2 ++
2 files changed, 12 insertions(+)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5540615..fc505c1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -14,6 +14,16 @@ Who: Len Brown <len.brown@intel.com>
---------------------------
+What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
+When: 2012
+Why: This optional sub-feature of APM is of dubious reliability,
+ and ancient APM laptops are likely better served by calling HLT.
+ Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
+ the pm_idle function pointer to modules.
+Who: Len Brown <len.brown@intel.com>
+
+----------------------------
+
What: x86_32 "no-hlt" cmdline param
When: 2012
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 0e4f24c..4c4ac32 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -359,6 +359,7 @@ 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
@@ -902,6 +903,7 @@ 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;
--
1.7.12.rc0
Signed-off-by: Len Brown <len.brown@intel.com>
---
Documentation/feature-removal-schedule.txt | 10 ----------
arch/x86/kernel/apm_32.c | 2 --
2 files changed, 12 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 56000b3..bb4f9e0 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -13,16 +13,6 @@ Who: Jim Cromie <jim.cromie@gmail.com>, Jason Baron <jbaron@redhat.com>
---------------------------
-What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
-When: 2012
-Why: This optional sub-feature of APM is of dubious reliability,
- and ancient APM laptops are likely better served by calling HLT.
- Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
- the pm_idle function pointer to modules.
-Who: Len Brown <len.brown@intel.com>
-
-----------------------------
-
What: x86_32 "no-hlt" cmdline param
When: 2012
Why: remove a branch from idle path, simplify code used by everybody.
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 07b0c0d..3a89ca3 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -358,7 +358,6 @@ 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
@@ -902,7 +901,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;
--
1.7.12.rc0
^ permalink raw reply related
* [0/4] pm_idle, default_idle cleanup
From: Len Brown @ 2012-07-27 22:42 UTC (permalink / raw)
To: x86, linux-pm, linux-kernel
The 1st three patches in this series are specific to x86.
With an ack from the x86 crew (the main patch still has Ingo's ack
from 16 months ago) I think they could be 3.6-rc1 cleanup candidates.
The 4th patch is enabled by the first 3 -- removing pm_idle() from pm.h
touches 10 architectures. That one will need a bunch of acks and
post rc1 linux-next build testing to make sure it doesn't break 3.7.
thanks,
Len Brown, Intel Open Source Technology Center
^ permalink raw reply
* [PATCH] ACPI: replace strlen("string") with sizeof("string") -1
From: Len Brown @ 2012-07-27 1:39 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown, Pavel Vasilyev
In-Reply-To: <Pine.LNX.4.44L0.1206301023540.29029-100000@netrider.rowland.org>
...both give the number of chars in the string
without the '\0', as strncmp() wants,
but sizeof() is compile-time.
Reported-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Pavel Vasilyev <pavel@pavlinux.ru>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/sysfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 240a244..7c3f98b 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val,
struct kernel_param *kp)
{
int result = 0;
- if (!strncmp(val, "enable", strlen("enable"))) {
+ if (!strncmp(val, "enable", sizeof("enable") - 1)) {
result = acpi_debug_trace(trace_method_name, trace_debug_level,
trace_debug_layer, 0);
if (result)
@@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val,
struct kernel_param *kp)
goto exit;
}
- if (!strncmp(val, "disable", strlen("disable"))) {
+ if (!strncmp(val, "disable", sizeof("disable") - 1)) {
int name = 0;
result = acpi_debug_trace((char *)&name, trace_debug_level,
trace_debug_layer, 0);
--
1.7.12.rc0
^ permalink raw reply related
* Re: [PATCH 48/52] tools/power: turbostat: fix large c1% issue
From: Konrad Rzeszutek Wilk @ 2012-07-25 13:03 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, linux-pm, linux-kernel, Len Brown
In-Reply-To: <c3ae331d1c2fe25edfbece73fda0bb312445b636.1343187618.git.len.brown@intel.com>
On Tue, Jul 24, 2012 at 11:41:44PM -0400, Len Brown wrote:
> From: Len Brown <len.brown@intel.com>
>
> Under some conditions, c1% was displayed as very large number,
> much higher than 100%.
>
> c1% is not measured, it is derived as "that, which is left over"
> from other counters. However, the other counters are not collected
> atomically, and so it is possible for c1% to be calaculagted as
calculated.
> a small negative number -- displayed as very large positive.
>
> There was a check for mperf vs tsc for this already,
> but it needed to also include the other counters
> that are used to calculate c1.
>
> Signed-off-by: Len Brown <len.brown@intel.com>
> ---
> tools/power/x86/turbostat/turbostat.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
> index b815a12..861d771 100644
> --- a/tools/power/x86/turbostat/turbostat.c
> +++ b/tools/power/x86/turbostat/turbostat.c
> @@ -444,6 +444,9 @@ delta_core(struct core_data *new, struct core_data *old)
> old->c7 = new->c7 - old->c7;
> }
>
> +/*
> + * old = new - old
> + */
> void
> delta_thread(struct thread_data *new, struct thread_data *old,
> struct core_data *core_delta)
> @@ -482,19 +485,20 @@ delta_thread(struct thread_data *new, struct thread_data *old,
>
>
> /*
> - * As mperf and tsc collection are not atomic,
> - * it is possible for mperf's non-halted cycles
> + * As counter collection is not atomic,
> + * it is possible for mperf's non-halted cycles + idle states
> * to exceed TSC's all cycles: show c1 = 0% in that case.
> */
> - if (old->mperf > old->tsc)
> + if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
> old->c1 = 0;
> else {
> /* normal case, derive c1 */
> old->c1 = old->tsc - old->mperf - core_delta->c3
> - core_delta->c6 - core_delta->c7;
> }
> +
> if (old->mperf == 0) {
> - if (verbose) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
> + if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
> old->mperf = 1; /* divide by 0 protection */
> }
>
> --
> 1.7.12.rc0
>
> --
> 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
* Re: [PATCH v4 3/4] OMAP2+: use control module mfd driver in omap_type
From: Konstantin Baydarov @ 2012-07-25 12:45 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, amit.kucheria,
Eduardo Valentin, balbi, linux-pm, linux-omap, linux-arm-kernel,
amit.kachhap
In-Reply-To: <500FE915.6090707@mvista.com>
HI, Sergei.
On 07/25/2012 04:39 PM, Sergei Shtylyov wrote:
> Hello.
>
> On 25-07-2012 15:05, Konstantin Baydarov wrote:
>
>> OMAP system control module can be probed early, then
>> omap_type is safe to use its APIs.
>
>> TODO: add support for other omap versions
>
>> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
>> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
>> ---
>> arch/arm/mach-omap2/id.c | 11 ++++++-----
>> 1 files changed, 6 insertions(+), 5 deletions(-)
>
>> diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
>> index 40373db..8018cad 100644
>> --- a/arch/arm/mach-omap2/id.c
>> +++ b/arch/arm/mach-omap2/id.c
> [...]
>> @@ -43,15 +44,15 @@ int omap_type(void)
>> u32 val = 0;
>>
>> if (cpu_is_omap24xx()) {
>> - val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
>> + val = omap_control_status_read();
>> } else if (soc_is_am33xx()) {
>> - val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
>> + val = omap_control_status_read();
>> } else if (cpu_is_omap34xx()) {
>> - val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
>> + val = omap_control_status_read();
>> } else if (cpu_is_omap44xx()) {
>> - val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
>> + val = omap_control_status_read();
>
> Isn't it better to merge now identical code into one *if*?
Good point.
>
> WBR, Sergei
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" 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
* Re: [PATCH v4 3/4] OMAP2+: use control module mfd driver in omap_type
From: Sergei Shtylyov @ 2012-07-25 12:39 UTC (permalink / raw)
To: Konstantin Baydarov
Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, amit.kucheria,
Eduardo Valentin, balbi, linux-pm, linux-omap, linux-arm-kernel,
amit.kachhap
In-Reply-To: <500FD2EF.4010304@dev.rtsoft.ru>
Hello.
On 25-07-2012 15:05, Konstantin Baydarov wrote:
> OMAP system control module can be probed early, then
> omap_type is safe to use its APIs.
> TODO: add support for other omap versions
> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
> ---
> arch/arm/mach-omap2/id.c | 11 ++++++-----
> 1 files changed, 6 insertions(+), 5 deletions(-)
> diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
> index 40373db..8018cad 100644
> --- a/arch/arm/mach-omap2/id.c
> +++ b/arch/arm/mach-omap2/id.c
[...]
> @@ -43,15 +44,15 @@ int omap_type(void)
> u32 val = 0;
>
> if (cpu_is_omap24xx()) {
> - val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
> + val = omap_control_status_read();
> } else if (soc_is_am33xx()) {
> - val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
> + val = omap_control_status_read();
> } else if (cpu_is_omap34xx()) {
> - val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
> + val = omap_control_status_read();
> } else if (cpu_is_omap44xx()) {
> - val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
> + val = omap_control_status_read();
Isn't it better to merge now identical code into one *if*?
WBR, Sergei
^ permalink raw reply
* [PATCH RESEND v5 4/5] thermal: exynos: register the tmu sensor with the kernel thermal layer
From: Amit Daniel Kachhap @ 2012-07-25 11:21 UTC (permalink / raw)
To: linux-pm, lenb
Cc: linux-kernel, linux-acpi, amit.kachhap, Donggeun Kim, SangWook Ju,
Durgadoss, Jean Delvare
In-Reply-To: <1342177825-19006-5-git-send-email-amit.kachhap@linaro.org>
This code added creates a link between temperature sensors, linux thermal
framework and cooling devices for samsung exynos platform. This layer
monitors the temperature from the sensor and informs the generic thermal
layer to take the necessary cooling action.
[akpm@linux-foundation.org: fix comment layout]
Signed-off-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
Cc: Donggeun Kim <dg77.kim@samsung.com>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: SangWook Ju <sw.ju@samsung.com>
Cc: Durgadoss <durgadoss.r@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Resending this patch to take care of a new parameter in
thermal_zone_device_register API.
drivers/thermal/exynos_thermal.c | 344 +++++++++++++++++++++++++-
include/linux/platform_data/exynos_thermal.h | 6 +
2 files changed, 348 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index fe4c81e..9ef8c37 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -35,6 +35,9 @@
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/platform_data/exynos_thermal.h>
+#include <linux/thermal.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
#include <linux/of.h>
#include <plat/cpu.h>
@@ -95,6 +98,7 @@
#define ACTIVE_INTERVAL 500
#define IDLE_INTERVAL 10000
+#define MCELSIUS 1000
/* CPU Zone information */
#define PANIC_ZONE 4
@@ -105,6 +109,8 @@
#define GET_ZONE(trip) (trip + 2)
#define GET_TRIP(zone) (zone - 2)
+#define EXYNOS_ZONE_COUNT 3
+
struct exynos_tmu_data {
struct exynos_tmu_platform_data *pdata;
struct resource *mem;
@@ -117,6 +123,309 @@ struct exynos_tmu_data {
u8 temp_error1, temp_error2;
};
+struct thermal_trip_point_conf {
+ int trip_val[MAX_TRIP_COUNT];
+ int trip_count;
+};
+
+struct thermal_cooling_conf {
+ struct freq_clip_table freq_data[MAX_TRIP_COUNT];
+ int freq_clip_count;
+};
+
+struct thermal_sensor_conf {
+ char name[SENSOR_NAME_LEN];
+ int (*read_temperature)(void *data);
+ struct thermal_trip_point_conf trip_data;
+ struct thermal_cooling_conf cooling_data;
+ void *private_data;
+};
+
+struct exynos_thermal_zone {
+ enum thermal_device_mode mode;
+ struct thermal_zone_device *therm_dev;
+ struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
+ unsigned int cool_dev_size;
+ struct platform_device *exynos4_dev;
+ struct thermal_sensor_conf *sensor_conf;
+};
+
+static struct exynos_thermal_zone *th_zone;
+static void exynos_unregister_thermal(void);
+static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+
+/* Get mode callback functions for thermal zone */
+static int exynos_get_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode *mode)
+{
+ if (th_zone)
+ *mode = th_zone->mode;
+ return 0;
+}
+
+/* Set mode callback functions for thermal zone */
+static int exynos_set_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode mode)
+{
+ if (!th_zone->therm_dev) {
+ pr_notice("thermal zone not registered\n");
+ return 0;
+ }
+
+ mutex_lock(&th_zone->therm_dev->lock);
+
+ if (mode == THERMAL_DEVICE_ENABLED)
+ th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+ else
+ th_zone->therm_dev->polling_delay = 0;
+
+ mutex_unlock(&th_zone->therm_dev->lock);
+
+ th_zone->mode = mode;
+ thermal_zone_device_update(th_zone->therm_dev);
+ pr_info("thermal polling set for duration=%d msec\n",
+ th_zone->therm_dev->polling_delay);
+ return 0;
+}
+
+/*
+ * This function may be called from interrupt based temperature sensor
+ * when threshold is changed.
+ */
+static void exynos_report_trigger(void)
+{
+ unsigned int i;
+ char data[10];
+ char *envp[] = { data, NULL };
+
+ if (!th_zone || !th_zone->therm_dev)
+ return;
+
+ thermal_zone_device_update(th_zone->therm_dev);
+
+ mutex_lock(&th_zone->therm_dev->lock);
+ /* Find the level for which trip happened */
+ for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
+ if (th_zone->therm_dev->last_temperature <
+ th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
+ break;
+ }
+
+ if (th_zone->mode == THERMAL_DEVICE_ENABLED) {
+ if (i > 0)
+ th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
+ else
+ th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+ }
+
+ snprintf(data, sizeof(data), "%u", i);
+ kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
+ mutex_unlock(&th_zone->therm_dev->lock);
+}
+
+/* Get trip type callback functions for thermal zone */
+static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+ enum thermal_trip_type *type)
+{
+ switch (GET_ZONE(trip)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ *type = THERMAL_TRIP_ACTIVE;
+ break;
+ case PANIC_ZONE:
+ *type = THERMAL_TRIP_CRITICAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* Get trip temperature callback functions for thermal zone */
+static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+ unsigned long *temp)
+{
+ if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+ return -EINVAL;
+
+ *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+ /* convert the temperature into millicelsius */
+ *temp = *temp * MCELSIUS;
+
+ return 0;
+}
+
+/* Get critical temperature callback functions for thermal zone */
+static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ int ret;
+ /* Panic zone */
+ ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+ return ret;
+}
+
+/* Bind callback functions for thermal zone */
+static int exynos_bind(struct thermal_zone_device *thermal,
+ struct thermal_cooling_device *cdev)
+{
+ int ret = 0, i;
+
+ /* find the cooling device registered*/
+ for (i = 0; i < th_zone->cool_dev_size; i++)
+ if (cdev == th_zone->cool_dev[i])
+ break;
+
+ /* No matching cooling device */
+ if (i == th_zone->cool_dev_size)
+ return 0;
+
+ switch (GET_ZONE(i)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ if (thermal_zone_bind_cooling_device(thermal, i, cdev)) {
+ pr_err("error binding cooling dev inst 0\n");
+ ret = -EINVAL;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Unbind callback functions for thermal zone */
+static int exynos_unbind(struct thermal_zone_device *thermal,
+ struct thermal_cooling_device *cdev)
+{
+ int ret = 0, i;
+
+ /* find the cooling device registered*/
+ for (i = 0; i < th_zone->cool_dev_size; i++)
+ if (cdev == th_zone->cool_dev[i])
+ break;
+
+ /* No matching cooling device */
+ if (i == th_zone->cool_dev_size)
+ return 0;
+
+ switch (GET_ZONE(i)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ if (thermal_zone_unbind_cooling_device(thermal, i, cdev)) {
+ pr_err("error unbinding cooling dev\n");
+ ret = -EINVAL;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+/* Get temperature callback functions for thermal zone */
+static int exynos_get_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ void *data;
+
+ if (!th_zone->sensor_conf) {
+ pr_info("Temperature sensor not initialised\n");
+ return -EINVAL;
+ }
+ data = th_zone->sensor_conf->private_data;
+ *temp = th_zone->sensor_conf->read_temperature(data);
+ /* convert the temperature into millicelsius */
+ *temp = *temp * MCELSIUS;
+ return 0;
+}
+
+/* Operation callback functions for thermal zone */
+static struct thermal_zone_device_ops const exynos_dev_ops = {
+ .bind = exynos_bind,
+ .unbind = exynos_unbind,
+ .get_temp = exynos_get_temp,
+ .get_mode = exynos_get_mode,
+ .set_mode = exynos_set_mode,
+ .get_trip_type = exynos_get_trip_type,
+ .get_trip_temp = exynos_get_trip_temp,
+ .get_crit_temp = exynos_get_crit_temp,
+};
+
+/* Register with the in-kernel thermal management */
+static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+{
+ int ret, count, tab_size;
+ struct freq_clip_table *tab_ptr, *clip_data;
+
+ if (!sensor_conf || !sensor_conf->read_temperature) {
+ pr_err("Temperature sensor not initialised\n");
+ return -EINVAL;
+ }
+
+ th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+ if (!th_zone)
+ return -ENOMEM;
+
+ th_zone->sensor_conf = sensor_conf;
+
+ tab_ptr = (struct freq_clip_table *)sensor_conf->cooling_data.freq_data;
+ tab_size = sensor_conf->cooling_data.freq_clip_count;
+
+ /* Register the cpufreq cooling device */
+ for (count = 0; count < tab_size; count++) {
+ clip_data = (struct freq_clip_table *)&(tab_ptr[count]);
+ clip_data->mask_val = cpumask_of(0);
+ th_zone->cool_dev[count] = cpufreq_cooling_register(
+ clip_data, 1);
+ if (IS_ERR(th_zone->cool_dev[count])) {
+ pr_err("Failed to register cpufreq cooling device\n");
+ ret = -EINVAL;
+ th_zone->cool_dev_size = count;
+ goto err_unregister;
+ }
+ }
+ th_zone->cool_dev_size = count;
+
+ th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+ EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, 0, 0, 0,
+ IDLE_INTERVAL);
+
+ if (IS_ERR(th_zone->therm_dev)) {
+ pr_err("Failed to register thermal zone device\n");
+ ret = -EINVAL;
+ goto err_unregister;
+ }
+ th_zone->mode = THERMAL_DEVICE_ENABLED;
+
+ pr_info("Exynos: Kernel Thermal management registered\n");
+
+ return 0;
+
+err_unregister:
+ exynos_unregister_thermal();
+ return ret;
+}
+
+/* Un-Register with the in-kernel thermal management */
+static void exynos_unregister_thermal(void)
+{
+ int i;
+
+ for (i = 0; i < th_zone->cool_dev_size; i++) {
+ if (th_zone && th_zone->cool_dev[i])
+ cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+ }
+
+ if (th_zone && th_zone->therm_dev)
+ thermal_zone_device_unregister(th_zone->therm_dev);
+
+ kfree(th_zone);
+
+ pr_info("Exynos: Kernel Thermal management unregistered\n");
+}
+
/*
* TMU treats temperature as a mapped temperature code.
* The temperature is converted differently depending on the calibration type.
@@ -337,6 +646,7 @@ static void exynos_tmu_work(struct work_struct *work)
clk_disable(data->clk);
mutex_unlock(&data->lock);
+ exynos_report_trigger();
enable_irq(data->irq);
}
@@ -349,12 +659,16 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
return IRQ_HANDLED;
}
-
+static struct thermal_sensor_conf exynos_sensor_conf = {
+ .name = "exynos-therm",
+ .read_temperature = (int (*)(void *))exynos_tmu_read,
+}
+;
static int __devinit exynos_tmu_probe(struct platform_device *pdev)
{
struct exynos_tmu_data *data;
struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
- int ret;
+ int ret, i;
if (!pdata) {
dev_err(&pdev->dev, "No platform init data supplied.\n");
@@ -432,6 +746,30 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
exynos_tmu_control(pdev, true);
+ /* Register the sensor with thermal management interface */
+ (&exynos_sensor_conf)->private_data = data;
+ exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
+ pdata->trigger_level1_en + pdata->trigger_level2_en +
+ pdata->trigger_level3_en;
+
+ for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
+ exynos_sensor_conf.trip_data.trip_val[i] =
+ pdata->threshold + pdata->trigger_levels[i];
+
+ exynos_sensor_conf.cooling_data.freq_clip_count =
+ pdata->freq_tab_count;
+ for (i = 0; i < pdata->freq_tab_count; i++) {
+ exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
+ pdata->freq_tab[i].freq_clip_max;
+ exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
+ pdata->freq_tab[i].temp_level;
+ }
+
+ ret = exynos_register_thermal(&exynos_sensor_conf);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register thermal interface\n");
+ goto err_clk;
+ }
return 0;
err_clk:
platform_set_drvdata(pdev, NULL);
@@ -454,6 +792,8 @@ static int __devexit exynos_tmu_remove(struct platform_device *pdev)
exynos_tmu_control(pdev, false);
+ exynos_unregister_thermal();
+
clk_put(data->clk);
free_irq(data->irq, data);
diff --git a/include/linux/platform_data/exynos_thermal.h b/include/linux/platform_data/exynos_thermal.h
index c980af6..858eaca 100644
--- a/include/linux/platform_data/exynos_thermal.h
+++ b/include/linux/platform_data/exynos_thermal.h
@@ -21,6 +21,7 @@
#ifndef _LINUX_EXYNOS_THERMAL_H
#define _LINUX_EXYNOS_THERMAL_H
+#include <linux/cpu_cooling.h>
enum calibration_type {
TYPE_ONE_POINT_TRIMMING,
@@ -72,6 +73,9 @@ enum soc_type {
* @type: determines the type of SOC
* @efuse_value: platform defined fuse value
* @cal_type: calibration type for temperature
+ * @freq_clip_table: Table representing frequency reduction percentage.
+ * @freq_tab_count: Count of the above table as frequency reduction may
+ * applicable to only some of the trigger levels.
*
* This structure is required for configuration of exynos_tmu driver.
*/
@@ -90,5 +94,7 @@ struct exynos_tmu_platform_data {
enum calibration_type cal_type;
enum soc_type type;
+ struct freq_clip_table freq_tab[4];
+ unsigned int freq_tab_count;
};
#endif /* _LINUX_EXYNOS_THERMAL_H */
--
1.7.1
^ permalink raw reply related
* Re: [PATCH v4 1/4] ARM: OMAP4: Remove un-used control module headers and defines.
From: Konstantin Baydarov @ 2012-07-25 11:17 UTC (permalink / raw)
To: balbi
Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, amit.kucheria,
linux-pm, linux-arm-kernel, linux-omap, amit.kachhap,
Eduardo Valentin
In-Reply-To: <20120725110635.GE16794@arwen.pp.htv.fi>
Hi, Balbi.
On 07/25/2012 03:06 PM, Felipe Balbi wrote:
> Hi,
>
> On Wed, Jul 25, 2012 at 03:05:13PM +0400, Konstantin Baydarov wrote:
>> Most of the OMAP4 control module register defines are not used and
>> can be removed. Keep only needed defines and move them to common
>> control module header just like other OMAP versions.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
>> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
> Wasn't this one authored by Santosh ?? Where's his From: Santosh
> Shilimkar ???
I hit "edit as new" when I sent patches through thunderbird, I'll fix in the next series.
BR,
Konstantin Baydarov.
>
^ permalink raw reply
* RE: [linux-pm] [PATCH 50/52] Thermal: Make Thermal trip points writeable
From: R, Durgadoss @ 2012-07-25 11:15 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown, Zhang, Rui
Cc: linux-acpi@vger.kernel.org, linux-pm@lists.linux-foundation.org,
Durgadoss R, linux-kernel@vger.kernel.org, Brown, Len
In-Reply-To: <201207251313.11061.rjw@sisk.pl>
Hi Rafael,
> -----Original Message-----
> From: linux-pm-bounces@lists.linux-foundation.org [mailto:linux-pm-
> bounces@lists.linux-foundation.org] On Behalf Of Rafael J. Wysocki
> Sent: Wednesday, July 25, 2012 4:43 PM
> To: Len Brown; Zhang, Rui
> Cc: linux-acpi@vger.kernel.org; linux-pm@lists.linux-foundation.org; Durgadoss
> R; linux-kernel@vger.kernel.org; Brown, Len
> Subject: Re: [linux-pm] [PATCH 50/52] Thermal: Make Thermal trip points
> writeable
>
> On Wednesday, July 25, 2012, Len Brown wrote:
> > From: Durgadoss R <dugardoss.r@intel.com>
> >
> > Some of the thermal drivers using the Generic Thermal Framework
> > require (all/some) trip points to be writeable. This patch makes
> > the trip point temperatures writeable on a per-trip point basis,
> > and modifies the required function call in thermal.c. This patch
> > also updates the Documentation to reflect the new change.
> >
> > Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > Signed-off-by: Len Brown <len.brown@intel.com>
>
> There was a broken build report related to this patch (or a previous version
> of it):
>
> http://marc.info/?l=linux-kernel&m=134294496105083&w=2
>
> Do I think correctly that it has been fixed already?
Yes you are right. It has been fixed in this patch.
Thanks,
Durga
^ permalink raw reply
* Re: [PATCH v4 1/4] ARM: OMAP4: Remove un-used control module headers and defines.
From: Felipe Balbi @ 2012-07-25 11:15 UTC (permalink / raw)
To: Konstantin Baydarov
Cc: balbi, kishon, amit.kucheria, linux-pm, linux-omap,
linux-arm-kernel
In-Reply-To: <500FD5DC.7010002@dev.rtsoft.ru>
[-- Attachment #1: Type: text/plain, Size: 886 bytes --]
Hi,
On Wed, Jul 25, 2012 at 03:17:48PM +0400, Konstantin Baydarov wrote:
> Hi, Balbi.
>
> On 07/25/2012 03:06 PM, Felipe Balbi wrote:
> > Hi,
> >
> > On Wed, Jul 25, 2012 at 03:05:13PM +0400, Konstantin Baydarov wrote:
> >> Most of the OMAP4 control module register defines are not used and
> >> can be removed. Keep only needed defines and move them to common
> >> control module header just like other OMAP versions.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> >> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
> > Wasn't this one authored by Santosh ?? Where's his From: Santosh
> > Shilimkar ???
>
> I hit "edit as new" when I sent patches through thunderbird, I'll fix in the next series.
git send-email would help avoiding those ;-)
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 50/52] Thermal: Make Thermal trip points writeable
From: Rafael J. Wysocki @ 2012-07-25 11:13 UTC (permalink / raw)
To: Len Brown, Zhang Rui
Cc: linux-acpi, linux-pm, linux-kernel, Durgadoss R, Len Brown
In-Reply-To: <c56f5c0342dfee11a1a13d2f5bb7618de5b17590.1343187618.git.len.brown@intel.com>
On Wednesday, July 25, 2012, Len Brown wrote:
> From: Durgadoss R <dugardoss.r@intel.com>
>
> Some of the thermal drivers using the Generic Thermal Framework
> require (all/some) trip points to be writeable. This patch makes
> the trip point temperatures writeable on a per-trip point basis,
> and modifies the required function call in thermal.c. This patch
> also updates the Documentation to reflect the new change.
>
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> Signed-off-by: Len Brown <len.brown@intel.com>
There was a broken build report related to this patch (or a previous version
of it):
http://marc.info/?l=linux-kernel&m=134294496105083&w=2
Do I think correctly that it has been fixed already?
Rafael
> ---
> Documentation/thermal/sysfs-api.txt | 4 +-
> drivers/acpi/thermal.c | 4 +-
> drivers/platform/x86/acerhdf.c | 2 +-
> drivers/platform/x86/intel_mid_thermal.c | 2 +-
> drivers/thermal/spear_thermal.c | 2 +-
> drivers/thermal/thermal_sys.c | 145 +++++++++++++++++++++----------
> include/linux/thermal.h | 15 +++-
> 7 files changed, 121 insertions(+), 53 deletions(-)
>
> diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
> index 1733ab9..4c10593 100644
> --- a/Documentation/thermal/sysfs-api.txt
> +++ b/Documentation/thermal/sysfs-api.txt
> @@ -32,7 +32,8 @@ temperature) and throttle appropriate devices.
>
> 1.1 thermal zone device interface
> 1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name,
> - int trips, void *devdata, struct thermal_zone_device_ops *ops)
> + int trips, int mask, void *devdata,
> + struct thermal_zone_device_ops *ops)
>
> This interface function adds a new thermal zone device (sensor) to
> /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
> @@ -40,6 +41,7 @@ temperature) and throttle appropriate devices.
>
> name: the thermal zone name.
> trips: the total number of trip points this thermal zone supports.
> + mask: Bit string: If 'n'th bit is set, then trip point 'n' is writeable.
> devdata: device private data
> ops: thermal zone device call-backs.
> .bind: bind the thermal zone device with a thermal cooling device.
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 7dbebea..2107d1b 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -845,7 +845,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
>
> if (tz->trips.passive.flags.valid)
> tz->thermal_zone =
> - thermal_zone_device_register("acpitz", trips, tz,
> + thermal_zone_device_register("acpitz", trips, 0, tz,
> &acpi_thermal_zone_ops,
> tz->trips.passive.tc1,
> tz->trips.passive.tc2,
> @@ -853,7 +853,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
> tz->polling_frequency*100);
> else
> tz->thermal_zone =
> - thermal_zone_device_register("acpitz", trips, tz,
> + thermal_zone_device_register("acpitz", trips, 0, tz,
> &acpi_thermal_zone_ops,
> 0, 0, 0,
> tz->polling_frequency*100);
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index 2fd9d36..39abb15 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -660,7 +660,7 @@ static int acerhdf_register_thermal(void)
> if (IS_ERR(cl_dev))
> return -EINVAL;
>
> - thz_dev = thermal_zone_device_register("acerhdf", 1, NULL,
> + thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> &acerhdf_dev_ops, 0, 0, 0,
> (kernelmode) ? interval*1000 : 0);
> if (IS_ERR(thz_dev))
> diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
> index 5ae9cd9..2b2c212 100644
> --- a/drivers/platform/x86/intel_mid_thermal.c
> +++ b/drivers/platform/x86/intel_mid_thermal.c
> @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
> goto err;
> }
> pinfo->tzd[i] = thermal_zone_device_register(name[i],
> - 0, td_info, &tzd_ops, 0, 0, 0, 0);
> + 0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> if (IS_ERR(pinfo->tzd[i])) {
> kfree(td_info);
> ret = PTR_ERR(pinfo->tzd[i]);
> diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
> index c2e32df..69a55d4 100644
> --- a/drivers/thermal/spear_thermal.c
> +++ b/drivers/thermal/spear_thermal.c
> @@ -147,7 +147,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
> stdev->flags = pdata->thermal_flags;
> writel_relaxed(stdev->flags, stdev->thermal_base);
>
> - spear_thermal = thermal_zone_device_register("spear_thermal", 0,
> + spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
> stdev, &ops, 0, 0, 0, 0);
> if (IS_ERR(spear_thermal)) {
> dev_err(&pdev->dev, "thermal zone device is NULL\n");
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 022bacb..5feb335 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -196,6 +196,28 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
> }
>
> static ssize_t
> +trip_point_temp_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct thermal_zone_device *tz = to_thermal_zone(dev);
> + int trip, ret;
> + unsigned long temperature;
> +
> + if (!tz->ops->set_trip_temp)
> + return -EPERM;
> +
> + if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
> + return -EINVAL;
> +
> + if (kstrtoul(buf, 10, &temperature))
> + return -EINVAL;
> +
> + ret = tz->ops->set_trip_temp(tz, trip, temperature);
> +
> + return ret ? ret : count;
> +}
> +
> +static ssize_t
> trip_point_temp_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> {
> @@ -283,33 +305,6 @@ static DEVICE_ATTR(temp, 0444, temp_show, NULL);
> static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
> static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
>
> -static struct device_attribute trip_point_attrs[] = {
> - __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL),
> - __ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL),
> - __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
> -};
> -
> /* sys I/F for cooling device */
> #define to_cooling_device(_dev) \
> container_of(_dev, struct thermal_cooling_device, device)
> @@ -1089,9 +1084,81 @@ leave:
> EXPORT_SYMBOL(thermal_zone_device_update);
>
> /**
> + * create_trip_attrs - create attributes for trip points
> + * @tz: the thermal zone device
> + * @mask: Writeable trip point bitmap.
> + */
> +static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
> +{
> + int indx;
> +
> + tz->trip_type_attrs =
> + kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
> + if (!tz->trip_type_attrs)
> + return -ENOMEM;
> +
> + tz->trip_temp_attrs =
> + kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
> + if (!tz->trip_temp_attrs) {
> + kfree(tz->trip_type_attrs);
> + return -ENOMEM;
> + }
> +
> + for (indx = 0; indx < tz->trips; indx++) {
> +
> + /* create trip type attribute */
> + snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
> + "trip_point_%d_type", indx);
> +
> + sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
> + tz->trip_type_attrs[indx].attr.attr.name =
> + tz->trip_type_attrs[indx].name;
> + tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
> + tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
> +
> + device_create_file(&tz->device,
> + &tz->trip_type_attrs[indx].attr);
> +
> + /* create trip temp attribute */
> + snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
> + "trip_point_%d_temp", indx);
> +
> + sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
> + tz->trip_temp_attrs[indx].attr.attr.name =
> + tz->trip_temp_attrs[indx].name;
> + tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
> + tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
> + if (mask & (1 << indx)) {
> + tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
> + tz->trip_temp_attrs[indx].attr.store =
> + trip_point_temp_store;
> + }
> +
> + device_create_file(&tz->device,
> + &tz->trip_temp_attrs[indx].attr);
> + }
> + return 0;
> +}
> +
> +static void remove_trip_attrs(struct thermal_zone_device *tz)
> +{
> + int indx;
> +
> + for (indx = 0; indx < tz->trips; indx++) {
> + device_remove_file(&tz->device,
> + &tz->trip_type_attrs[indx].attr);
> + device_remove_file(&tz->device,
> + &tz->trip_temp_attrs[indx].attr);
> + }
> + kfree(tz->trip_type_attrs);
> + kfree(tz->trip_temp_attrs);
> +}
> +
> +/**
> * thermal_zone_device_register - register a new thermal zone device
> * @type: the thermal zone device type
> * @trips: the number of trip points the thermal zone support
> + * @mask: a bit string indicating the writeablility of trip points
> * @devdata: private device data
> * @ops: standard thermal zone device callbacks
> * @tc1: thermal coefficient 1 for passive calculations
> @@ -1107,7 +1174,7 @@ EXPORT_SYMBOL(thermal_zone_device_update);
> * section 11.1.5.1 of the ACPI specification 3.0.
> */
> struct thermal_zone_device *thermal_zone_device_register(char *type,
> - int trips, void *devdata,
> + int trips, int mask, void *devdata,
> const struct thermal_zone_device_ops *ops,
> int tc1, int tc2, int passive_delay, int polling_delay)
> {
> @@ -1121,7 +1188,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
> if (strlen(type) >= THERMAL_NAME_LENGTH)
> return ERR_PTR(-EINVAL);
>
> - if (trips > THERMAL_MAX_TRIPS || trips < 0)
> + if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
> return ERR_PTR(-EINVAL);
>
> if (!ops || !ops->get_temp)
> @@ -1175,15 +1242,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
> goto unregister;
> }
>
> + result = create_trip_attrs(tz, mask);
> + if (result)
> + goto unregister;
> +
> for (count = 0; count < trips; count++) {
> - result = device_create_file(&tz->device,
> - &trip_point_attrs[count * 2]);
> - if (result)
> - break;
> - result = device_create_file(&tz->device,
> - &trip_point_attrs[count * 2 + 1]);
> - if (result)
> - goto unregister;
> tz->ops->get_trip_type(tz, count, &trip_type);
> if (trip_type == THERMAL_TRIP_PASSIVE)
> passive = 1;
> @@ -1232,7 +1295,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> {
> struct thermal_cooling_device *cdev;
> struct thermal_zone_device *pos = NULL;
> - int count;
>
> if (!tz)
> return;
> @@ -1259,13 +1321,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
> device_remove_file(&tz->device, &dev_attr_temp);
> if (tz->ops->get_mode)
> device_remove_file(&tz->device, &dev_attr_mode);
> + remove_trip_attrs(tz);
>
> - for (count = 0; count < tz->trips; count++) {
> - device_remove_file(&tz->device,
> - &trip_point_attrs[count * 2]);
> - device_remove_file(&tz->device,
> - &trip_point_attrs[count * 2 + 1]);
> - }
> thermal_remove_hwmon_sysfs(tz);
> release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
> idr_destroy(&tz->idr);
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 796f1ff..6eaf914 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -58,6 +58,8 @@ struct thermal_zone_device_ops {
> enum thermal_trip_type *);
> int (*get_trip_temp) (struct thermal_zone_device *, int,
> unsigned long *);
> + int (*set_trip_temp) (struct thermal_zone_device *, int,
> + unsigned long);
> int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
> int (*notify) (struct thermal_zone_device *, int,
> enum thermal_trip_type);
> @@ -85,10 +87,17 @@ struct thermal_cooling_device {
> ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
> #define CELSIUS_TO_KELVIN(t) ((t)*10+2732)
>
> +struct thermal_attr {
> + struct device_attribute attr;
> + char name[THERMAL_NAME_LENGTH];
> +};
> +
> struct thermal_zone_device {
> int id;
> char type[THERMAL_NAME_LENGTH];
> struct device device;
> + struct thermal_attr *trip_temp_attrs;
> + struct thermal_attr *trip_type_attrs;
> void *devdata;
> int trips;
> int tc1;
> @@ -137,9 +146,9 @@ enum {
> };
> #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
>
> -struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
> - const struct thermal_zone_device_ops *, int tc1, int tc2,
> - int passive_freq, int polling_freq);
> +struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
> + void *, const struct thermal_zone_device_ops *, int tc1,
> + int tc2, int passive_freq, int polling_freq);
> void thermal_zone_device_unregister(struct thermal_zone_device *);
>
> int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
>
^ permalink raw reply
* Re: [PATCH v4 2/4] mfd: omap: control: core system control driver
From: Felipe Balbi @ 2012-07-25 11:07 UTC (permalink / raw)
To: Konstantin Baydarov
Cc: balbi, kishon, amit.kucheria, linux-pm, linux-omap,
linux-arm-kernel
In-Reply-To: <500FD2EC.7060208@dev.rtsoft.ru>
[-- Attachment #1: Type: text/plain, Size: 891 bytes --]
Hi,
On Wed, Jul 25, 2012 at 03:05:16PM +0400, Konstantin Baydarov wrote:
> This patch introduces a MFD core device driver for
> OMAP system control module.
>
> The control module allows software control of
> various static modes supported by the device. It is
> composed of two control submodules: general control
> module and device (padconfiguration) control
> module.
>
> Device driver is probed with postcore_initcall.
> Control module register CONTROL_STATUS that is needed
> by omap_type() is early mapped by postcore_initcall_sync.
>
> Signed-off-by: J Keerthy <j-keerthy@ti.com>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
I believe this and the next 3 were authored by Eduardo. Also missing his
From tag.
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v4 1/4] ARM: OMAP4: Remove un-used control module headers and defines.
From: Felipe Balbi @ 2012-07-25 11:06 UTC (permalink / raw)
To: Konstantin Baydarov
Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, balbi,
amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
amit.kachhap, Eduardo Valentin
In-Reply-To: <500FD2E9.8050408@dev.rtsoft.ru>
[-- Attachment #1: Type: text/plain, Size: 560 bytes --]
Hi,
On Wed, Jul 25, 2012 at 03:05:13PM +0400, Konstantin Baydarov wrote:
> Most of the OMAP4 control module register defines are not used and
> can be removed. Keep only needed defines and move them to common
> control module header just like other OMAP versions.
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
Wasn't this one authored by Santosh ?? Where's his From: Santosh
Shilimkar ???
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox