From fece5219b0375dbd8d1741cc1516bff89163ed1a Mon Sep 17 00:00:00 2001 From: Vincent Guittot Date: Mon, 11 Apr 2011 14:37:04 +0200 Subject: ux500: pm: add use-case governor Signed-off-by: Vincent Guittot Signed-off-by: Mian Yousaf Kaukab [ANDROID]: ux500: pm: update sysfs interface for usecase governor A separate sysfs node is added fro each use-case. It is now possible to enable multiple use-cases simultaneously. If multiple use-cases are enabled, each configuration (of all enabled uses-caes) is compared and the configuration which is requesting highest performance is selected. Signed-off-by: Mian Yousaf Kaukab [ANDROID]: ux500: pm: usecase-gov Act on interrupts per s If the number of interrupts per seconds are above a certain level, exit from the asked mode. [ANDROID]: ux500: pm: update low-power-audio config in usecse-governor Update low-power-audio configuration to plug-out second cpu. This makes auto, voice-call and low-power-audio configurations to be same. Auto mode is activated by default (without any user space interaction). This makes voice-call and low-power-audio configurations redundant. However, analysis work is still on going for adding other settings that may become part of usecase governor so keeping all configurations in there for now. Signed-off-by: Mian Yousaf Kaukab [ANDROID]: ux500: pm: update usecase governor dependencies in Kconfig [ANDROID]: ARM: ux500: pm: usecase gov depends on PM Signed-off-by: Jonas Aaberg [ANDROID]: ux500: pm: minor code cleanup in UC governor Signed-off-by: Martin Persson [ANDROID] ux500: pm: disable auto mode in usecase governor In absence of auto mode there is no need to schedule work on early suspend so schedule work only when needed. Signed-off-by: Mian Yousaf Kaukab [ANDROID]: pm: force ondemand governor to choose higher frequency In stead of overriding frequency selected by ondemand governor in u8500_cpufreq_target(), force ondemand governor to select higher frequency when wlan and usb workaround is enabled. ANDROID tag is used to keep the patch internal. Otherwise it does not have any Android dependency. Signed-off-by: Mian Yousaf Kaukab [ANDROID]: ARM: u8500: usecaseg: Tiny code clean-up Signed-off-by: Jonas Aaberg arm: ux500: halve the frequencies of some clocks in vc use case This patch adds a new APE OPP (50% with ACLK and DMACLK frequencies at 25%) which is used during the voice call use case. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Mattias Nilsson ux500: pm: Add min cpufreq to UC governor Add a minimum cpu frequency limit to each use case in the use case governor. Signed-off-by: Martin Persson ux500: pm: allow usecase governor to force cpu idle states Also update low-power-audio configuration to force ApSleep state. ux500: pm: move use case definitions to a header file ux500: pm: add pl310 prefetch control in use-case governor ux500: pm: cosmetic changes in use-case governor Signed-off-by: Mian Yousaf Kaukab --- drivers/cpuidle/governors/menu.c | 58 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'drivers/cpuidle') diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 95f4c391e4f..ed28f774ca4 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -124,6 +124,7 @@ struct menu_device { }; static int tune_multiplier = 1024; +static int forced_state; #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -290,26 +291,34 @@ static int menu_select(struct cpuidle_device *dev) if (data->expected_us > 5) data->last_state_idx = CPUIDLE_DRIVER_STATE_START; - /* - * Find the idle state with the lowest power while satisfying - * our constraints. - */ - 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) - continue; - if (s->exit_latency * multiplier > data->predicted_us) - continue; - - if (s->power_usage < power_usage) { - power_usage = s->power_usage; - data->last_state_idx = i; - data->exit_us = s->exit_latency; + WARN((forced_state >= dev->state_count), \ + "Forced state value out of range.\n"); + + if ((forced_state != 0) && (forced_state < dev->state_count)) { + data->exit_us = dev->states[forced_state].exit_latency; + data->last_state_idx = forced_state; + } else { + /* + * Find the idle state with the lowest power while satisfying + * our constraints. + */ + 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) + continue; + if (s->exit_latency * multiplier > data->predicted_us) + continue; + + if (s->power_usage < power_usage) { + power_usage = s->power_usage; + data->last_state_idx = i; + data->exit_us = s->exit_latency; + } } } @@ -402,6 +411,15 @@ int cpuidle_set_multiplier(unsigned int value) } EXPORT_SYMBOL(cpuidle_set_multiplier); +/* Writing 0 will remove the forced state. */ +int cpuidle_force_state(unsigned int state) +{ + forced_state = state; + + return 0; +} +EXPORT_SYMBOL(cpuidle_force_state); + static ssize_t show_multiplier(struct sysdev_class *class, struct sysdev_class_attribute *attr, char *buf) -- cgit v1.2.3