>From 8e05cb67e8c61e287d1f424decb4edc77c622481 Mon Sep 17 00:00:00 2001 From: Illyas Mansoor <[email protected]> Date: Wed, 3 Nov 2010 01:49:26 +0530 Subject: [PATCH 1/2] Removing SFI C and P state divers.
Intel CPU Idle driver will be used for C state, and SFI P state driver is moved to arch/x86/kernel/cpu/cpufreq directory. Signed-off-by: Illyas Mansoor <[email protected]> --- drivers/sfi/Kconfig | 9 -- drivers/sfi/Makefile | 6 - drivers/sfi/sfi_processor_core.c | 205 --------------------------- drivers/sfi/sfi_processor_idle.c | 262 ----------------------------------- drivers/sfi/sfi_processor_perflib.c | 189 ------------------------- 5 files changed, 0 insertions(+), 671 deletions(-) delete mode 100644 drivers/sfi/sfi_processor_core.c delete mode 100644 drivers/sfi/sfi_processor_idle.c delete mode 100644 drivers/sfi/sfi_processor_perflib.c diff --git a/drivers/sfi/Kconfig b/drivers/sfi/Kconfig index 8d8cc67..2e24183 100644 --- a/drivers/sfi/Kconfig +++ b/drivers/sfi/Kconfig @@ -16,13 +16,4 @@ menuconfig SFI For more information, see http://simplefirmware.org Say 'Y' here to enable the kernel to boot on SFI-only platforms. -config SFI_PROCESSOR_PM - bool "SFI Processor Power Management" - depends on SFI && X86_LOCAL_APIC - default y - -config SFI_CPUIDLE - bool "SFI Processor C-State driver" - depends on SFI_PROCESSOR_PM && CPU_IDLE - default y diff --git a/drivers/sfi/Makefile b/drivers/sfi/Makefile index 39f1f44..2343732 100644 --- a/drivers/sfi/Makefile +++ b/drivers/sfi/Makefile @@ -1,9 +1,3 @@ obj-y += sfi_acpi.o obj-y += sfi_core.o -sfi-processor-objs += sfi_processor_core.o -sfi-processor-objs += sfi_processor_idle.o -sfi-processor-objs += sfi_processor_perflib.o - -obj-$(CONFIG_SFI_PROCESSOR_PM) += sfi-processor.o - diff --git a/drivers/sfi/sfi_processor_core.c b/drivers/sfi/sfi_processor_core.c deleted file mode 100644 index ce1ebb7..0000000 --- a/drivers/sfi/sfi_processor_core.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * sfi_processor_core.c - sfi based c-state driver - * Copyright (c) 2010, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/sfi.h> -#include <linux/cpu.h> -#include <linux/sfi_processor.h> - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Processor enumeration based on SFI table."); - -DEFINE_PER_CPU(struct sfi_processor *, sfi_processors); - -#define SFI_CPU_MAX 8 - -static u32 sfi_cpu_num; -static struct sfi_cpu_table_entry sfi_cpu_array[SFI_CPU_MAX]; - -struct cpuidle_driver sfi_idle_driver = { - .name = "sfi_idle", - .owner = THIS_MODULE, -}; - -static int __init parse_cpus(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_cpu_table_entry *pentry; - int i; - - sb = (struct sfi_table_simple *)table; - - sfi_cpu_num = SFI_GET_NUM_ENTRIES(sb, u64); - - pentry = (struct sfi_cpu_table_entry *) sb->pentry; - for (i = 0; i < sfi_cpu_num; i++) { - sfi_cpu_array[i].apic_id = pentry->apic_id; - printk(KERN_INFO "APIC ID: %d\n", pentry->apic_id); - pentry++; - } - - return 0; - -} - -static int alloc_cstates(int cpu, u32 count) -{ - struct sfi_processor *pr; - u32 totallen = count * sizeof(struct sfi_cstate_table_entry); - - pr = per_cpu(sfi_processors, cpu); - pr->power.sfi_cstates = kzalloc(totallen, GFP_KERNEL); - if (!pr->power.sfi_cstates) - return -ENOMEM; - - totallen = count * sizeof(struct cpuidle_state); - pr->power.states = kzalloc(totallen, GFP_KERNEL); - if (!pr->power.states) { - kfree(pr->power.sfi_cstates); - return -ENOMEM; - } - - return 0; -} - -static void dealloc_cstates(int num) -{ - struct sfi_processor *pr; - int i; - - for (i = 0; i < num; i++) { - pr = per_cpu(sfi_processors, i); - kfree(pr->power.sfi_cstates); - kfree(pr->power.states); - } -} - -static int __init parse_idle(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_cstate_table_entry *pentry; - struct sfi_processor *pr; - int i; - int result; - u32 total_cstates, actual_cstates; - - sb = (struct sfi_table_simple *)table; - actual_cstates = SFI_GET_NUM_ENTRIES(sb, u64); - pentry = (struct sfi_cstate_table_entry *)sb->pentry; -#ifdef CONFIG_MSTWN_POWER_MGMT - total_cstates = actual_cstates + NEW_CSTATES_COUNT; -#else - total_cstates = actual_cstates; -#endif - - for (i = 0; i < sfi_cpu_num; i++) { - pr = per_cpu(sfi_processors, i); - result = alloc_cstates(i, total_cstates); - if (result < 0) - dealloc_cstates(i); - memcpy(pr->power.sfi_cstates, pentry, - actual_cstates * sizeof(*pentry)); - pr->power.count = actual_cstates; - } - - return 0; -} - -static int __init init_sfi_processor_list(void) -{ - struct sfi_processor *pr; - int i; - int result; - - /* parse the cpus from the sfi table */ - result = sfi_table_parse(SFI_SIG_CPUS, NULL, NULL, parse_cpus); - - if (result < 0) - return result; - - pr = kzalloc(sfi_cpu_num * sizeof(struct sfi_processor), GFP_KERNEL); - if (!pr) - return -ENOMEM; - - for (i = 0; i < sfi_cpu_num; i++) { - pr->id = sfi_cpu_array[i].apic_id; - per_cpu(sfi_processors, pr->id) = pr; - pr++; - } - - return 0; -} - -static int __init sfi_processor_init(void) -{ - struct sfi_processor *pr; - int i; - int result; - - result = init_sfi_processor_list(); - if (result) - return result; - - /* parse the cpu idle states */ - result = sfi_table_parse(SFI_SIG_IDLE, NULL, NULL, parse_idle); - - if (result < 0) - return result; - - result = cpuidle_register_driver(&sfi_idle_driver); - if (!result) { - for (i = 0; i < sfi_cpu_num; i++) { - pr = per_cpu(sfi_processors, i); - if (pr) { - result = sfi_processor_power_init(pr); - if (result) - break; - } - } - if (result) - cpuidle_unregister_driver(&sfi_idle_driver); - } else - printk(KERN_ERR "Failed to register cpuidle driver: %s\n", - sfi_idle_driver.name); - - return result; -} - -static void __exit sfi_processor_exit(void) -{ - struct sfi_processor *pr; - int i; - - for (i = 0; i < sfi_cpu_num; i++) { - pr = per_cpu(sfi_processors, i); - sfi_processor_power_exit(pr); - } - - pr = per_cpu(sfi_processors, 0); - kfree(pr); - - cpuidle_unregister_driver(&sfi_idle_driver); - -} - -module_init(sfi_processor_init); -module_exit(sfi_processor_exit); diff --git a/drivers/sfi/sfi_processor_idle.c b/drivers/sfi/sfi_processor_idle.c deleted file mode 100644 index ecf8f67..0000000 --- a/drivers/sfi/sfi_processor_idle.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * sfi_processor_idle.c - sfi based c-state driver - * Copyright (c) 2010, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <asm/processor.h> -#include <linux/sfi_processor.h> -#include <linux/sched.h> -#include <linux/clockchips.h> -#include <linux/sfi.h> - -#define MWAIT_SUBSTATE_MASK (0xf) -#define MWAIT_SUBSTATE_SIZE (4) - -#define CPUID_MWAIT_LEAF (5) -#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) -#define CPUID5_ECX_INTERRUPT_BREAK (0x2) - -#define MWAIT_ECX_INTERRUPT_BREAK (0x1) - -static unsigned int latency_factor __read_mostly = 4; -module_param(latency_factor, uint, 0644); - -static int sfi_idle_enter_deep(struct cpuidle_device *dev, - struct cpuidle_state *state); - -static int sfi_idle_enter_simple(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - ktime_t t1, t2; - s64 diff = 0; - struct sfi_cstate_table_entry *data; - - data = (struct sfi_cstate_table_entry *)cpuidle_get_statedata(state); - if (unlikely(!data)) - return 0; - - - local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; - } - - t1 = ktime_get(); - mwait_idle_with_hints(data->hint, MWAIT_ECX_INTERRUPT_BREAK); - t2 = ktime_get(); - - local_irq_enable(); - current_thread_info()->status |= TS_POLLING; - - diff = ktime_to_us(ktime_sub(t2, t1)); - if (diff > INT_MAX) - diff = INT_MAX; - - return (int)diff; -} - -static int sfi_idle_enter_deep(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - - ktime_t t1, t2; - s64 diff_us = 0; - s64 diff_ns = 0; - struct sfi_cstate_table_entry *data; - struct sfi_processor *pr; - - pr = __get_cpu_var(sfi_processors); - if (unlikely(!pr)) - return 0; - - data = (struct sfi_cstate_table_entry *)cpuidle_get_statedata(state); - if (unlikely(!data)) - return 0; - - local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; - } - - t1 = ktime_get(); - - /* Tell the scheduler that we are going deep-idle: */ - sched_clock_idle_sleep_event(); - - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &pr->id); - mwait_idle_with_hints(data->hint, MWAIT_ECX_INTERRUPT_BREAK); - - t2 = ktime_get(); - - diff_us = ktime_to_us(ktime_sub(t2, t1)); - diff_ns = ktime_to_ns(ktime_sub(t2, t1)); - - /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(diff_ns); - - local_irq_enable(); - current_thread_info()->status |= TS_POLLING; - - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &pr->id); - - if (diff_us > INT_MAX) - diff_us = INT_MAX; - - return (int)diff_us; - -} - -/** - * sfi_processor_setup_cpuidle - prepares and configures CPUIDLE - * @pr: the SFI processor - */ -static int sfi_processor_setup_cpuidle(struct sfi_processor *pr) -{ - int i; - struct cpuidle_state *state; - struct cpuidle_device *dev = &pr->power.dev; - static int cstates[] = {0, 1, 2, 4, 6}; - - for (i = 0; i < CPUIDLE_STATE_MAX; i++) { - dev->states[i].name[0] = '\0'; - dev->states[i].desc[0] = '\0'; - } - - for (i = 1; i <= pr->power.count; i++) { - - state = &dev->states[i]; - - snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", cstates[i]); - snprintf(state->desc, CPUIDLE_DESC_LEN, "C%d", cstates[i]); - - state->exit_latency = pr->power.states[i].exit_latency; - state->target_residency = state->exit_latency * latency_factor; - state->power_usage = pr->power.states[i].power_usage; - state->flags = 0; - cpuidle_set_statedata(state, &pr->power.sfi_cstates[i]); - - printk - (KERN_INFO "State details Name:%s, Desc:%s, \ - exit_latency:%d,target_residency%d,power_usage%d,hint%d", - state->name, state->desc, state->exit_latency, - state->target_residency, state->power_usage, - pr->power.sfi_cstates[i].hint); - - switch (i) { - case 1: - state->flags |= CPUIDLE_FLAG_SHALLOW; - state->enter = sfi_idle_enter_simple; - break; - - case 2: - state->flags |= CPUIDLE_FLAG_BALANCED; - state->flags |= CPUIDLE_FLAG_TIME_VALID; - state->enter = sfi_idle_enter_deep; - break; - - default: - state->flags |= CPUIDLE_FLAG_DEEP; - state->enter = sfi_idle_enter_deep; - break; - } - - } - - dev->state_count = i; - - return 0; -} - -int sfi_cstate_probe(unsigned int hint) -{ - int retval; - unsigned int eax, ebx, ecx, edx; - unsigned int edx_part; - unsigned int cstate_type; - unsigned int num_cstate_subtype; - - cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); - - /* Check whether this particular CState is supported or not */ - cstate_type = (hint >> MWAIT_SUBSTATE_SIZE) + 1; - edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE); - num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; - - retval = 0; - if (num_cstate_subtype < (hint & MWAIT_SUBSTATE_MASK)) { - retval = -1; - goto out; - } - - /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */ - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || - !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) { - retval = -1; - goto out; - } - -out: - return retval; -} - -int sfi_processor_power_init(struct sfi_processor *pr) -{ - - int totallen; - struct sfi_cstate_table_entry *pentry; - - pentry = pr->power.sfi_cstates; - - for (totallen = 1; totallen <= pr->power.count; totallen++, pentry++) { - pr->power.states[totallen].power_usage = 0; - pr->power.states[totallen].exit_latency = pentry->latency; - sfi_cstate_probe(pentry->hint); - printk(KERN_INFO "Cstate[%d]: hint = 0x%08x, latency = %dms\n", - totallen, pentry->hint, pentry->latency); - } - - sfi_processor_setup_cpuidle(pr); - pr->power.dev.cpu = pr->id; - if (cpuidle_register_device(&pr->power.dev)) - return -EIO; - - return 0; -} - -int sfi_processor_power_exit(struct sfi_processor *pr) -{ - cpuidle_unregister_device(&pr->power.dev); - return 0; -} diff --git a/drivers/sfi/sfi_processor_perflib.c b/drivers/sfi/sfi_processor_perflib.c deleted file mode 100644 index 39f9d27..0000000 --- a/drivers/sfi/sfi_processor_perflib.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * sfi_Processor_perflib.c - sfi Processor P-States Library - * - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Author: Vishwesh M Rudramuni - * Contact information: Vishwesh Rudramuni <[email protected]> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/cpufreq.h> -#include <linux/sfi.h> -#include <linux/sfi_processor.h> -#include <linux/slab.h> - -#define SFI_PROCESSOR_COMPONENT 0x01000000 -#define SFI_PROCESSOR_CLASS "processor" -#define SFI_PROCESSOR_FILE_PERFORMANCE "performance" -#define _COMPONENT SFI_PROCESSOR_COMPONENT -#define MSR_IA32_CLOCK_CR_GEYSIII_VCC_3 0xcf -#define GRD_RATIO_900 9 -#define GRD_RATIO_1100 0xb -#define CTRL_VAL_900 0x90c -#define CTRL_VAL_1100 0xb14 -#define GRD_VID_MASK 0x3F -#define GRD_BUS_RATIO_MASK 0xF - - -static DEFINE_MUTEX(performance_mutex); - -/* Use cpufreq debug layer for _PPC changes. */ -#define cpufreq_printk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \ - "cpufreq-core", msg) - -#define SFI_FREQ_MAX 32 -struct sfi_freq_table_entry sfi_cpufreq_array[SFI_FREQ_MAX]; -int g_sfi_cpufreq_num; - -static int __init parse_freq(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - struct sfi_freq_table_entry *pentry; - int totallen; - - sb = (struct sfi_table_simple *)table; - if (!sb) { - printk(KERN_WARNING "SFI: Unable to map FREQ\n"); - return -ENODEV; - } - - if (!g_sfi_cpufreq_num) { - g_sfi_cpufreq_num = SFI_GET_NUM_ENTRIES(sb, - struct sfi_freq_table_entry); - pentry = (struct sfi_freq_table_entry *)sb->pentry; - totallen = g_sfi_cpufreq_num * sizeof(*pentry); - memcpy(sfi_cpufreq_array, pentry, totallen); - } - - return 0; -} - -static int sfi_processor_get_performance_states(struct sfi_processor *pr) -{ - int result = 0; - int i; - unsigned int l, h; - unsigned int grd_vid, grd_ratio; - - pr->performance->state_count = g_sfi_cpufreq_num; - pr->performance->states = - kmalloc(sizeof(struct sfi_processor_px) * g_sfi_cpufreq_num, - GFP_KERNEL); - if (!pr->performance->states) - result = -ENOMEM; - - printk(KERN_INFO "Num p-states %d\n", g_sfi_cpufreq_num); - - /* Populate the P-states info from the SFI table here */ - for (i = 0; i < g_sfi_cpufreq_num; i++) { - pr->performance->states[i].core_frequency = \ - sfi_cpufreq_array[i].freq_mhz; - pr->performance->states[i].transition_latency = \ - sfi_cpufreq_array[i].latency; - pr->performance->states[i].control = \ - sfi_cpufreq_array[i].ctrl_val; - printk(KERN_INFO "State [%d]: core_frequency[%d] \ - transition_latency[%d] \ - control[0x%x] status[0x%x]\n", i, - (u32) pr->performance->states[i].core_frequency, - (u32) pr->performance->states[i].transition_latency, - (u32) pr->performance->states[i].control, - (u32) pr->performance->states[i].status); - } - - /* program the GFM when the cpu's are initialized */ - rdmsr(MSR_IA32_CLOCK_CR_GEYSIII_VCC_3, l, h); - grd_vid = (l >> 12) & GRD_VID_MASK; - grd_ratio = (l >> 7) & GRD_BUS_RATIO_MASK; - - /* program the control values for GFM */ - if (grd_ratio == GRD_RATIO_900) - l = CTRL_VAL_900; - else if (grd_ratio == GRD_RATIO_1100) - l = CTRL_VAL_1100; - - h = 0; - - /* write the value to change the freq to GFM */ - wrmsr(MSR_IA32_PERF_CTL, l, h); - - return result; -} - -int -sfi_processor_register_performance(struct sfi_processor_performance - *performance, unsigned int cpu) -{ - struct sfi_processor *pr; - - mutex_lock(&performance_mutex); - - pr = per_cpu(sfi_processors, cpu); - if (!pr) { - mutex_unlock(&performance_mutex); - return -ENODEV; - } - - if (pr->performance) { - mutex_unlock(&performance_mutex); - return -EBUSY; - } - - WARN_ON(!performance); - - pr->performance = performance; - - /* parse the freq table from sfi */ - g_sfi_cpufreq_num = 0; - sfi_table_parse(SFI_SIG_FREQ, NULL, NULL, parse_freq); - - sfi_processor_get_performance_states(pr); - - mutex_unlock(&performance_mutex); - return 0; -} -EXPORT_SYMBOL(sfi_processor_register_performance); - -void -sfi_processor_unregister_performance(struct sfi_processor_performance - *performance, unsigned int cpu) -{ - struct sfi_processor *pr; - - - mutex_lock(&performance_mutex); - - pr = per_cpu(sfi_processors, cpu); - if (!pr) { - mutex_unlock(&performance_mutex); - return; - } - - if (pr->performance) - kfree(pr->performance->states); - pr->performance = NULL; - - mutex_unlock(&performance_mutex); - - return; -} -EXPORT_SYMBOL(sfi_processor_unregister_performance); -- 1.7.2.3
0001-Removing-SFI-C-and-P-state-divers.patch
Description: 0001-Removing-SFI-C-and-P-state-divers.patch
_______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
