Re: [PATCH v8 0/8] Consolidate cpuidle functionality

2012-03-20 Thread Deepthi Dharwar
On 03/21/2012 05:31 AM, Rafael J. Wysocki wrote:

 On Wednesday, March 21, 2012, Amit Kucheria wrote:
 On Wed, Mar 21, 2012 at 12:48 AM, Kevin Hilman khil...@ti.com wrote:
 Arnd Bergmann arnd.bergm...@linaro.org writes:

 On Tuesday 20 March 2012, Robert Lee wrote:
 This patch series moves various functionality duplicated in platform
 cpuidle drivers to the core cpuidle driver. Also, the platform irq
 disabling was removed as it appears that all calls into
 cpuidle_call_idle will have already called local_irq_disable().

 These changes have been pulled into linux-next.

 Len, Andrew, can a request be made for Linus to pull these changes?

 FWIW, Len seems to be rather inactive on the kernel mailing list right
 now and generally not very interested in anything outside of x86 and
 acpi. If he doesn't reply in the next few days and Andrew also isn't
 interested in handling these patches, I'd suggest you just send the pull
 request to Linus, with Len on Cc and explain that you tried to send
 them through him but gave up in the end.

 FWIW, I have not had good luck getting response for proposed core
 CPUidle changes either:

http://lkml.org/lkml/2011/9/19/374

 Maybe it's time that drivers/cpuidle gets a maintainer.  With lots of
 discussions of scheduler changes that affect load estimation, I suspect
 we're all going to have a bit of CPUidle work to do in the
 not-so-distant future.


 I don't mean to be piling on to Len here, but Daniel Lezcano too has a
 bunch of clean ups that didn't get any maintainer review for over two
 months. He has now refreshed them for 3.3 and is getting ready to send
 them out again. We (Linaro) expect to be spending a lot of time on
 cpuidle in the future and would be glad to help review, test and
 collect patches into a tree for Linus/Andrew to pull while we wait for
 Len to respond or another maintainer to emerge.
 
 Well, I discussed that before with Arjan and he said he would maintain
 CPUidle if Len didn't have the time, but it seems he didn't expect that
 there would be a lot of work on it in the near future.
 
 So, I suggest that if neither Len nor Arjan reappear shortly, people can
 send CPUidle patches to me.
 
 Thanks,
 Rafael
 


I'll be glad to assist you in this.

Cheers,
Deepthi

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 1/9] cpuidle: Add common time keeping and irq enabling

2012-02-29 Thread Deepthi Dharwar
Hi Rob,


On 02/29/2012 08:41 AM, Robert Lee wrote:

 Make necessary changes to implement time keeping and irq enabling
 in the core cpuidle code.  This will allow the removal of these
 functionalities from various platform cpuidle implementations whose
 timekeeping and irq enabling follows the form in this common code.
 
 Signed-off-by: Robert Lee rob@linaro.org
 ---
  arch/arm/include/asm/cpuidle.h |   14 ++
  drivers/cpuidle/cpuidle.c  |   90 
 
  include/linux/cpuidle.h|   13 ++
  3 files changed, 99 insertions(+), 18 deletions(-)
  create mode 100644 arch/arm/include/asm/cpuidle.h
 
 diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
 new file mode 100644
 index 000..1d2075b
 --- /dev/null
 +++ b/arch/arm/include/asm/cpuidle.h
 @@ -0,0 +1,14 @@
 +#ifndef __ASM_ARM_CPUIDLE_H
 +#define __ASM_ARM_CPUIDLE_H
 +
 +/* Common ARM WFI state */
 +#define CPUIDLE_ARM_WFI_STATE {\
 + .enter  = cpuidle_simple_enter,\
 + .exit_latency   = 1,\
 + .target_residency   = 1,\
 + .flags  = CPUIDLE_FLAG_TIME_VALID,\
 + .name   = WFI,\
 + .desc   = ARM core clock gating (WFI),\
 +}
 +
 +#endif
 diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
 index 59f4261..00b02f5 100644
 --- a/drivers/cpuidle/cpuidle.c
 +++ b/drivers/cpuidle/cpuidle.c
 @@ -18,6 +18,7 @@
  #include linux/ktime.h
  #include linux/hrtimer.h
  #include linux/module.h
 +#include asm/proc-fns.h
  #include trace/events/power.h
 
  #include cpuidle.h
 @@ -53,6 +54,24 @@ static void cpuidle_kick_cpus(void) {}
 
  static int __cpuidle_register_device(struct cpuidle_device *dev);
 
 +static inline int cpuidle_enter(struct cpuidle_device *dev,
 + struct cpuidle_driver *drv, int index)
 +{
 + struct cpuidle_state *target_state = drv-states[index];
 + return target_state-enter(dev, drv, index);
 +}
 +
 +static inline int cpuidle_enter_tk(struct cpuidle_device *dev,
 +struct cpuidle_driver *drv, int index)
 +{
 + return cpuidle_wrap_enter(dev, drv, index, cpuidle_enter);
 +}
 +
 +typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev,
 +struct cpuidle_driver *drv, int index);
 +
 +static cpuidle_enter_t cpuidle_enter_ops;
 +
  /**
   * cpuidle_idle_call - the main idle loop
   *
 @@ -63,7 +82,6 @@ int cpuidle_idle_call(void)
  {
   struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
   struct cpuidle_driver *drv = cpuidle_get_driver();
 - struct cpuidle_state *target_state;
   int next_state, entered_state;
 
   if (off)
 @@ -92,12 +110,10 @@ int cpuidle_idle_call(void)
   return 0;
   }
 
 - target_state = drv-states[next_state];
 -
   trace_power_start(POWER_CSTATE, next_state, dev-cpu);
   trace_cpu_idle(next_state, dev-cpu);
 
 - entered_state = target_state-enter(dev, drv, next_state);
 + entered_state = cpuidle_enter_ops(dev, drv, next_state);
 
   trace_power_end(dev-cpu);
   trace_cpu_idle(PWR_EVENT_EXIT, dev-cpu);
 @@ -110,7 +126,8 @@ int cpuidle_idle_call(void)
   dev-states_usage[entered_state].time +=
   (unsigned long long)dev-last_residency;
   dev-states_usage[entered_state].usage++;
 - }
 + } else
 + dev-last_residency = 0;
 
   /* give the governor an opportunity to reflect on the outcome */
   if (cpuidle_curr_governor-reflect)
 @@ -164,20 +181,29 @@ void cpuidle_resume_and_unlock(void)
 
  EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
 
 -#ifdef CONFIG_ARCH_HAS_CPU_RELAX
 -static int poll_idle(struct cpuidle_device *dev,
 - struct cpuidle_driver *drv, int index)
 +/**
 + * cpuidle_wrap_enter - performs timekeeping and irqen around enter function
 + * @dev: pointer to a valid cpuidle_device object
 + * @drv: pointer to a valid cpuidle_driver object
 + * @index: index of the target cpuidle state.
 + */
 +int cpuidle_wrap_enter(struct cpuidle_device *dev,
 + struct cpuidle_driver *drv, int index,
 + int (*enter)(struct cpuidle_device *dev,
 + struct cpuidle_driver *drv, int index))
  {
 - ktime_t t1, t2;
 + ktime_t time_start, time_end;
   s64 diff;
 
 - t1 = ktime_get();
 + time_start = ktime_get();
 +
 + index = enter(dev, drv, index);
 +
 + time_end = ktime_get();
 +
   local_irq_enable();
 - while (!need_resched())
 - cpu_relax();
 
 - t2 = ktime_get();
 - diff = ktime_to_us(ktime_sub(t2, t1));
 + diff = ktime_to_us(ktime_sub(time_end, time_start));
   if (diff  INT_MAX)
   diff = INT_MAX;
 
 @@ -186,6 +212,31 @@ static int poll_idle(struct cpuidle_device *dev,
   return index;
  }
 
 +int 

Re: [PATCH v7 1/9] cpuidle: Add common time keeping and irq enabling

2012-02-29 Thread Deepthi Dharwar
,
 + struct cpuidle_driver *drv, int index,
 + int (*enter)(struct cpuidle_device *dev,
 + struct cpuidle_driver *drv, int index))
 +{ return -ENODEV; }
 
  #endif
 


For the generic cpuidle changes
Reviewed-by: Deepthi Dharwar deep...@linux.vnet.ibm.com

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] CPUIdle: Reevaluate C-states under CPU load to favor deeper C-states

2011-11-09 Thread Deepthi Dharwar
On Saturday 05 November 2011 03:16 AM, Kevin Hilman wrote:
 ping v2
 
 Kevin Hilman khil...@ti.com writes:
 
 From: Nicole Chalhoub n-chalh...@ti.com

 While there is CPU load, program a C-state specific one-shot timer in
 order to give CPUidle another opportunity to pick a deeper C-state
 instead of spending potentially long idle times in a shallow C-state.

 Long winded version:
 When going idle with a high load average, CPUidle menu governor will
 decide to pick a shallow C-state since one of the guiding principles
 of the menu governor is The busier the system, the less impact of
 C-states is acceptable (taken from cpuidle/governors/menu.c.)
 That makes perfect sense.

 However, there are missed power-saving opportunities for bursty
 workloads with long idle times (e.g. MP3 playback.)  Given such a
 workload, because of the load average, CPUidle tends to pick a shallow
 C-state.  Because we also go tickless, this shallow C-state is used
 for the duration of the idle period. If the idle period is long, a
 deeper C state would've resulted in better power savings.
 This patch provides an additional opportuntity for CPUidle to pick a
 deeper C-state by programming a timer (with a C-state specific timeout)
 such that the CPUidle governor will have another opportunity to pick a
 deeper C-state.

 Adding this timer for C-state reevaluation improved the load estimation
 on our ARM/OMAP4 platform and increased the time spent in deep C-states
 (~50% of idle time in C-states deeper than C1).  A power saving of ~10mA
 at battery level is observed during MP3 playback on OMAP4/Blaze board.

 Signed-off-by: Nicole Chalhoub n-chalh...@ti.com
 Signed-off-by: Kevin Hilman khil...@ti.com
 ---
  drivers/cpuidle/cpuidle.c|   28 +-
  drivers/cpuidle/governors/menu.c |   39 
 -
  include/linux/cpuidle.h  |4 +++
  3 files changed, 63 insertions(+), 8 deletions(-)

 diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
 index 1994885..4b1ac0c 100644
 --- a/drivers/cpuidle/cpuidle.c
 +++ b/drivers/cpuidle/cpuidle.c
 @@ -92,13 +92,33 @@ static void cpuidle_idle_call(void)
  target_state-time += (unsigned long long)dev-last_residency;
  target_state-usage++;
  
 -/* give the governor an opportunity to reflect on the outcome */
 -if (cpuidle_curr_governor-reflect)
 +hrtimer_cancel(dev-cstate_timer);
 +
 +/*
 + * Give the governor an opportunity to reflect on the outcome
 + * Do not take into account the wakeups due to the hrtimer, they
 + * should not impact the predicted idle time.
 + */
 +if ((!dev-hrtimer_expired)  cpuidle_curr_governor-reflect)
  cpuidle_curr_governor-reflect(dev);
  trace_power_end(0);
  }
  
  /**
 + * cstate_reassessment_timer - interrupt handler of the cstate hrtimer
 + * @handle: the expired hrtimer
 + */
 +static enum hrtimer_restart cstate_reassessment_timer(struct hrtimer 
 *handle)
 +{
 +struct cpuidle_device *data =
 +container_of(handle, struct cpuidle_device, cstate_timer);
 +
 +data-hrtimer_expired = 1;
 +
 +return HRTIMER_NORESTART;
 +}
 +
 +/**
   * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
   */
  void cpuidle_install_idle_handler(void)
 @@ -185,6 +205,10 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
  
  dev-enabled = 1;
  
 +dev-hrtimer_expired = 0;
 +hrtimer_init(dev-cstate_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 +dev-cstate_timer.function = cstate_reassessment_timer;
 +
  enabled_devices++;
  return 0;
  
 diff --git a/drivers/cpuidle/governors/menu.c 
 b/drivers/cpuidle/governors/menu.c
 index 1b12870..fd54584 100644
 --- a/drivers/cpuidle/governors/menu.c
 +++ b/drivers/cpuidle/governors/menu.c
 @@ -125,10 +125,21 @@ struct menu_device {
  #define LOAD_INT(x) ((x)  FSHIFT)
  #define LOAD_FRAC(x) LOAD_INT(((x)  (FIXED_1-1)) * 100)
  
 -static int get_loadavg(void)
 +static int get_loadavg(struct cpuidle_device *dev)
  {
 -unsigned long this = this_cpu_load();
 +unsigned long this;
  
 +/*
 + * this_cpu_load() returns the value of rq-load.weight
 + * at the previous scheduler tick and not the current value.
 + * If the timer expired, that means we are in idle,there
 + * are no more runnable processes in the current queue
 + * =return the current value of rq-load.weight which is 0.
 + */
 +if (dev-hrtimer_expired == 1)
 +return 0;
 +else
 +this = this_cpu_load();
  
  return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10;
  }
 @@ -166,13 +177,13 @@ static inline int which_bucket(unsigned int duration)
   * to be, the higher this multiplier, and thus the higher
   * the barrier to go to an expensive C state.
   */
 -static inline int performance_multiplier(void)
 +static inline int performance_multiplier(struct cpuidle_device *dev)
  {
  int mult = 1;
  
  /* for higher 

Re: [PATCH v9 2/4] cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev-prepare()

2011-10-31 Thread Deepthi Dharwar
On Friday 28 October 2011 07:54 PM, Arjan van de Ven wrote:
 
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 On 10/28/2011 3:50 AM, Deepthi Dharwar wrote:
 The cpuidle_device-prepare() mechanism causes updates to the
 cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE
 to tell the governor not to chose a state on a per-cpu basis at
 run-time. State demotion is now handled by the driver and it returns
 the actual state entered. Hence, this mechanism is not required.
 Also this removes per-cpu flags from cpuidle_state enabling
 it to be made global.

 
 having worked on some newer platforms
 this one is really still needed. doing this inside the actual states
 does not work,
 because if the deepest 3 states are invalid, the same (somewhat
 expensive) test would have to be done 3 times,
 and each of the states would have to fail before the 4th one gets chosen.
 that's just not going to work
 
 (in the state handler you can't know what other state to fall back to,
 and especially not how to enter such a fallback state)
 
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v2.0.17 (MingW32)
 
 iQEcBAEBAgAGBQJOqrsGAAoJEEHdSxh4DVnEu7EH/i5lEJctBAIubJOcZz/tvBFp
 XYmAe/HqNtSXeHOVsJkTf8y4ppE8487exF7xxMik4GRN0CZNCtkyMezqDVu+eDim
 O/UUbScsAc5cSY6mkjOFXLFup+mi1nkRUnAbxXEyTMhWwcbfr2OvcuO7l7TmATML
 hu87P3PVEafEop3q2+uWMc57fFxnNFfEDqRx6N9V+OJKV5dHrRYL4G4E01fYGFLo
 xTR0IW7nB15L0C29zk9uk/Dqow8SoJZA83c7p7AieP5zdntb6p7noIf03qmdp19f
 fulwMwembCHivo+pLO+jAMhKD1T6VYoCyiYW0LHrQ2E07fayBhFJCxlazgKFcl0=
 =FL6o
 -END PGP SIGNATURE-
 
Hi Arjan,

Thanks for the review. 

We retain the dev-prepare() routine and CPUIDLE_FLAG_IGNORE 
but still allow the dev-enter() to return index ? 
So by retaining it, transition to the idle states
would be much quicker in case one more states are invalid.

Also to note is that in the newer design, we have split the 
cpuidle_state structure. One global struct, cpuidle_states[] that
contains all the state related information including flags, and 
the other cpuidle_device that contain statistics and other data 
that are per-cpu basis. 
So the flags are not per cpu per state basis but 
maintained globally as per state basis. 

So if we have to enable CPUIDLE_FLAG_IGNORE flag in this 
current new design, then I am thinking if we needed to have this 
on a per-cpu basis. If so, then flags have to be moved into cpuidle_device 
struct rather than cpuidle_state struct. 

Is it a good idea to retain these flags as global (part of cpuidle_states) 
or make it per-cpu basis ? 

-Thanks
Deepthi   

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v9 0/4] cpuidle: Global registration of idle states with per-cpu statistics

2011-10-28 Thread Deepthi Dharwar
Version 6 of this patch series dated 22nd Sept 2011 was 
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com for OMAP specific parts.
Reviewed-by: Kevin Hilman khil...@ti.com
Tested-by: Jean Pihet j-pi...@ti.com

Hi Len, 
Can you please queue this series for the next mainline merge window by merging
it into your development tree and also linux-next for further testing.

I have also tested it by applying these patches on your ACPI tree hosted 
@github.

Thanks
-Deepthi

--

The following patch series implements global registration of cpuidle
states, and also has the necessary data structure changes to
accommodate the per-cpu writable members of the cpuidle_states
structure.

This patch series had been in discussion earlier and
following are the links to the previous discussions.

v8 -- https://lkml.org/lkml/2011/10/3/52
v7 -- https://lkml.org/lkml/2011/9/27/74 
v6 -- https://lkml.org/lkml/2011/9/22/58
v5 -- https://lkml.org/lkml/2011/6/6/259
v4 -- https://lkml.org/lkml/2011/4/28/312
v3 -- https://lkml.org/lkml/2011/2/8/73
v2 -- https://lkml.org/lkml/2011/1/13/98
v1 -- https://lkml.org/lkml/2011/3/22/161

Changes from previous version (v8):

   1. Rebased and tested on 3.1

Tests done:

1. Compile tested for ARM using the following configs: 
da8xx_omapl_defconfig,
kirkwood_defconfig, omap2plus_defconfig, at91rm9200_defconfig
  
2. Boot tested on x86 nehalem with multiple C-states for both intel_idle
and acpi_idle drivers.

3. Boot tested on T60p thinkpad that has T2600 cpu with multiple C-states. 
Also tested the case when there is dynamic changes in C-states 
AC - Battery Power switch.

Brief description of the patches:

Core change in this series is to split the cpuidle_device structure 
into two parts, i.e  global and per-cpu basis. 

The per-cpu pieces are mostly generic statistics that can be independent 
of current running driver. As a result of these changes, there is single 
copy of cpuidle_states structure and single registration done by one 
cpu. The low level driver is free to set per-cpu driver data on
each cpu if needed using the cpuidle_set_statedata() as the case
today. Only in very rare cases asymmetric C-states exist which can be 
handled within the cpuidle driver. Most architectures do not have 
asymmetric C-states.

First two patches in the series facilitate splitting of cpuidle_states
and cpuidle_device structure and next two patches do the actual split,
change the API's and make existing code follow the changed API.

[1/4] - Move the idle residency accounting part from cpuidle.c to
the respective low level drivers, so that the accounting can
be accurately maintained if the driver decides to demote the
chosen (suggested) by the governor.

[2/4] - removes the cpuidle_device()-prepare API since is is not
widely used and the only use case was to allow software
demotion using CPUIDLE_FLAG_IGNORE flag.  Both these
functions can be absorbed within the cpuidle back-end
driver ad hence deprecating the prepare routine and the
CPUIDLE_FLAG_IGNORE flag.

- Ref: https://lkml.org/lkml/2011/3/25/52

[3/4] - Splits the usage statistics (read/write) part out of
cpuidle_state structure, so that the states can become read
only and hence made global.

[4/4] - Most APIs will now need to pass pointer to both global
cpuidle_driver and per-cpu cpuidle_device structure.

 arch/arm/mach-at91/cpuidle.c  |   41 +++--
 arch/arm/mach-davinci/cpuidle.c   |   51 ---
 arch/arm/mach-exynos4/cpuidle.c   |   30 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   42 +++---
 arch/arm/mach-omap2/cpuidle34xx.c |  133 +++--
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   28 ++--
 drivers/acpi/processor_driver.c   |   20 ---
 drivers/acpi/processor_idle.c |  251 +++--
 drivers/cpuidle/cpuidle.c |   86 ---
 drivers/cpuidle/driver.c  |   25 +++
 drivers/cpuidle/governors/ladder.c|   41 -
 drivers/cpuidle/governors/menu.c  |   29 ++--
 drivers/cpuidle/sysfs.c   |   22 ++-
 drivers/idle/intel_idle.c |  130 +
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   52 ---
 16 files changed, 650 insertions(+), 332 deletions(-)


-- 

-Deepthi
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v9 1/4] cpuidle: Move dev-last_residency update to driver enter routine; remove dev-last_state

2011-10-28 Thread Deepthi Dharwar
Cpuidle governor only suggests the state to enter using the
governor-select() interface, but allows the low level driver to
override the recommended state. The actual entered state
may be different because of software or hardware demotion. Software
demotion is done by the back-end cpuidle driver and can be accounted
correctly. Current cpuidle code uses last_state field to capture the
actual state entered and based on that updates the statistics for the
state entered.

Ideally the driver enter routine should update the counters,
and it should return the state actually entered rather than the time
spent there. The generic cpuidle code should simply handle where
the counters live in the sysfs namespace, not updating the counters.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   10 +++-
 arch/arm/mach-davinci/cpuidle.c   |9 +++-
 arch/arm/mach-exynos4/cpuidle.c   |7 ++-
 arch/arm/mach-kirkwood/cpuidle.c  |   12 -
 arch/arm/mach-omap2/cpuidle34xx.c |   67 +
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   12 +++--
 drivers/acpi/processor_idle.c |   75 ++---
 drivers/cpuidle/cpuidle.c |   32 +++---
 drivers/cpuidle/governors/ladder.c|   13 ++
 drivers/cpuidle/governors/menu.c  |7 ++-
 drivers/idle/intel_idle.c |   12 -
 include/linux/cpuidle.h   |7 +--
 12 files changed, 164 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 1cfeac1..4696a0d 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,7 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-  struct cpuidle_state *state)
+  int index)
 {
struct timeval before, after;
int idle_time;
@@ -41,10 +41,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 
local_irq_disable();
do_gettimeofday(before);
-   if (state == dev-states[0])
+   if (index == 0)
/* Wait for interrupt state */
cpu_do_idle();
-   else if (state == dev-states[1]) {
+   else if (index == 1) {
asm(b 1f; .align 5; 1:);
asm(mcr p15, 0, r0, c7, c10, 4);  /* drain write buffer */
saved_lpr = sdram_selfrefresh_enable();
@@ -55,7 +55,9 @@ static int at91_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+   return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index bd59f31..ca8582a 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,9 +78,9 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-   struct cpuidle_state *state)
+   int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(state);
+   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
struct timeval before, after;
int idle_time;
 
@@ -98,7 +98,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+
+   return index;
 }
 
 static int __init davinci_cpuidle_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
index bf7e96f..ea026e7 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -16,7 +16,7 @@
 #include asm/proc-fns.h
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state);
+ int index);
 
 static struct cpuidle_state exynos4_cpuidle_set[] = {
[0] = {
@@ -37,7 +37,7 @@ static struct cpuidle_driver exynos4_idle_driver = {
 };
 
 static int exynos4_enter_idle(struct cpuidle_device *dev

[PATCH v9 2/4] cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev-prepare()

2011-10-28 Thread Deepthi Dharwar
The cpuidle_device-prepare() mechanism causes updates to the
cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE
to tell the governor not to chose a state on a per-cpu basis at
run-time. State demotion is now handled by the driver and it returns
the actual state entered. Hence, this mechanism is not required.
Also this removes per-cpu flags from cpuidle_state enabling
it to be made global.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Reviewed-by: Kevin Hilman khil...@ti.com
---
 drivers/cpuidle/cpuidle.c|   10 --
 drivers/cpuidle/governors/menu.c |2 --
 include/linux/cpuidle.h  |3 ---
 3 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 8faf3a6..984d178 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -83,16 +83,6 @@ int cpuidle_idle_call(void)
hrtimer_peek_ahead_timers();
 #endif
 
-   /*
-* Call the device's prepare function before calling the
-* governor's select function.  -prepare gives the device's
-* cpuidle driver a chance to update any dynamic information
-* of its cpuidle states for the current idle period, e.g.
-* state availability, latencies, residencies, etc.
-*/
-   if (dev-prepare)
-   dev-prepare(dev);
-
/* ask the governor for the next state */
next_state = cpuidle_curr_governor-select(dev);
if (need_resched()) {
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 3c44c53..31dd287 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -288,8 +288,6 @@ static int menu_select(struct cpuidle_device *dev)
for (i = CPUIDLE_DRIVER_STATE_START; i  dev-state_count; i++) {
struct cpuidle_state *s = dev-states[i];
 
-   if (s-flags  CPUIDLE_FLAG_IGNORE)
-   continue;
if (s-target_residency  data-predicted_us)
continue;
if (s-exit_latency  latency_req)
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 8da811b..c6d85cf 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -47,7 +47,6 @@ struct cpuidle_state {
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID(0x01) /* is residency time measurable? 
*/
-#define CPUIDLE_FLAG_IGNORE(0x100) /* ignore during this idle period */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0x)
 
@@ -93,8 +92,6 @@ struct cpuidle_device {
struct completion   kobj_unregister;
void*governor_data;
int safe_state_index;
-
-   int (*prepare)  (struct cpuidle_device *dev);
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v9 3/4] cpuidle: Split cpuidle_state structure and move per-cpu statistics fields

2011-10-28 Thread Deepthi Dharwar
This is the first step towards global registration of cpuidle
states. The statistics used primarily by the governor are per-cpu
and have to be split from rest of the fields inside cpuidle_state,
which would be made global i.e. single copy. The driver_data field
is also per-cpu and moved.

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-davinci/cpuidle.c   |5 ++--
 arch/arm/mach-omap2/cpuidle34xx.c |   13 ++
 drivers/acpi/processor_idle.c |   25 ++--
 drivers/cpuidle/cpuidle.c |   11 +
 drivers/cpuidle/sysfs.c   |   19 ++-
 drivers/idle/intel_idle.c |   46 +++--
 include/linux/cpuidle.h   |   25 
 7 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index ca8582a..f2d2f34 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -80,7 +80,8 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 static int davinci_enter_idle(struct cpuidle_device *dev,
int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
+   struct cpuidle_state_usage *state_usage = dev-states_usage[index];
+   struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
struct timeval before, after;
int idle_time;
 
@@ -142,7 +143,7 @@ static int __init davinci_cpuidle_probe(struct 
platform_device *pdev)
strcpy(device-states[1].desc, WFI and DDR Self Refresh);
if (pdata-ddr2_pdown)
davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
-   cpuidle_set_statedata(device-states[1], davinci_states[1]);
+   cpuidle_set_statedata(device-states_usage[1], davinci_states[1]);
 
device-state_count = DAVINCI_CPUIDLE_MAX_STATES;
 
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 58425c7..d3fce7b 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -97,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
int index)
 {
struct omap3_idle_statedata *cx =
-   cpuidle_get_statedata(dev-states[index]);
+   cpuidle_get_statedata(dev-states_usage[index]);
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
int idle_time;
@@ -160,8 +160,9 @@ return_sleep_time:
 static int next_valid_state(struct cpuidle_device *dev,
int index)
 {
+   struct cpuidle_state_usage *curr_usage = dev-states_usage[index];
struct cpuidle_state *curr = dev-states[index];
-   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
u32 mpu_deepest_state = PWRDM_POWER_RET;
u32 core_deepest_state = PWRDM_POWER_RET;
int next_index = -1;
@@ -202,7 +203,7 @@ static int next_valid_state(struct cpuidle_device *dev,
 */
idx--;
for (; idx = 0; idx--) {
-   cx = cpuidle_get_statedata(dev-states[idx]);
+   cx = cpuidle_get_statedata(dev-states_usage[idx]);
if ((cx-valid) 
(cx-mpu_state = mpu_deepest_state) 
(cx-core_state = core_deepest_state)) {
@@ -231,7 +232,6 @@ static int next_valid_state(struct cpuidle_device *dev,
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
   int index)
 {
-   struct cpuidle_state *state = dev-states[index];
int new_state_idx;
u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
struct omap3_idle_statedata *cx;
@@ -264,7 +264,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 * Prevent PER off if CORE is not in retention or off as this
 * would disable PER wakeups completely.
 */
-   cx = cpuidle_get_statedata(state);
+   cx = cpuidle_get_statedata(dev-states_usage[index]);
core_next_state = cx-core_state;
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
if ((per_next_state == PWRDM_POWER_OFF) 
@@ -318,6 +318,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
 {
struct omap3_idle_statedata *cx = omap3_idle_data[idx];
struct cpuidle_state *state = dev-states[idx];
+   struct cpuidle_state_usage *state_usage = dev-states_usage[idx

[PATCH v9 4/4] cpuidle: Single/Global registration of idle states

2011-10-28 Thread Deepthi Dharwar
This patch makes the cpuidle_states structure global (single copy)
instead of per-cpu. The statistics needed on per-cpu basis
by the governor are kept per-cpu. This simplifies the cpuidle
subsystem as state registration is done by single cpu only.
Having single copy of cpuidle_states saves memory. Rare case
of asymmetric C-states can be handled within the cpuidle driver
and architectures such as POWER do not have asymmetric C-states.

Having single/global registration of all the idle states,
dynamic C-state transitions on x86 are handled by
the boot cpu. Here, the boot cpu  would disable all the devices,
re-populate the states and later enable all the devices,
irrespective of the cpu that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   31 +++--
 arch/arm/mach-davinci/cpuidle.c   |   39 ---
 arch/arm/mach-exynos4/cpuidle.c   |   23 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   30 +++--
 arch/arm/mach-omap2/cpuidle34xx.c |   73 -
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   18 ++-
 drivers/acpi/processor_driver.c   |   20 +--
 drivers/acpi/processor_idle.c |  191 +
 drivers/cpuidle/cpuidle.c |   45 ++--
 drivers/cpuidle/driver.c  |   25 
 drivers/cpuidle/governors/ladder.c|   28 +++--
 drivers/cpuidle/governors/menu.c  |   20 ++-
 drivers/cpuidle/sysfs.c   |3 -
 drivers/idle/intel_idle.c |   80 +++---
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   19 ++-
 16 files changed, 439 insertions(+), 207 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 4696a0d..93178f6 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,6 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
   int index)
 {
struct timeval before, after;
@@ -64,27 +65,29 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 static int at91_init_cpuidle(void)
 {
struct cpuidle_device *device;
-
-   cpuidle_register_driver(at91_idle_driver);
+   struct cpuidle_driver *driver = at91_idle_driver;
 
device = per_cpu(at91_cpuidle_device, smp_processor_id());
device-state_count = AT91_MAX_STATES;
+   driver-state_count = AT91_MAX_STATES;
 
/* Wait for interrupt state */
-   device-states[0].enter = at91_enter_idle;
-   device-states[0].exit_latency = 1;
-   device-states[0].target_residency = 1;
-   device-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[0].name, WFI);
-   strcpy(device-states[0].desc, Wait for interrupt);
+   driver-states[0].enter = at91_enter_idle;
+   driver-states[0].exit_latency = 1;
+   driver-states[0].target_residency = 1;
+   driver-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[0].name, WFI);
+   strcpy(driver-states[0].desc, Wait for interrupt);
 
/* Wait for interrupt and RAM self refresh state */
-   device-states[1].enter = at91_enter_idle;
-   device-states[1].exit_latency = 10;
-   device-states[1].target_residency = 1;
-   device-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[1].name, RAM_SR);
-   strcpy(device-states[1].desc, WFI and RAM Self Refresh);
+   driver-states[1].enter = at91_enter_idle;
+   driver-states[1].exit_latency = 10;
+   driver-states[1].target_residency = 1;
+   driver-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[1].name, RAM_SR);
+   strcpy(driver-states[1].desc, WFI and RAM Self Refresh);
+
+   cpuidle_register_driver(at91_idle_driver);
 
if (cpuidle_register_device(device)) {
printk(KERN_ERR at91_init_cpuidle: Failed registering\n);
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index f2d2f34..dbeeccd 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,6 +78,7 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
int index)
 {
struct cpuidle_state_usage *state_usage = dev

[PATCH V8 0/4] cpuidle: Global registration of idle states with per-cpu statistics

2011-10-03 Thread Deepthi Dharwar
Version 6 of this patch series dated 22nd Sept 2011 was 
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com for OMAP specific parts.
Reviewed-by: Kevin Hilman khil...@ti.com
Tested-by: Jean Pihet j-pi...@ti.com

Hi Len, 
Can you please queue this series for the next mainline merge window by merging
it into your development tree and also linux-next for further testing.

I also tested it by applying these patches on your ACPI tree hosted @github.

Thanks
-Deepthi

--

The following patch series implements global registration of cpuidle
states, and also has the necessary data structure changes to
accommodate the per-cpu writable members of the cpuidle_states
structure.

This patch series had been in discussion earlier and
following are the links to the previous discussions.

v7 -- https://lkml.org/lkml/2011/9/27/74 
v6 -- https://lkml.org/lkml/2011/9/22/58
v5 -- https://lkml.org/lkml/2011/6/6/259
v4 -- https://lkml.org/lkml/2011/4/28/312
v3 -- https://lkml.org/lkml/2011/2/8/73
v2 -- https://lkml.org/lkml/2011/1/13/98
v1 -- https://lkml.org/lkml/2011/3/22/161

Changes from previous version (V7):

   1. Rebased and tested it on 3.1-rc8

   2. As suggested by Kevin in V7, Signature of Jean
  was moved from signed-off tag to tested-by.

Tests done:

1. Compile tested for ARM using the following configs: 
da8xx_omapl_defconfig,
exynos4_defconfig, kirkwood_defconfig, omap2plus_defconfig, 
at91rm9200_defconfig
  
2. Boot tested on x86 nehalem with multiple C-states for both intel_idle
and acpi_idle drivers.

3. Boot tested on T60p thinkpad that has T2600 cpu with multiple C-states. 
Also tested the case when there is dynamic changes in C-states 
AC - Battery Power switch.

Brief description of the patches:

Core change in this series is to split the cpuidle_device structure 
into two parts, i.e  global and per-cpu basis. 

The per-cpu pieces are mostly generic statistics that can be independent 
of current running driver. As a result of these changes, there is single 
copy of cpuidle_states structure and single registration done by one 
cpu. The low level driver is free to set per-cpu driver data on
each cpu if needed using the cpuidle_set_statedata() as the case
today. Only in very rare cases asymmetric C-states exist which can be 
handled within the cpuidle driver. Most architectures do not have 
asymmetric C-states.

First two patches in the series facilitate splitting of cpuidle_states
and cpuidle_device structure and next two patches do the actual split,
change the API's and make existing code follow the changed API.

[1/4] - Move the idle residency accounting part from cpuidle.c to
the respective low level drivers, so that the accounting can
be accurately maintained if the driver decides to demote the
chosen (suggested) by the governor.

[2/4] - removes the cpuidle_device()-prepare API since is is not
widely used and the only use case was to allow software
demotion using CPUIDLE_FLAG_IGNORE flag.  Both these
functions can be absorbed within the cpuidle back-end
driver ad hence deprecating the prepare routine and the
CPUIDLE_FLAG_IGNORE flag.

- Ref: https://lkml.org/lkml/2011/3/25/52

[3/4] - Splits the usage statistics (read/write) part out of
cpuidle_state structure, so that the states can become read
only and hence made global.

[4/4] - Most APIs will now need to pass pointer to both global
cpuidle_driver and per-cpu cpuidle_device structure.

 arch/arm/mach-at91/cpuidle.c  |   41 +++--
 arch/arm/mach-davinci/cpuidle.c   |   51 ---
 arch/arm/mach-exynos4/cpuidle.c   |   30 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   42 +++---
 arch/arm/mach-omap2/cpuidle34xx.c |  133 +++--
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   28 ++--
 drivers/acpi/processor_driver.c   |   20 ---
 drivers/acpi/processor_idle.c |  251 +++--
 drivers/cpuidle/cpuidle.c |   86 ---
 drivers/cpuidle/driver.c  |   25 +++
 drivers/cpuidle/governors/ladder.c|   41 -
 drivers/cpuidle/governors/menu.c  |   29 ++--
 drivers/cpuidle/sysfs.c   |   22 ++-
 drivers/idle/intel_idle.c |  130 +
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   52 ---
 16 files changed, 650 insertions(+), 332 deletions(-)


-- 

-Deepthi
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V8 1/4] cpuidle: Move dev-last_residency update to driver enter routine; remove dev-last_state

2011-10-03 Thread Deepthi Dharwar
Cpuidle governor only suggests the state to enter using the
governor-select() interface, but allows the low level driver to
override the recommended state. The actual entered state
may be different because of software or hardware demotion. Software
demotion is done by the back-end cpuidle driver and can be accounted
correctly. Current cpuidle code uses last_state field to capture the
actual state entered and based on that updates the statistics for the
state entered.

Ideally the driver enter routine should update the counters,
and it should return the state actually entered rather than the time
spent there. The generic cpuidle code should simply handle where
the counters live in the sysfs namespace, not updating the counters.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   10 +++-
 arch/arm/mach-davinci/cpuidle.c   |9 +++-
 arch/arm/mach-exynos4/cpuidle.c   |7 ++-
 arch/arm/mach-kirkwood/cpuidle.c  |   12 -
 arch/arm/mach-omap2/cpuidle34xx.c |   67 +
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   12 +++--
 drivers/acpi/processor_idle.c |   75 ++---
 drivers/cpuidle/cpuidle.c |   32 +++---
 drivers/cpuidle/governors/ladder.c|   13 ++
 drivers/cpuidle/governors/menu.c  |7 ++-
 drivers/idle/intel_idle.c |   12 -
 include/linux/cpuidle.h   |7 +--
 12 files changed, 164 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 1cfeac1..4696a0d 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,7 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-  struct cpuidle_state *state)
+  int index)
 {
struct timeval before, after;
int idle_time;
@@ -41,10 +41,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 
local_irq_disable();
do_gettimeofday(before);
-   if (state == dev-states[0])
+   if (index == 0)
/* Wait for interrupt state */
cpu_do_idle();
-   else if (state == dev-states[1]) {
+   else if (index == 1) {
asm(b 1f; .align 5; 1:);
asm(mcr p15, 0, r0, c7, c10, 4);  /* drain write buffer */
saved_lpr = sdram_selfrefresh_enable();
@@ -55,7 +55,9 @@ static int at91_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+   return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index bd59f31..ca8582a 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,9 +78,9 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-   struct cpuidle_state *state)
+   int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(state);
+   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
struct timeval before, after;
int idle_time;
 
@@ -98,7 +98,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+
+   return index;
 }
 
 static int __init davinci_cpuidle_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
index bf7e96f..ea026e7 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -16,7 +16,7 @@
 #include asm/proc-fns.h
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state);
+ int index);
 
 static struct cpuidle_state exynos4_cpuidle_set[] = {
[0] = {
@@ -37,7 +37,7 @@ static struct cpuidle_driver exynos4_idle_driver = {
 };
 
 static int exynos4_enter_idle(struct cpuidle_device *dev

[PATCH V8 2/4] cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev-prepare()

2011-10-03 Thread Deepthi Dharwar
The cpuidle_device-prepare() mechanism causes updates to the
cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE
to tell the governor not to chose a state on a per-cpu basis at
run-time. State demotion is now handled by the driver and it returns
the actual state entered. Hence, this mechanism is not required.
Also this removes per-cpu flags from cpuidle_state enabling
it to be made global.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Reviewed-by: Kevin Hilman khil...@ti.com
---
 drivers/cpuidle/cpuidle.c|   10 --
 drivers/cpuidle/governors/menu.c |2 --
 include/linux/cpuidle.h  |3 ---
 3 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 88bd121..f66bcf9 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -83,16 +83,6 @@ int cpuidle_idle_call(void)
hrtimer_peek_ahead_timers();
 #endif
 
-   /*
-* Call the device's prepare function before calling the
-* governor's select function.  -prepare gives the device's
-* cpuidle driver a chance to update any dynamic information
-* of its cpuidle states for the current idle period, e.g.
-* state availability, latencies, residencies, etc.
-*/
-   if (dev-prepare)
-   dev-prepare(dev);
-
/* ask the governor for the next state */
next_state = cpuidle_curr_governor-select(dev);
if (need_resched()) {
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index e4b200c..af724e8 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -288,8 +288,6 @@ static int menu_select(struct cpuidle_device *dev)
for (i = CPUIDLE_DRIVER_STATE_START; i  dev-state_count; i++) {
struct cpuidle_state *s = dev-states[i];
 
-   if (s-flags  CPUIDLE_FLAG_IGNORE)
-   continue;
if (s-target_residency  data-predicted_us)
continue;
if (s-exit_latency  latency_req)
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 8da811b..c6d85cf 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -47,7 +47,6 @@ struct cpuidle_state {
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID(0x01) /* is residency time measurable? 
*/
-#define CPUIDLE_FLAG_IGNORE(0x100) /* ignore during this idle period */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0x)
 
@@ -93,8 +92,6 @@ struct cpuidle_device {
struct completion   kobj_unregister;
void*governor_data;
int safe_state_index;
-
-   int (*prepare)  (struct cpuidle_device *dev);
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V8 3/4] cpuidle: Split cpuidle_state structure and move per-cpu statistics fields

2011-10-03 Thread Deepthi Dharwar
This is the first step towards global registration of cpuidle
states. The statistics used primarily by the governor are per-cpu
and have to be split from rest of the fields inside cpuidle_state,
which would be made global i.e. single copy. The driver_data field
is also per-cpu and moved.

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-davinci/cpuidle.c   |5 ++--
 arch/arm/mach-omap2/cpuidle34xx.c |   13 ++
 drivers/acpi/processor_idle.c |   25 ++--
 drivers/cpuidle/cpuidle.c |   11 +
 drivers/cpuidle/sysfs.c   |   19 ++-
 drivers/idle/intel_idle.c |   46 +++--
 include/linux/cpuidle.h   |   25 
 7 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index ca8582a..f2d2f34 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -80,7 +80,8 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 static int davinci_enter_idle(struct cpuidle_device *dev,
int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
+   struct cpuidle_state_usage *state_usage = dev-states_usage[index];
+   struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
struct timeval before, after;
int idle_time;
 
@@ -142,7 +143,7 @@ static int __init davinci_cpuidle_probe(struct 
platform_device *pdev)
strcpy(device-states[1].desc, WFI and DDR Self Refresh);
if (pdata-ddr2_pdown)
davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
-   cpuidle_set_statedata(device-states[1], davinci_states[1]);
+   cpuidle_set_statedata(device-states_usage[1], davinci_states[1]);
 
device-state_count = DAVINCI_CPUIDLE_MAX_STATES;
 
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 58425c7..d3fce7b 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -97,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
int index)
 {
struct omap3_idle_statedata *cx =
-   cpuidle_get_statedata(dev-states[index]);
+   cpuidle_get_statedata(dev-states_usage[index]);
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
int idle_time;
@@ -160,8 +160,9 @@ return_sleep_time:
 static int next_valid_state(struct cpuidle_device *dev,
int index)
 {
+   struct cpuidle_state_usage *curr_usage = dev-states_usage[index];
struct cpuidle_state *curr = dev-states[index];
-   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
u32 mpu_deepest_state = PWRDM_POWER_RET;
u32 core_deepest_state = PWRDM_POWER_RET;
int next_index = -1;
@@ -202,7 +203,7 @@ static int next_valid_state(struct cpuidle_device *dev,
 */
idx--;
for (; idx = 0; idx--) {
-   cx = cpuidle_get_statedata(dev-states[idx]);
+   cx = cpuidle_get_statedata(dev-states_usage[idx]);
if ((cx-valid) 
(cx-mpu_state = mpu_deepest_state) 
(cx-core_state = core_deepest_state)) {
@@ -231,7 +232,6 @@ static int next_valid_state(struct cpuidle_device *dev,
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
   int index)
 {
-   struct cpuidle_state *state = dev-states[index];
int new_state_idx;
u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
struct omap3_idle_statedata *cx;
@@ -264,7 +264,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 * Prevent PER off if CORE is not in retention or off as this
 * would disable PER wakeups completely.
 */
-   cx = cpuidle_get_statedata(state);
+   cx = cpuidle_get_statedata(dev-states_usage[index]);
core_next_state = cx-core_state;
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
if ((per_next_state == PWRDM_POWER_OFF) 
@@ -318,6 +318,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
 {
struct omap3_idle_statedata *cx = omap3_idle_data[idx];
struct cpuidle_state *state = dev-states[idx];
+   struct cpuidle_state_usage *state_usage = dev-states_usage[idx

[PATCH V8 4/4] cpuidle: Single/Global registration of idle states

2011-10-03 Thread Deepthi Dharwar
This patch makes the cpuidle_states structure global (single copy)
instead of per-cpu. The statistics needed on per-cpu basis
by the governor are kept per-cpu. This simplifies the cpuidle
subsystem as state registration is done by single cpu only.
Having single copy of cpuidle_states saves memory. Rare case
of asymmetric C-states can be handled within the cpuidle driver
and architectures such as POWER do not have asymmetric C-states.

Having single/global registration of all the idle states,
dynamic C-state transitions on x86 are handled by
the boot cpu. Here, the boot cpu  would disable all the devices,
re-populate the states and later enable all the devices,
irrespective of the cpu that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Tested-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   31 +++--
 arch/arm/mach-davinci/cpuidle.c   |   39 ---
 arch/arm/mach-exynos4/cpuidle.c   |   23 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   30 +++--
 arch/arm/mach-omap2/cpuidle34xx.c |   73 -
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   18 ++-
 drivers/acpi/processor_driver.c   |   20 +--
 drivers/acpi/processor_idle.c |  191 +
 drivers/cpuidle/cpuidle.c |   45 ++--
 drivers/cpuidle/driver.c  |   25 
 drivers/cpuidle/governors/ladder.c|   28 +++--
 drivers/cpuidle/governors/menu.c  |   20 ++-
 drivers/cpuidle/sysfs.c   |3 -
 drivers/idle/intel_idle.c |   80 +++---
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   19 ++-
 16 files changed, 439 insertions(+), 207 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 4696a0d..93178f6 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,6 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
   int index)
 {
struct timeval before, after;
@@ -64,27 +65,29 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 static int at91_init_cpuidle(void)
 {
struct cpuidle_device *device;
-
-   cpuidle_register_driver(at91_idle_driver);
+   struct cpuidle_driver *driver = at91_idle_driver;
 
device = per_cpu(at91_cpuidle_device, smp_processor_id());
device-state_count = AT91_MAX_STATES;
+   driver-state_count = AT91_MAX_STATES;
 
/* Wait for interrupt state */
-   device-states[0].enter = at91_enter_idle;
-   device-states[0].exit_latency = 1;
-   device-states[0].target_residency = 1;
-   device-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[0].name, WFI);
-   strcpy(device-states[0].desc, Wait for interrupt);
+   driver-states[0].enter = at91_enter_idle;
+   driver-states[0].exit_latency = 1;
+   driver-states[0].target_residency = 1;
+   driver-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[0].name, WFI);
+   strcpy(driver-states[0].desc, Wait for interrupt);
 
/* Wait for interrupt and RAM self refresh state */
-   device-states[1].enter = at91_enter_idle;
-   device-states[1].exit_latency = 10;
-   device-states[1].target_residency = 1;
-   device-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[1].name, RAM_SR);
-   strcpy(device-states[1].desc, WFI and RAM Self Refresh);
+   driver-states[1].enter = at91_enter_idle;
+   driver-states[1].exit_latency = 10;
+   driver-states[1].target_residency = 1;
+   driver-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[1].name, RAM_SR);
+   strcpy(driver-states[1].desc, WFI and RAM Self Refresh);
+
+   cpuidle_register_driver(at91_idle_driver);
 
if (cpuidle_register_device(device)) {
printk(KERN_ERR at91_init_cpuidle: Failed registering\n);
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index f2d2f34..dbeeccd 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,6 +78,7 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
int index)
 {
struct cpuidle_state_usage *state_usage = dev

[PATCH V7 0/4] cpuidle: Global registration of idle states with per-cpu statistics

2011-09-27 Thread Deepthi Dharwar
Version 6 of this patch series dated 22nd Sept 2011 was 
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com for OMAP specific parts.
Reviewed-by: Kevin Hilman khil...@ti.com
Signed-off-by: Jean Pihet j-pi...@ti.com

Hi Len, 
Can you please queue this series for the next mainline merge window by merging
it into your development tree and also linux-next for further testing.

I also tested it, by applying these patches on your ACPI tree hosted @github.

Thanks
-Deepthi


The following patch series implements global registration of cpuidle
states, and also has the necessary data structure changes to
accommodate the per-cpu writable members of the cpuidle_states
structure.

This patch series had been in discussion earlier and
following are the links to the previous discussions.

v1 -- https://lkml.org/lkml/2011/3/22/161
v2 -- https://lkml.org/lkml/2011/1/13/98
v3 -- https://lkml.org/lkml/2011/2/8/73
v4 -- https://lkml.org/lkml/2011/4/28/312
v5 -- https://lkml.org/lkml/2011/6/6/259
v6 -- https://lkml.org/lkml/2011/9/22/58

Changes from previous version (V6):

   Removed the RFC tag.

Tests done:

1. Compile tested for ARM using the following configs: 
da8xx_omapl_defconfig,
exynos4_defconfig, kirkwood_defconfig, omap2plus_defconfig, 
at91rm9200_defconfig
  
2. Boot tested on x86 nehalem with multiple C-states for both intel_idle
and acpi_idle drivers.

3. Boot tested on T60p thinkpad that has T2600 cpu with multiple C-states. 
Also tested the case when there is dynamic changes in C-states 
AC - Battery Power switch.

Brief description of the patches:

Core change in this series is to split the cpuidle_device structure 
into two parts, i.e  global and per-cpu basis. 

The per-cpu pieces are mostly generic statistics that can be independent 
of current running driver. As a result of these changes, there is single 
copy of cpuidle_states structure and single registration done by one 
cpu. The low level driver is free to set per-cpu driver data on
each cpu if needed using the cpuidle_set_statedata() as the case
today. Only in very rare cases asymmetric C-states exist which can be 
handled within the cpuidle driver. Most architectures do not have 
asymmetric C-states.

First two patches in the series facilitate splitting of cpuidle_states
and cpuidle_device structure and next two patches do the actual split,
change the API's and make existing code follow the changed API.

[1/4] - Move the idle residency accounting part from cpuidle.c to
the respective low level drivers, so that the accounting can
be accurately maintained if the driver decides to demote the
chosen (suggested) by the governor.

[2/4] - removes the cpuidle_device()-prepare API since is is not
widely used and the only use case was to allow software
demotion using CPUIDLE_FLAG_IGNORE flag.  Both these
functions can be absorbed within the cpuidle back-end
driver ad hence deprecating the prepare routine and the
CPUIDLE_FLAG_IGNORE flag.

- Ref: https://lkml.org/lkml/2011/3/25/52

[3/4] - Splits the usage statistics (read/write) part out of
cpuidle_state structure, so that the states can become read
only and hence made global.

[4/4] - Most APIs will now need to pass pointer to both global
cpuidle_driver and per-cpu cpuidle_device structure.

 arch/arm/mach-at91/cpuidle.c  |   41 +++--
 arch/arm/mach-davinci/cpuidle.c   |   51 ---
 arch/arm/mach-exynos4/cpuidle.c   |   30 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   42 +++---
 arch/arm/mach-omap2/cpuidle34xx.c |  133 +++--
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   28 ++--
 drivers/acpi/processor_driver.c   |   20 ---
 drivers/acpi/processor_idle.c |  251 +++--
 drivers/cpuidle/cpuidle.c |   86 ---
 drivers/cpuidle/driver.c  |   25 +++
 drivers/cpuidle/governors/ladder.c|   41 -
 drivers/cpuidle/governors/menu.c  |   29 ++--
 drivers/cpuidle/sysfs.c   |   22 ++-
 drivers/idle/intel_idle.c |  130 +
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   52 ---
 16 files changed, 650 insertions(+), 332 deletions(-)


-- 

-Deepthi
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V7 1/4] cpuidle: Move dev-last_residency update to driver enter routine; remove dev-last_state

2011-09-27 Thread Deepthi Dharwar
Cpuidle governor only suggests the state to enter using the
governor-select() interface, but allows the low level driver to
override the recommended state. The actual entered state
may be different because of software or hardware demotion. Software
demotion is done by the back-end cpuidle driver and can be accounted
correctly. Current cpuidle code uses last_state field to capture the
actual state entered and based on that updates the statistics for the
state entered.

Ideally the driver enter routine should update the counters,
and it should return the state actually entered rather than the time
spent there. The generic cpuidle code should simply handle where
the counters live in the sysfs namespace, not updating the counters.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Signed-off-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   10 +++-
 arch/arm/mach-davinci/cpuidle.c   |9 +++-
 arch/arm/mach-exynos4/cpuidle.c   |7 ++-
 arch/arm/mach-kirkwood/cpuidle.c  |   12 -
 arch/arm/mach-omap2/cpuidle34xx.c |   67 +
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   12 +++--
 drivers/acpi/processor_idle.c |   75 ++---
 drivers/cpuidle/cpuidle.c |   32 +++---
 drivers/cpuidle/governors/ladder.c|   13 ++
 drivers/cpuidle/governors/menu.c  |7 ++-
 drivers/idle/intel_idle.c |   12 -
 include/linux/cpuidle.h   |7 +--
 12 files changed, 164 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 1cfeac1..4696a0d 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,7 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-  struct cpuidle_state *state)
+  int index)
 {
struct timeval before, after;
int idle_time;
@@ -41,10 +41,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 
local_irq_disable();
do_gettimeofday(before);
-   if (state == dev-states[0])
+   if (index == 0)
/* Wait for interrupt state */
cpu_do_idle();
-   else if (state == dev-states[1]) {
+   else if (index == 1) {
asm(b 1f; .align 5; 1:);
asm(mcr p15, 0, r0, c7, c10, 4);  /* drain write buffer */
saved_lpr = sdram_selfrefresh_enable();
@@ -55,7 +55,9 @@ static int at91_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+   return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index bd59f31..ca8582a 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,9 +78,9 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-   struct cpuidle_state *state)
+   int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(state);
+   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
struct timeval before, after;
int idle_time;
 
@@ -98,7 +98,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+
+   return index;
 }
 
 static int __init davinci_cpuidle_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
index bf7e96f..ea026e7 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -16,7 +16,7 @@
 #include asm/proc-fns.h
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state);
+ int index);
 
 static struct cpuidle_state exynos4_cpuidle_set[] = {
[0] = {
@@ -37,7 +37,7 @@ static struct cpuidle_driver exynos4_idle_driver = {
 };
 
 static int exynos4_enter_idle(struct cpuidle_device *dev

[PATCH V7 2/4] cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev-prepare()

2011-09-27 Thread Deepthi Dharwar
The cpuidle_device-prepare() mechanism causes updates to the
cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE
to tell the governor not to chose a state on a per-cpu basis at
run-time. State demotion is now handled by the driver and it returns
the actual state entered. Hence, this mechanism is not required.
Also this removes per-cpu flags from cpuidle_state enabling
it to be made global.

Reference:
https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Signed-off-by: Jean Pihet j-pi...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Reviewed-by: Kevin Hilman khil...@ti.com
---
 drivers/cpuidle/cpuidle.c|   10 --
 drivers/cpuidle/governors/menu.c |2 --
 include/linux/cpuidle.h  |3 ---
 3 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 88bd121..f66bcf9 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -83,16 +83,6 @@ int cpuidle_idle_call(void)
hrtimer_peek_ahead_timers();
 #endif
 
-   /*
-* Call the device's prepare function before calling the
-* governor's select function.  -prepare gives the device's
-* cpuidle driver a chance to update any dynamic information
-* of its cpuidle states for the current idle period, e.g.
-* state availability, latencies, residencies, etc.
-*/
-   if (dev-prepare)
-   dev-prepare(dev);
-
/* ask the governor for the next state */
next_state = cpuidle_curr_governor-select(dev);
if (need_resched()) {
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index e4b200c..af724e8 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -288,8 +288,6 @@ static int menu_select(struct cpuidle_device *dev)
for (i = CPUIDLE_DRIVER_STATE_START; i  dev-state_count; i++) {
struct cpuidle_state *s = dev-states[i];
 
-   if (s-flags  CPUIDLE_FLAG_IGNORE)
-   continue;
if (s-target_residency  data-predicted_us)
continue;
if (s-exit_latency  latency_req)
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 8da811b..c6d85cf 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -47,7 +47,6 @@ struct cpuidle_state {
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID(0x01) /* is residency time measurable? 
*/
-#define CPUIDLE_FLAG_IGNORE(0x100) /* ignore during this idle period */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0x)
 
@@ -93,8 +92,6 @@ struct cpuidle_device {
struct completion   kobj_unregister;
void*governor_data;
int safe_state_index;
-
-   int (*prepare)  (struct cpuidle_device *dev);
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V7 3/4] cpuidle: Split cpuidle_state structure and move per-cpu statistics fields

2011-09-27 Thread Deepthi Dharwar
This is the first step towards global registration of cpuidle
states. The statistics used primarily by the governor are per-cpu
and have to be split from rest of the fields inside cpuidle_state,
which would be made global i.e. single copy. The driver_data field
is also per-cpu and moved.

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Signed-off-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-davinci/cpuidle.c   |5 ++--
 arch/arm/mach-omap2/cpuidle34xx.c |   13 ++
 drivers/acpi/processor_idle.c |   25 ++--
 drivers/cpuidle/cpuidle.c |   11 +
 drivers/cpuidle/sysfs.c   |   19 ++-
 drivers/idle/intel_idle.c |   46 +++--
 include/linux/cpuidle.h   |   25 
 7 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index ca8582a..f2d2f34 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -80,7 +80,8 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 static int davinci_enter_idle(struct cpuidle_device *dev,
int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
+   struct cpuidle_state_usage *state_usage = dev-states_usage[index];
+   struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
struct timeval before, after;
int idle_time;
 
@@ -142,7 +143,7 @@ static int __init davinci_cpuidle_probe(struct 
platform_device *pdev)
strcpy(device-states[1].desc, WFI and DDR Self Refresh);
if (pdata-ddr2_pdown)
davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
-   cpuidle_set_statedata(device-states[1], davinci_states[1]);
+   cpuidle_set_statedata(device-states_usage[1], davinci_states[1]);
 
device-state_count = DAVINCI_CPUIDLE_MAX_STATES;
 
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 58425c7..d3fce7b 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -97,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
int index)
 {
struct omap3_idle_statedata *cx =
-   cpuidle_get_statedata(dev-states[index]);
+   cpuidle_get_statedata(dev-states_usage[index]);
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
int idle_time;
@@ -160,8 +160,9 @@ return_sleep_time:
 static int next_valid_state(struct cpuidle_device *dev,
int index)
 {
+   struct cpuidle_state_usage *curr_usage = dev-states_usage[index];
struct cpuidle_state *curr = dev-states[index];
-   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
u32 mpu_deepest_state = PWRDM_POWER_RET;
u32 core_deepest_state = PWRDM_POWER_RET;
int next_index = -1;
@@ -202,7 +203,7 @@ static int next_valid_state(struct cpuidle_device *dev,
 */
idx--;
for (; idx = 0; idx--) {
-   cx = cpuidle_get_statedata(dev-states[idx]);
+   cx = cpuidle_get_statedata(dev-states_usage[idx]);
if ((cx-valid) 
(cx-mpu_state = mpu_deepest_state) 
(cx-core_state = core_deepest_state)) {
@@ -231,7 +232,6 @@ static int next_valid_state(struct cpuidle_device *dev,
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
   int index)
 {
-   struct cpuidle_state *state = dev-states[index];
int new_state_idx;
u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
struct omap3_idle_statedata *cx;
@@ -264,7 +264,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 * Prevent PER off if CORE is not in retention or off as this
 * would disable PER wakeups completely.
 */
-   cx = cpuidle_get_statedata(state);
+   cx = cpuidle_get_statedata(dev-states_usage[index]);
core_next_state = cx-core_state;
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
if ((per_next_state == PWRDM_POWER_OFF) 
@@ -318,6 +318,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
 {
struct omap3_idle_statedata *cx = omap3_idle_data[idx];
struct cpuidle_state *state = dev-states[idx];
+   struct cpuidle_state_usage *state_usage = dev-states_usage[idx

[PATCH V7 4/4] cpuidle: Single/Global registration of idle states

2011-09-27 Thread Deepthi Dharwar
This patch makes the cpuidle_states structure global (single copy)
instead of per-cpu. The statistics needed on per-cpu basis
by the governor are kept per-cpu. This simplifies the cpuidle
subsystem as state registration is done by single cpu only.
Having single copy of cpuidle_states saves memory. Rare case
of asymmetric C-states can be handled within the cpuidle driver
and architectures such as POWER do not have asymmetric C-states.

Having single/global registration for all the idle states,
dynamic C-state transitions on x86 are handled by
the boot cpu. Here, the boot cpu  would disable all the devices,
re-populate the states and later enable all the devices,
irrespective of the cpu that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
Signed-off-by: Jean Pihet j-pi...@ti.com
Reviewed-by: Kevin Hilman khil...@ti.com
Acked-by: Arjan van de Ven ar...@linux.intel.com
Acked-by: Kevin Hilman khil...@ti.com
---
 arch/arm/mach-at91/cpuidle.c  |   31 +++--
 arch/arm/mach-davinci/cpuidle.c   |   39 ---
 arch/arm/mach-exynos4/cpuidle.c   |   23 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   30 +++--
 arch/arm/mach-omap2/cpuidle34xx.c |   73 -
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   18 ++-
 drivers/acpi/processor_driver.c   |   20 +--
 drivers/acpi/processor_idle.c |  191 +
 drivers/cpuidle/cpuidle.c |   45 ++--
 drivers/cpuidle/driver.c  |   25 
 drivers/cpuidle/governors/ladder.c|   28 +++--
 drivers/cpuidle/governors/menu.c  |   20 ++-
 drivers/cpuidle/sysfs.c   |3 -
 drivers/idle/intel_idle.c |   80 +++---
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   19 ++-
 16 files changed, 439 insertions(+), 207 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 4696a0d..93178f6 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,6 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
   int index)
 {
struct timeval before, after;
@@ -64,27 +65,29 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 static int at91_init_cpuidle(void)
 {
struct cpuidle_device *device;
-
-   cpuidle_register_driver(at91_idle_driver);
+   struct cpuidle_driver *driver = at91_idle_driver;
 
device = per_cpu(at91_cpuidle_device, smp_processor_id());
device-state_count = AT91_MAX_STATES;
+   driver-state_count = AT91_MAX_STATES;
 
/* Wait for interrupt state */
-   device-states[0].enter = at91_enter_idle;
-   device-states[0].exit_latency = 1;
-   device-states[0].target_residency = 1;
-   device-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[0].name, WFI);
-   strcpy(device-states[0].desc, Wait for interrupt);
+   driver-states[0].enter = at91_enter_idle;
+   driver-states[0].exit_latency = 1;
+   driver-states[0].target_residency = 1;
+   driver-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[0].name, WFI);
+   strcpy(driver-states[0].desc, Wait for interrupt);
 
/* Wait for interrupt and RAM self refresh state */
-   device-states[1].enter = at91_enter_idle;
-   device-states[1].exit_latency = 10;
-   device-states[1].target_residency = 1;
-   device-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[1].name, RAM_SR);
-   strcpy(device-states[1].desc, WFI and RAM Self Refresh);
+   driver-states[1].enter = at91_enter_idle;
+   driver-states[1].exit_latency = 10;
+   driver-states[1].target_residency = 1;
+   driver-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[1].name, RAM_SR);
+   strcpy(driver-states[1].desc, WFI and RAM Self Refresh);
+
+   cpuidle_register_driver(at91_idle_driver);
 
if (cpuidle_register_device(device)) {
printk(KERN_ERR at91_init_cpuidle: Failed registering\n);
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index f2d2f34..dbeeccd 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,6 +78,7 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
int index)
 {
struct cpuidle_state_usage *state_usage

Re: [RFC PATCH V6 0/4] cpuidle: Global registration of idle states with per-cpu statistics

2011-09-23 Thread Deepthi Dharwar
On Friday 23 September 2011 01:15 AM, Kevin Hilman wrote:
 Deepthi Dharwar deep...@linux.vnet.ibm.com writes:
 
 The following patch series implements global registration of cpuidle
 states, and also has the necessary data structure changes to
 accommodate the per-cpu writable members of the cpuidle_states
 structure.
 
 I reviewed earlier versions of the series, and this version still looks
 good to me.  Any reason it is still RFC?
 
 Reviewed-by: Kevin Hilman khil...@ti.com
 
 and for the OMAP-specific parts,
 
 Acked-by: Kevin Hilman khil...@ti.com
 
 Kevin
 
Hi Kevin,
Thanks for reviewing the patch.

This was posted as an RFC, as there were
a couple of ToDos listed in this patch series
which I thought needed additional review before 
I could ask for inclusion. 

To Do :
==

1. Russell King pointed out that in (V5 1/4) of this patch in
arch/arm/mach-at91/cpuidle.c, AT91 pieces may be broken.
In at91_enter_idle() routine, folks need to fix the two
consecutive asm() statements by combining
it to one as per the GCC reference manual.

Reference:
https://lkml.org/lkml/2011/6/6/273

2. In (V6 4/4), handle the case when idle states may change at run time
and acpi_processor_cst_has_changed() routine is called in a
better way than the current solution in this patch.

In this current solution where global registration is implemented,
the boot cpu on x86 would disable all the devices, repopulate the
states and later enable all the devices, irrespective of the cpu
that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83

Thanks  Regards,
 -Deepthi
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH V6 0/4] cpuidle: Global registration of idle states with per-cpu statistics

2011-09-22 Thread Deepthi Dharwar
The following patch series implements global registration of cpuidle
states, and also has the necessary data structure changes to
accommodate the per-cpu writable members of the cpuidle_states
structure.

This patch series had been in discussion earlier and
following are the links to the previous discussions.

v1 -- https://lkml.org/lkml/2011/3/22/161
v2 -- https://lkml.org/lkml/2011/1/13/98
v3 -- https://lkml.org/lkml/2011/2/8/73
v4 -- https://lkml.org/lkml/2011/4/28/312
v5 -- https://lkml.org/lkml/2011/6/6/259

Changes from previous version (V5):

Rebased the series to 3.1-rc7

Tests done:

1. Compile tested for ARM using the following configs: 
da8xx_omapl_defconfig,
exynos4_defconfig, kirkwood_defconfig, omap2plus_defconfig, 
at91rm9200_defconfig
  
2. Boot tested on x86 nehalem with multiple C-states for both intel_idle
and acpi_idle drivers.

3. Boot tested on T60p thinkpad that has T2600 cpu with multiple C-states. 
Also tested the case when there is dynamic changes in C-states 
AC - Battery Power switch.

Brief description of the patches:

Core change in this series is to split the cpuidle_device structure 
into two parts, i.e  global and per-cpu basis. 

The per-cpu pieces are mostly generic statistics that can be independent 
of current running driver. As a result of these changes, there is single 
copy of cpuidle_states structure and single registration done by one 
cpu. The low level driver is free to set per-cpu driver data on
each cpu if needed using the cpuidle_set_statedata() as the case
today. Only in very rare cases asymmetric C-states exist which can be 
handled within the cpuidle driver. Most architectures do not have 
asymmetric C-states.

First two patches in the series facilitate splitting of cpuidle_states
and cpuidle_device structure and next two patches do the actual split,
change the API's and make existing code follow the changed API.

[1/4] - Move the idle residency accounting part from cpuidle.c to
the respective low level drivers, so that the accounting can
be accurately maintained if the driver decides to demote the
chosen (suggested) by the governor.

[2/4] - removes the cpuidle_device()-prepare API since is is not
widely used and the only use case was to allow software
demotion using CPUIDLE_FLAG_IGNORE flag.  Both these
functions can be absorbed within the cpuidle back-end
driver ad hence deprecating the prepare routine and the
CPUIDLE_FLAG_IGNORE flag.

- Ref: https://lkml.org/lkml/2011/3/25/52

[3/4] - Splits the usage statistics (read/write) part out of
cpuidle_state structure, so that the states can become read
only and hence made global.

[4/4] - Most APIs will now need to pass pointer to both global
cpuidle_driver and per-cpu cpuidle_device structure.

 arch/arm/mach-at91/cpuidle.c  |   41 +++--
 arch/arm/mach-davinci/cpuidle.c   |   51 ---
 arch/arm/mach-exynos4/cpuidle.c   |   30 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   42 +++---
 arch/arm/mach-omap2/cpuidle34xx.c |  133 +++--
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   28 ++--
 drivers/acpi/processor_driver.c   |   20 ---
 drivers/acpi/processor_idle.c |  251 +++--
 drivers/cpuidle/cpuidle.c |   86 ---
 drivers/cpuidle/driver.c  |   25 +++
 drivers/cpuidle/governors/ladder.c|   41 -
 drivers/cpuidle/governors/menu.c  |   29 ++--
 drivers/cpuidle/sysfs.c   |   22 ++-
 drivers/idle/intel_idle.c |  130 +
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   52 ---
 16 files changed, 650 insertions(+), 332 deletions(-)


-- 

Thanks
 -Deepthi
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH V6 2/4] cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev-prepare()

2011-09-22 Thread Deepthi Dharwar
The cpuidle_device-prepare() mechanism causes updates to the
cpuidle_state[].flags, setting and clearing CPUIDLE_FLAG_IGNORE
to tell the governor not to chose a state on a per-cpu basis at
run-time. State demotion is now handled by the driver and it returns
the actual state entered. Hence, this mechanism is not required.
Also this removes per-cpu flags from cpuidle_state enabling
it to be made global.

Ref: https://lkml.org/lkml/2011/3/25/52

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
---
 drivers/cpuidle/cpuidle.c|   10 --
 drivers/cpuidle/governors/menu.c |2 --
 include/linux/cpuidle.h  |3 ---
 3 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 88bd121..f66bcf9 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -83,16 +83,6 @@ int cpuidle_idle_call(void)
hrtimer_peek_ahead_timers();
 #endif
 
-   /*
-* Call the device's prepare function before calling the
-* governor's select function.  -prepare gives the device's
-* cpuidle driver a chance to update any dynamic information
-* of its cpuidle states for the current idle period, e.g.
-* state availability, latencies, residencies, etc.
-*/
-   if (dev-prepare)
-   dev-prepare(dev);
-
/* ask the governor for the next state */
next_state = cpuidle_curr_governor-select(dev);
if (need_resched()) {
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index e4b200c..af724e8 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -288,8 +288,6 @@ static int menu_select(struct cpuidle_device *dev)
for (i = CPUIDLE_DRIVER_STATE_START; i  dev-state_count; i++) {
struct cpuidle_state *s = dev-states[i];
 
-   if (s-flags  CPUIDLE_FLAG_IGNORE)
-   continue;
if (s-target_residency  data-predicted_us)
continue;
if (s-exit_latency  latency_req)
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 8da811b..c6d85cf 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -47,7 +47,6 @@ struct cpuidle_state {
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID(0x01) /* is residency time measurable? 
*/
-#define CPUIDLE_FLAG_IGNORE(0x100) /* ignore during this idle period */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0x)
 
@@ -93,8 +92,6 @@ struct cpuidle_device {
struct completion   kobj_unregister;
void*governor_data;
int safe_state_index;
-
-   int (*prepare)  (struct cpuidle_device *dev);
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH V6 1/4] cpuidle: Move dev-last_residency update to driver enter routine; remove dev-last_state

2011-09-22 Thread Deepthi Dharwar
Cpuidle governor only suggests the state to enter using the
governor-select() interface, but allows the low level driver to
override the recommended state. The actual entered state
may be different because of software or hardware demotion. Software
demotion is done by the back-end cpuidle driver and can be accounted
correctly. Current cpuidle code uses last_state field to capture the
actual state entered and based on that updates the statistics for the
state entered.

Ideally the driver enter routine should update the counters,
and it should return the state actually entered rather than the time
spent there. The generic cpuidle code should simply handle where
the counters live in the sysfs namespace, not updating the counters.

Reference:
https://lkml.org/lkml/2011/3/25/52

To Do :
==
Russell King pointed out that in (V5) of this patch in
arch/arm/mach-at91/cpuidle.c, AT91 pieces may be broken.
In at91_enter_idle() routine, folks need to fix the two
consecutive asm() statements by combining
it to one as per the GCC reference manual.

Reference:
https://lkml.org/lkml/2011/6/6/273

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
---
 arch/arm/mach-at91/cpuidle.c  |   10 +++-
 arch/arm/mach-davinci/cpuidle.c   |9 +++-
 arch/arm/mach-exynos4/cpuidle.c   |7 ++-
 arch/arm/mach-kirkwood/cpuidle.c  |   12 -
 arch/arm/mach-omap2/cpuidle34xx.c |   67 +
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   12 +++--
 drivers/acpi/processor_idle.c |   75 ++---
 drivers/cpuidle/cpuidle.c |   32 +++---
 drivers/cpuidle/governors/ladder.c|   13 ++
 drivers/cpuidle/governors/menu.c  |7 ++-
 drivers/idle/intel_idle.c |   12 -
 include/linux/cpuidle.h   |7 +--
 12 files changed, 164 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 1cfeac1..4696a0d 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,7 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-  struct cpuidle_state *state)
+  int index)
 {
struct timeval before, after;
int idle_time;
@@ -41,10 +41,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 
local_irq_disable();
do_gettimeofday(before);
-   if (state == dev-states[0])
+   if (index == 0)
/* Wait for interrupt state */
cpu_do_idle();
-   else if (state == dev-states[1]) {
+   else if (index == 1) {
asm(b 1f; .align 5; 1:);
asm(mcr p15, 0, r0, c7, c10, 4);  /* drain write buffer */
saved_lpr = sdram_selfrefresh_enable();
@@ -55,7 +55,9 @@ static int at91_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+   return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index bd59f31..ca8582a 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,9 +78,9 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-   struct cpuidle_state *state)
+   int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(state);
+   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
struct timeval before, after;
int idle_time;
 
@@ -98,7 +98,10 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
-   return idle_time;
+
+   dev-last_residency = idle_time;
+
+   return index;
 }
 
 static int __init davinci_cpuidle_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
index bf7e96f..ea026e7 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -16,7 +16,7 @@
 #include asm/proc-fns.h
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state);
+ int index);
 
 static struct cpuidle_state exynos4_cpuidle_set[] = {
[0] = {
@@ -37,7 +37,7

[RFC PATCH V6 3/4] cpuidle: Split cpuidle_state structure and move per-cpu statistics fields

2011-09-22 Thread Deepthi Dharwar
This is the first step towards global registration of cpuidle
states. The statistics used primarily by the governor are per-cpu
and have to be split from rest of the fields inside cpuidle_state,
which would be made global i.e. single copy. The driver_data field
is also per-cpu and moved.

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
---
 arch/arm/mach-davinci/cpuidle.c   |5 ++--
 arch/arm/mach-omap2/cpuidle34xx.c |   13 ++
 drivers/acpi/processor_idle.c |   25 ++--
 drivers/cpuidle/cpuidle.c |   11 +
 drivers/cpuidle/sysfs.c   |   19 ++-
 drivers/idle/intel_idle.c |   46 +++--
 include/linux/cpuidle.h   |   25 
 7 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index ca8582a..f2d2f34 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -80,7 +80,8 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 static int davinci_enter_idle(struct cpuidle_device *dev,
int index)
 {
-   struct davinci_ops *ops = cpuidle_get_statedata(dev-states[index]);
+   struct cpuidle_state_usage *state_usage = dev-states_usage[index];
+   struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
struct timeval before, after;
int idle_time;
 
@@ -142,7 +143,7 @@ static int __init davinci_cpuidle_probe(struct 
platform_device *pdev)
strcpy(device-states[1].desc, WFI and DDR Self Refresh);
if (pdata-ddr2_pdown)
davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
-   cpuidle_set_statedata(device-states[1], davinci_states[1]);
+   cpuidle_set_statedata(device-states_usage[1], davinci_states[1]);
 
device-state_count = DAVINCI_CPUIDLE_MAX_STATES;
 
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 58425c7..d3fce7b 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -97,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
int index)
 {
struct omap3_idle_statedata *cx =
-   cpuidle_get_statedata(dev-states[index]);
+   cpuidle_get_statedata(dev-states_usage[index]);
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
int idle_time;
@@ -160,8 +160,9 @@ return_sleep_time:
 static int next_valid_state(struct cpuidle_device *dev,
int index)
 {
+   struct cpuidle_state_usage *curr_usage = dev-states_usage[index];
struct cpuidle_state *curr = dev-states[index];
-   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
u32 mpu_deepest_state = PWRDM_POWER_RET;
u32 core_deepest_state = PWRDM_POWER_RET;
int next_index = -1;
@@ -202,7 +203,7 @@ static int next_valid_state(struct cpuidle_device *dev,
 */
idx--;
for (; idx = 0; idx--) {
-   cx = cpuidle_get_statedata(dev-states[idx]);
+   cx = cpuidle_get_statedata(dev-states_usage[idx]);
if ((cx-valid) 
(cx-mpu_state = mpu_deepest_state) 
(cx-core_state = core_deepest_state)) {
@@ -231,7 +232,6 @@ static int next_valid_state(struct cpuidle_device *dev,
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
   int index)
 {
-   struct cpuidle_state *state = dev-states[index];
int new_state_idx;
u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
struct omap3_idle_statedata *cx;
@@ -264,7 +264,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 * Prevent PER off if CORE is not in retention or off as this
 * would disable PER wakeups completely.
 */
-   cx = cpuidle_get_statedata(state);
+   cx = cpuidle_get_statedata(dev-states_usage[index]);
core_next_state = cx-core_state;
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
if ((per_next_state == PWRDM_POWER_OFF) 
@@ -318,6 +318,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
 {
struct omap3_idle_statedata *cx = omap3_idle_data[idx];
struct cpuidle_state *state = dev-states[idx];
+   struct cpuidle_state_usage *state_usage = dev-states_usage[idx];
 
state-exit_latency = cpuidle_params_table[idx].exit_latency;
state-target_residency = cpuidle_params_table[idx].target_residency;
@@ -326,7 +327,7 @@ static

[RFC PATCH V6 4/4] cpuidle: Single/Global registration of idle states

2011-09-22 Thread Deepthi Dharwar
This patch makes the cpuidle_states structure global (single copy)
instead of per-cpu. The statistics needed on per-cpu basis
by the governor are kept per-cpu. This simplifies the cpuidle
subsystem as state registration is done by single cpu only.
Having single copy of cpuidle_states saves memory. Rare case
of asymmetric C-states can be handled within the cpuidle driver
and architectures such as POWER do not have asymmetric C-states.

ToDo:


Handle the case when idle states may change at run time
and acpi_processor_cst_has_changed() routine is called in a
better way than the current solution in this patch.

In this current solution where global registration is implemented,
the boot cpu on x86 would disable all the devices, repopulate the
states and later enable all the devices, irrespective of the cpu
that would receive the notification first.

Reference:
https://lkml.org/lkml/2011/4/25/83

Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com
Signed-off-by: Trinabh Gupta g.trin...@gmail.com
---
 arch/arm/mach-at91/cpuidle.c  |   31 +++--
 arch/arm/mach-davinci/cpuidle.c   |   39 ---
 arch/arm/mach-exynos4/cpuidle.c   |   23 ++--
 arch/arm/mach-kirkwood/cpuidle.c  |   30 +++--
 arch/arm/mach-omap2/cpuidle34xx.c |   73 -
 arch/sh/kernel/cpu/shmobile/cpuidle.c |   18 ++-
 drivers/acpi/processor_driver.c   |   20 +--
 drivers/acpi/processor_idle.c |  191 +
 drivers/cpuidle/cpuidle.c |   45 ++--
 drivers/cpuidle/driver.c  |   25 
 drivers/cpuidle/governors/ladder.c|   28 +++--
 drivers/cpuidle/governors/menu.c  |   20 ++-
 drivers/cpuidle/sysfs.c   |3 -
 drivers/idle/intel_idle.c |   80 +++---
 include/acpi/processor.h  |1 
 include/linux/cpuidle.h   |   19 ++-
 16 files changed, 439 insertions(+), 207 deletions(-)

diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 4696a0d..93178f6 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -33,6 +33,7 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
   int index)
 {
struct timeval before, after;
@@ -64,27 +65,29 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 static int at91_init_cpuidle(void)
 {
struct cpuidle_device *device;
-
-   cpuidle_register_driver(at91_idle_driver);
+   struct cpuidle_driver *driver = at91_idle_driver;
 
device = per_cpu(at91_cpuidle_device, smp_processor_id());
device-state_count = AT91_MAX_STATES;
+   driver-state_count = AT91_MAX_STATES;
 
/* Wait for interrupt state */
-   device-states[0].enter = at91_enter_idle;
-   device-states[0].exit_latency = 1;
-   device-states[0].target_residency = 1;
-   device-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[0].name, WFI);
-   strcpy(device-states[0].desc, Wait for interrupt);
+   driver-states[0].enter = at91_enter_idle;
+   driver-states[0].exit_latency = 1;
+   driver-states[0].target_residency = 1;
+   driver-states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[0].name, WFI);
+   strcpy(driver-states[0].desc, Wait for interrupt);
 
/* Wait for interrupt and RAM self refresh state */
-   device-states[1].enter = at91_enter_idle;
-   device-states[1].exit_latency = 10;
-   device-states[1].target_residency = 1;
-   device-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-   strcpy(device-states[1].name, RAM_SR);
-   strcpy(device-states[1].desc, WFI and RAM Self Refresh);
+   driver-states[1].enter = at91_enter_idle;
+   driver-states[1].exit_latency = 10;
+   driver-states[1].target_residency = 1;
+   driver-states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+   strcpy(driver-states[1].name, RAM_SR);
+   strcpy(driver-states[1].desc, WFI and RAM Self Refresh);
+
+   cpuidle_register_driver(at91_idle_driver);
 
if (cpuidle_register_device(device)) {
printk(KERN_ERR at91_init_cpuidle: Failed registering\n);
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index f2d2f34..dbeeccd 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -78,6 +78,7 @@ static struct davinci_ops 
davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
int index)
 {
struct cpuidle_state_usage *state_usage = dev-states_usage[index];
@@ -109,6 +110,7