?? dpm-core-2.6.16.patch
字號:
Index: linux-2.6.16/arch/arm/Kconfig===================================================================--- linux-2.6.16.orig/arch/arm/Kconfig 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/arch/arm/Kconfig 2006-04-11 06:34:10.000000000 +0000@@ -832,3 +832,5 @@ source "crypto/Kconfig" source "lib/Kconfig"++source "drivers/dpm/Kconfig"Index: linux-2.6.16/arch/i386/Kconfig===================================================================--- linux-2.6.16.orig/arch/i386/Kconfig 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/arch/i386/Kconfig 2006-04-11 06:34:10.000000000 +0000@@ -908,6 +908,7 @@ endmenu source "arch/i386/kernel/cpu/cpufreq/Kconfig"+source "arch/i386/kernel/cpu/dpm/Kconfig" endmenu Index: linux-2.6.16/arch/i386/kernel/cpu/Makefile===================================================================--- linux-2.6.16.orig/arch/i386/kernel/cpu/Makefile 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/cpu/Makefile 2006-04-11 06:34:10.000000000 +0000@@ -17,3 +17,4 @@ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_CPU_FREQ) += cpufreq/+obj-$(CONFIG_DPM) += dpm/Index: linux-2.6.16/arch/i386/kernel/cpu/dpm/Kconfig===================================================================--- linux-2.6.16.orig/arch/i386/kernel/cpu/dpm/Kconfig 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/cpu/dpm/Kconfig 2006-04-11 06:34:10.000000000 +0000@@ -0,0 +1,10 @@+#+# Dynamic Power Management+#++source "drivers/dpm/Kconfig"++config DPM_CENTRINO+ tristate "DPM for Intel Centrino Enhanced Speedstep"+ depends on DPM+ default nIndex: linux-2.6.16/arch/i386/kernel/cpu/dpm/Makefile===================================================================--- linux-2.6.16.orig/arch/i386/kernel/cpu/dpm/Makefile 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/cpu/dpm/Makefile 2006-04-11 06:34:10.000000000 +0000@@ -0,0 +1,3 @@+obj-$(CONFIG_DPM) += x86_dpm.o+obj-$(CONFIG_DPM_CENTRINO) += centrino_dpm.o+Index: linux-2.6.16/arch/i386/kernel/cpu/dpm/centrino_dpm.c===================================================================--- linux-2.6.16.orig/arch/i386/kernel/cpu/dpm/centrino_dpm.c 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/cpu/dpm/centrino_dpm.c 2006-04-11 06:34:10.000000000 +0000@@ -0,0 +1,133 @@+/*+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the+ * terms of the GNU General Public License version 2. This program is+ * licensed "as is" without any warranty of any kind, whether express+ * or implied.+ *+ * Based on speedstep-centrino.c by Jeremy Fitzhardinge <jeremy@goop.org>+ */++#include <linux/config.h>+#include <linux/dpm.h>+#include <linux/errno.h>+#include <linux/init.h>+#include <linux/kernel.h>+#include <linux/delay.h>++#include <asm/msr.h>+#include <asm/processor.h>+#include <asm/cpufeature.h>++/* Extract clock in kHz from PERF_CTL value */+static unsigned extract_clock(unsigned msr)+{+ msr = (msr >> 8) & 0xff;+ return msr * 100000;+}++/* Return the current CPU frequency in kHz */+static unsigned get_cur_freq(void)+{+ unsigned l, h;++ rdmsr(MSR_IA32_PERF_STATUS, l, h);+ return extract_clock(l);+}++static int+dpm_centrino_init_opt(struct dpm_opt *opt)+{+ int v = opt->pp[DPM_MD_V];+ int cpu = opt->pp[DPM_MD_CPU_FREQ];++ struct dpm_md_opt *md_opt = &opt->md_opt;++ md_opt->v = v;+ md_opt->cpu = cpu;+ return 0;+}++/* Fully determine the current machine-dependent operating point, and fill in a+ structure presented by the caller. This should only be called when the+ dpm_sem is held. This call can return an error if the system is currently at+ an operating point that could not be constructed by dpm_md_init_opt(). */++static int+dpm_centrino_get_opt(struct dpm_opt *opt)+{+ struct dpm_md_opt *md_opt = &opt->md_opt;++ md_opt->v = 100; /* TODO. */+ md_opt->cpu = get_cur_freq();+ return 0;+}++static int+dpm_centrino_set_opt(struct dpm_md_opt *md_opt)+{+ unsigned int msr = 0, oldmsr, h, mask = 0;++ if (md_opt->cpu != -1) {+ msr |= ((md_opt->cpu)/100) << 8;+ mask |= 0xff00;+ }++ if (md_opt->v != -1) {+ msr |= ((md_opt->v - 700) / 16);+ mask |= 0xff;+ }++ rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);++ if (msr == (oldmsr & mask))+ return 0;++ /* all but 16 LSB are "reserved", so treat them with+ care */+ oldmsr &= ~mask;+ msr &= mask;+ oldmsr |= msr;++ wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);+ return 0;+}++static int dpm_centrino_startup(void)+{+ struct cpuinfo_x86 *cpu = cpu_data;+ unsigned l, h;++ if (!cpu_has(cpu, X86_FEATURE_EST))+ return -ENODEV;++ /* Check to see if Enhanced SpeedStep is enabled, and try to+ enable it if not. */+ rdmsr(MSR_IA32_MISC_ENABLE, l, h);++ if (!(l & (1<<16))) {+ l |= (1<<16);+ wrmsr(MSR_IA32_MISC_ENABLE, l, h);++ /* check to see if it stuck */+ rdmsr(MSR_IA32_MISC_ENABLE, l, h);+ if (!(l & (1<<16))) {+ printk(KERN_INFO "DPM: Couldn't enable Enhanced SpeedStep\n");+ return -ENODEV;+ }+ }++ return 0;+}++int __init dpm_centrino_init(void)+{+ printk("Dynamic Power Management for Intel Centrino Enhanced SpeedStep.\n");++ dpm_bd.startup = dpm_centrino_startup;+ dpm_bd.init_opt = dpm_centrino_init_opt;+ dpm_bd.get_opt = dpm_centrino_get_opt;+ dpm_bd.set_opt = dpm_centrino_set_opt;+ return 0;+}++__initcall(dpm_centrino_init);Index: linux-2.6.16/arch/i386/kernel/cpu/dpm/x86_dpm.c===================================================================--- linux-2.6.16.orig/arch/i386/kernel/cpu/dpm/x86_dpm.c 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/cpu/dpm/x86_dpm.c 2006-04-11 06:34:10.000000000 +0000@@ -0,0 +1,133 @@+/*+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the+ * terms of the GNU General Public License version 2. This program is+ * licensed "as is" without any warranty of any kind, whether express+ * or implied.+ */++#include <linux/config.h>+#include <linux/dpm.h>+#include <linux/errno.h>+#include <linux/init.h>+#include <linux/kernel.h>+#include <linux/delay.h>+#include <linux/interrupt.h>++#include <asm/page.h>+#include <asm/uaccess.h>++struct dpm_bd dpm_bd;++static int+dpm_x86_init_opt(struct dpm_opt *opt)+{+ return dpm_bd.init_opt ? dpm_bd.init_opt(opt) : -1;+}++/* Fully determine the current machine-dependent operating point, and fill in a+ structure presented by the caller. This should only be called when the+ dpm_sem is held. This call can return an error if the system is currently at+ an operating point that could not be constructed by dpm_md_init_opt(). */++static unsigned long loops_per_jiffy_ref = 0;++static int+dpm_x86_get_opt(struct dpm_opt *opt)+{+ return dpm_bd.get_opt ? dpm_bd.get_opt(opt) : -1;+}++int+dpm_x86_set_opt(struct dpm_opt *cur, struct dpm_opt *new)+{+ struct cpuinfo_x86 *cpu = cpu_data;++ if (! new->md_opt.cpu) {+#ifdef CONFIG_PM+ pm_suspend(PM_SUSPEND_STANDBY);++ /* Here when we wake up. Recursive call to switch back to+ * to task state.+ */++ dpm_set_os(DPM_TASK_STATE);+#endif+ return 0;+ }++ if (dpm_bd.set_opt){+ dpm_bd.set_opt(&new->md_opt);++ }else{+ return -1;+ }++ if (cur->md_opt.cpu && new->md_opt.cpu){+ loops_per_jiffy_ref = cpu->loops_per_jiffy;+ cpu->loops_per_jiffy =+ dpm_compute_lpj(loops_per_jiffy_ref ,+ cur->md_opt.cpu,+ new->md_opt.cpu);++ loops_per_jiffy = cpu->loops_per_jiffy;+ if (cpu_khz)+ cpu_khz = dpm_compute_lpj(cpu_khz,+ cur->md_opt.cpu,+ new->md_opt.cpu);+ }+ return 0;+}++/*+ * idle loop+ */++static void (*orig_idle)(void);++void dpm_x86_idle(void)+{+ extern void default_idle(void);++ if (orig_idle)+ orig_idle();+ else+ default_idle();+}++/****************************************************************************+ * Initialization/Exit+ ****************************************************************************/++void+dpm_x86_startup(void)+{+ orig_idle = pm_idle;+ pm_idle = dpm_idle;++ if (dpm_bd.startup)+ dpm_bd.startup();+}++void+dpm_x86_cleanup(void)+{+ pm_idle = orig_idle;++ if (dpm_bd.cleanup)+ dpm_bd.cleanup();+}++int __init+dpm_x86_init(void)+{+ printk("Dynamic Power Management for x86.\n");++ dpm_md.init_opt = dpm_x86_init_opt;+ dpm_md.set_opt = dpm_x86_set_opt;+ dpm_md.get_opt = dpm_x86_get_opt;+ dpm_md.idle = dpm_x86_idle;+ dpm_md.startup = dpm_x86_startup;+ dpm_md.cleanup = dpm_x86_cleanup;+ return 0;+}+__initcall(dpm_x86_init);Index: linux-2.6.16/arch/i386/kernel/process.c===================================================================--- linux-2.6.16.orig/arch/i386/kernel/process.c 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/arch/i386/kernel/process.c 2006-04-11 06:34:10.000000000 +0000@@ -58,6 +58,8 @@ #include <asm/tlbflush.h> #include <asm/cpu.h> +#include <linux/dpm.h>+ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); static int hlt_counter;@@ -697,6 +699,7 @@ disable_tsc(prev_p, next_p); + dpm_set_os(next_p->dpm_state); return prev_p; } Index: linux-2.6.16/drivers/Makefile===================================================================--- linux-2.6.16.orig/drivers/Makefile 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/drivers/Makefile 2006-04-11 06:34:10.000000000 +0000@@ -67,6 +67,7 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/+obj-$(CONFIG_DPM) += dpm/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/Index: linux-2.6.16/drivers/base/core.c===================================================================--- linux-2.6.16.orig/drivers/base/core.c 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/drivers/base/core.c 2006-04-11 06:34:10.000000000 +0000@@ -282,6 +282,8 @@ if (parent) klist_add_tail(&dev->knode_parent, &parent->klist_children); + assert_constraints(dev->constraints);+ /* notify platform of device entry */ if (platform_notify) platform_notify(dev);@@ -367,6 +369,8 @@ klist_del(&dev->knode_parent); device_remove_file(dev, &dev->uevent_attr); + deassert_constraints(dev->constraints);+ /* Notify the platform of the removal, in case they * need to do anything... */Index: linux-2.6.16/drivers/base/power/Makefile===================================================================--- linux-2.6.16.orig/drivers/base/power/Makefile 2006-03-20 05:53:29.000000000 +0000+++ linux-2.6.16/drivers/base/power/Makefile 2006-04-11 06:34:10.000000000 +0000@@ -1,4 +1,4 @@-obj-y := shutdown.o+obj-y := shutdown.o power-dpm.o obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o ifeq ($(CONFIG_DEBUG_DRIVER),y)Index: linux-2.6.16/drivers/base/power/power-dpm.c===================================================================--- linux-2.6.16.orig/drivers/base/power/power-dpm.c 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.16/drivers/base/power/power-dpm.c 2006-04-11 06:35:28.000000000 +0000@@ -0,0 +1,473 @@+/*+ * power-dpm.c -- Dynamic Power Management LDM power hooks+ *+ * (c) 2003 MontaVista Software, Inc. This file is licensed under the+ * terms of the GNU General Public License version 2. This program is+ * licensed "as is" without any warranty of any kind, whether express or+ * implied.+ */++#include <linux/device.h>+#include <linux/pm.h>+#include <linux/dpm.h>+#include <linux/sched.h>+#include <linux/init.h>+#include <linux/mm.h>+#include <linux/slab.h>++#include "power.h"++/*+ * power hotplug events+ */++#define BUFFER_SIZE 1024 /* should be enough memory for the env */+#define NUM_ENVP 32 /* number of env pointers */+static unsigned long sequence_num;+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;++void power_event(char *eventstr)+{+ char *argv [3];+ char **envp = NULL;+ char *buffer = NULL;+ char *scratch;+ int i = 0;+ int retval;+ unsigned long seq;++ if (!uevent_helper[0])+ return;++ envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);+ if (!envp)+ return;+ memset (envp, 0x00, NUM_ENVP * sizeof (char *));++ buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);+ if (!buffer)+ goto exit;++ argv [0] = uevent_helper;+ argv [1] = "power";+ argv [2] = 0;++ /* minimal command environment */+ envp [i++] = "HOME=/";+ envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";++ scratch = buffer;++ envp [i++] = scratch;+ scratch += sprintf(scratch, "ACTION=event") + 1;++ spin_lock(&sequence_lock);+ seq = sequence_num++;+ spin_unlock(&sequence_lock);++ envp [i++] = scratch;+ scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1;+ envp [i++] = scratch;+ scratch += sprintf(scratch, "EVENT=%s", eventstr) + 1;++ pr_debug ("%s: %s %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],+ envp[0], envp[1], envp[2], envp[3], envp[4]);+ retval = call_usermodehelper (argv[0], argv, envp, 0);+ if (retval)+ pr_debug ("%s - call_usermodehelper returned %d\n",+ __FUNCTION__, retval);++exit:+ kfree(buffer);+ kfree(envp);+ return;+}++void device_power_event(struct device * dev, char *eventstr)+{+ char *argv [3];+ char **envp = NULL;+ char *buffer = NULL;+ char *scratch;+ int i = 0;+ int retval;+ unsigned long seq;++ if (!uevent_helper[0])+ return;++ envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);+ if (!envp)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -