All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dominik Brodowski <linux@brodo.de>
To: torvalds@transmeta.com
Cc: hpa@transmeta.com, linux-kernel@vger.kernel.org,
	cpufreq@www.linux.org.uk
Subject: [PATCH][2.5.35] CPUfreq /proc/sys/ API emulation (5/5)
Date: Tue, 17 Sep 2002 11:37:06 +0200	[thread overview]
Message-ID: <20020917113706.J25385@brodo.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 15012 bytes --]

CPUFreq 24-API add-on patch for 2.5.35:
kernel/cpufreq.c	cpufreq-24-API
include/linux/cpufreq.h	cpufreq-24-API
arch/i386/config.in	Transmeta LongRun does not work well with cpufreq-24-API
arch/i386/Config.help	help text for CONFIG_CPU_FREQ_24_API


diff -ruN linux-2535original/arch/i386/Config.help linux/arch/i386/Config.help
--- linux-2535original/arch/i386/Config.help	Tue Sep 17 10:35:43 2002
+++ linux/arch/i386/Config.help	Tue Sep 17 10:36:23 2002
@@ -850,6 +850,19 @@
 
   If in doubt, say N.
 
+CONFIG_CPU_FREQ_24_API
+  This enables the /proc/sys/cpu/ sysctl interface for controlling
+  CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. Note
+  that some drivers do not support this interface or offer less
+  functionality. 
+
+  If you say N here, you'll be able to control CPUFreq using the
+  new /proc/cpufreq interface.
+
+  For details, take a look at linux/Documentation/cpufreq. 
+
+  If in doubt, say N.
+
 CONFIG_X86_POWERNOW_K6
   This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
   AMD K6-3+ processors.
diff -ruN linux-2535original/arch/i386/config.in linux/arch/i386/config.in
--- linux-2535original/arch/i386/config.in	Tue Sep 17 10:35:43 2002
+++ linux/arch/i386/config.in	Tue Sep 17 10:36:16 2002
@@ -192,7 +192,10 @@
 
 bool 'CPU Frequency scaling' CONFIG_CPU_FREQ
 if [ "$CONFIG_CPU_FREQ" = "y" ]; then
-   define_bool CONFIG_CPU_FREQ_26_API y
+   bool ' /proc/sys/cpu/ interface (2.4.)' CONFIG_CPU_FREQ_24_API
+   if [ "$CONFIG_CPU_FREQ_24_API" = "n" ]; then
+       define_bool CONFIG_CPU_FREQ_26_API y
+   fi
    tristate ' AMD Mobile K6-2/K6-3 PowerNow!' CONFIG_X86_POWERNOW_K6
    if [ "$CONFIG_MELAN" = "y" ]; then
        tristate ' AMD Elan' CONFIG_ELAN_CPUFREQ
@@ -200,7 +203,9 @@
    tristate ' VIA Cyrix III Longhaul' CONFIG_X86_LONGHAUL
    tristate ' Intel Speedstep' CONFIG_X86_SPEEDSTEP
    tristate ' Intel Pentium 4 clock modulation' CONFIG_X86_P4_CLOCKMOD
-   tristate ' Transmeta LongRun' CONFIG_X86_LONGRUN
+   if [ "$CONFIG_CPU_FREQ_24_API" = "n" ]; then
+       tristate ' Transmeta LongRun' CONFIG_X86_LONGRUN
+   fi
 fi
 
 tristate 'Toshiba Laptop support' CONFIG_TOSHIBA
diff -ruN linux-2535original/include/linux/cpufreq.h linux/include/linux/cpufreq.h
--- linux-2535original/include/linux/cpufreq.h	Tue Sep 17 10:35:43 2002
+++ linux/include/linux/cpufreq.h	Tue Sep 17 10:35:57 2002
@@ -155,4 +155,98 @@
 #endif
 
 
+#ifdef CONFIG_CPU_FREQ_24_API
+/*********************************************************************
+ *                        CPUFREQ 2.4. INTERFACE                     *
+ *********************************************************************/
+int cpufreq_setmax(unsigned int cpu);
+#ifdef CONFIG_PM
+int cpufreq_restore(void);
+#endif
+int cpufreq_set(unsigned int kHz, unsigned int cpu);
+unsigned int cpufreq_get(unsigned int cpu);
+
+/* /proc/sys/cpu */
+enum {
+	CPU_NR   = 1,           /* compatibilty reasons */
+	CPU_NR_0 = 1,
+	CPU_NR_1 = 2,
+	CPU_NR_2 = 3,
+	CPU_NR_3 = 4,
+	CPU_NR_4 = 5,
+	CPU_NR_5 = 6,
+	CPU_NR_6 = 7,
+	CPU_NR_7 = 8,
+	CPU_NR_8 = 9,
+	CPU_NR_9 = 10,
+	CPU_NR_10 = 11,
+	CPU_NR_11 = 12,
+	CPU_NR_12 = 13,
+	CPU_NR_13 = 14,
+	CPU_NR_14 = 15,
+	CPU_NR_15 = 16,
+	CPU_NR_16 = 17,
+	CPU_NR_17 = 18,
+	CPU_NR_18 = 19,
+	CPU_NR_19 = 20,
+	CPU_NR_20 = 21,
+	CPU_NR_21 = 22,
+	CPU_NR_22 = 23,
+	CPU_NR_23 = 24,
+	CPU_NR_24 = 25,
+	CPU_NR_25 = 26,
+	CPU_NR_26 = 27,
+	CPU_NR_27 = 28,
+	CPU_NR_28 = 29,
+	CPU_NR_29 = 30,
+	CPU_NR_30 = 31,
+	CPU_NR_31 = 32,
+};
+
+/* /proc/sys/cpu/{0,1,...,(NR_CPUS-1)} */
+enum {
+	CPU_NR_FREQ_MAX = 1,
+	CPU_NR_FREQ_MIN = 2,
+	CPU_NR_FREQ = 3,
+};
+
+#define CTL_CPU_VARS_SPEED_MAX { \
+                ctl_name: CPU_NR_FREQ_MAX, \
+                data: &cpu_max_freq, \
+                procname: "speed-max", \
+                maxlen:	sizeof(cpu_max_freq),\
+                mode: 0444, \
+                proc_handler: proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED_MIN { \
+                ctl_name: CPU_NR_FREQ_MIN, \
+                data: &cpu_min_freq, \
+                procname: "speed-min", \
+                maxlen:	sizeof(cpu_min_freq),\
+                mode: 0444, \
+                proc_handler: proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED(cpunr) { \
+                ctl_name: CPU_NR_FREQ, \
+                procname: "speed", \
+                mode: 0644, \
+                proc_handler: cpufreq_procctl, \
+                strategy: cpufreq_sysctl, \
+                extra1: (void*) (cpunr), }
+
+#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
+                CTL_CPU_VARS_SPEED_MAX, \
+                CTL_CPU_VARS_SPEED_MIN, \
+                CTL_CPU_VARS_SPEED(cpunr),  \
+                { ctl_name: 0, }, }
+
+/* the ctl_table entry for each CPU */
+#define CPU_ENUM(s) { \
+                ctl_name: (CPU_NR + s), \
+                procname: #s, \
+                mode: 0555, \
+                child: ctl_cpu_vars_##s }
+
+#endif /* CONFIG_CPU_FREQ_24_API */
+
 #endif /* _LINUX_CPUFREQ_H */
diff -ruN linux-2535original/kernel/cpufreq.c linux/kernel/cpufreq.c
--- linux-2535original/kernel/cpufreq.c	Tue Sep 17 10:35:43 2002
+++ linux/kernel/cpufreq.c	Tue Sep 17 10:36:02 2002
@@ -28,6 +28,9 @@
 #include <linux/proc_fs.h>
 #endif
 
+#ifdef CONFIG_CPU_FREQ_24_API
+#include <linux/sysctl.h>
+#endif
 
 
 /**
@@ -65,6 +68,16 @@
 };
 
 
+#ifdef CONFIG_CPU_FREQ_24_API
+/**
+ * A few values needed by the 2.4.-compatible API
+ */
+static unsigned int     cpu_max_freq;
+static unsigned int     cpu_min_freq;
+static unsigned int     cpu_cur_freq[NR_CPUS];
+#endif
+
+
 
 /*********************************************************************
  *                              2.6. API                             *
@@ -327,6 +340,389 @@
 
 
 /*********************************************************************
+ *                        2.4. COMPATIBLE API                        *
+ *********************************************************************/
+
+#ifdef CONFIG_CPU_FREQ_24_API
+/* NOTE #1: when you use this API, you may not use any other calls,
+ * except cpufreq_[un]register_notifier, of course.
+ */
+
+/** 
+ * cpufreq_set - set the CPU frequency
+ * @freq: target frequency in kHz
+ * @cpu: CPU for which the frequency is to be set
+ *
+ * Sets the CPU frequency to freq.
+ */
+int cpufreq_set(unsigned int freq, unsigned int cpu)
+{
+	struct cpufreq_policy policy;
+	down(&cpufreq_driver_sem);
+	if (!cpufreq_driver || !cpu_max_freq) {
+		up(&cpufreq_driver_sem);
+		return -EINVAL;
+	}
+
+	policy.min = freq;
+	policy.max = freq;
+	policy.policy = CPUFREQ_POLICY_POWERSAVE;
+	policy.cpu = cpu;
+	
+	up(&cpufreq_driver_sem);
+
+	return cpufreq_set_policy(&policy);
+}
+EXPORT_SYMBOL_GPL(cpufreq_set);
+
+
+/** 
+ * cpufreq_setmax - set the CPU to the maximum frequency
+ * @cpu - affected cpu;
+ *
+ * Sets the CPU frequency to the maximum frequency supported by
+ * this CPU.
+ */
+int cpufreq_setmax(unsigned int cpu)
+{
+	if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
+		return -EINVAL;
+	return cpufreq_set(cpu_max_freq, cpu);
+}
+EXPORT_SYMBOL_GPL(cpufreq_setmax);
+
+
+/** 
+ * cpufreq_get - get the current CPU frequency (in kHz)
+ * @cpu: CPU number - currently without effect.
+ *
+ * Get the CPU current (static) CPU frequency
+ */
+unsigned int cpufreq_get(unsigned int cpu)
+{
+	if (!cpu_online(cpu))
+		return -EINVAL;
+	return cpu_cur_freq[cpu];
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+
+#ifdef CONFIG_SYSCTL
+
+
+/*********************** cpufreq_sysctl interface ********************/
+static int
+cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
+		void *buffer, size_t *lenp)
+{
+	char buf[16], *p;
+	int cpu = (int) ctl->extra1;
+	int len, left = *lenp;
+
+	if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
+		*lenp = 0;
+		return 0;
+	}
+
+	if (write) {
+		unsigned int freq;
+
+		len = left;
+		if (left > sizeof(buf))
+			left = sizeof(buf);
+		if (copy_from_user(buf, buffer, left))
+			return -EFAULT;
+		buf[sizeof(buf) - 1] = '\0';
+
+		freq = simple_strtoul(buf, &p, 0);
+		cpufreq_set(freq, cpu);
+	} else {
+		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
+		if (len > left)
+			len = left;
+		if (copy_to_user(buffer, buf, len))
+			return -EFAULT;
+	}
+
+	*lenp = len;
+	filp->f_pos += len;
+	return 0;
+}
+
+static int
+cpufreq_sysctl(ctl_table *table, int *name, int nlen,
+	       void *oldval, size_t *oldlenp,
+	       void *newval, size_t newlen, void **context)
+{
+	int cpu = (int) table->extra1;
+
+	if (!cpu_online(cpu))
+		return -EINVAL;
+
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
+		    put_user(sizeof(unsigned int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		unsigned int freq;
+
+		if (newlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (get_user(freq, (unsigned int *)newval))
+			return -EFAULT;
+
+		cpufreq_set(freq, cpu);
+	}
+	return 1;
+}
+
+/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+        CTL_TABLE_CPU_VARS(0);
+#if NR_CPUS > 1
+	CTL_TABLE_CPU_VARS(1);
+#endif
+#if NR_CPUS > 2
+	CTL_TABLE_CPU_VARS(2);
+#endif
+#if NR_CPUS > 3
+	CTL_TABLE_CPU_VARS(3);
+#endif
+#if NR_CPUS > 4
+	CTL_TABLE_CPU_VARS(4);
+#endif
+#if NR_CPUS > 5
+	CTL_TABLE_CPU_VARS(5);
+#endif
+#if NR_CPUS > 6
+	CTL_TABLE_CPU_VARS(6);
+#endif
+#if NR_CPUS > 7
+	CTL_TABLE_CPU_VARS(7);
+#endif
+#if NR_CPUS > 8
+	CTL_TABLE_CPU_VARS(8);
+#endif
+#if NR_CPUS > 9
+	CTL_TABLE_CPU_VARS(9);
+#endif
+#if NR_CPUS > 10
+	CTL_TABLE_CPU_VARS(10);
+#endif
+#if NR_CPUS > 11
+	CTL_TABLE_CPU_VARS(11);
+#endif
+#if NR_CPUS > 12
+	CTL_TABLE_CPU_VARS(12);
+#endif
+#if NR_CPUS > 13
+	CTL_TABLE_CPU_VARS(13);
+#endif
+#if NR_CPUS > 14
+	CTL_TABLE_CPU_VARS(14);
+#endif
+#if NR_CPUS > 15
+	CTL_TABLE_CPU_VARS(15);
+#endif
+#if NR_CPUS > 16
+	CTL_TABLE_CPU_VARS(16);
+#endif
+#if NR_CPUS > 17
+	CTL_TABLE_CPU_VARS(17);
+#endif
+#if NR_CPUS > 18
+	CTL_TABLE_CPU_VARS(18);
+#endif
+#if NR_CPUS > 19
+	CTL_TABLE_CPU_VARS(19);
+#endif
+#if NR_CPUS > 20
+	CTL_TABLE_CPU_VARS(20);
+#endif
+#if NR_CPUS > 21
+	CTL_TABLE_CPU_VARS(21);
+#endif
+#if NR_CPUS > 22
+	CTL_TABLE_CPU_VARS(22);
+#endif
+#if NR_CPUS > 23
+	CTL_TABLE_CPU_VARS(23);
+#endif
+#if NR_CPUS > 24
+	CTL_TABLE_CPU_VARS(24);
+#endif
+#if NR_CPUS > 25
+	CTL_TABLE_CPU_VARS(25);
+#endif
+#if NR_CPUS > 26
+	CTL_TABLE_CPU_VARS(26);
+#endif
+#if NR_CPUS > 27
+	CTL_TABLE_CPU_VARS(27);
+#endif
+#if NR_CPUS > 28
+	CTL_TABLE_CPU_VARS(28);
+#endif
+#if NR_CPUS > 29
+	CTL_TABLE_CPU_VARS(29);
+#endif
+#if NR_CPUS > 30
+	CTL_TABLE_CPU_VARS(30);
+#endif
+#if NR_CPUS > 31
+	CTL_TABLE_CPU_VARS(31);
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
+	CPU_ENUM(0),
+#if NR_CPUS > 1
+	CPU_ENUM(1),
+#endif
+#if NR_CPUS > 2
+	CPU_ENUM(2),
+#endif
+#if NR_CPUS > 3
+	CPU_ENUM(3),
+#endif
+#if NR_CPUS > 4
+	CPU_ENUM(4),
+#endif
+#if NR_CPUS > 5
+	CPU_ENUM(5),
+#endif
+#if NR_CPUS > 6
+	CPU_ENUM(6),
+#endif
+#if NR_CPUS > 7
+	CPU_ENUM(7),
+#endif
+#if NR_CPUS > 8
+	CPU_ENUM(8),
+#endif
+#if NR_CPUS > 9
+	CPU_ENUM(9),
+#endif
+#if NR_CPUS > 10
+	CPU_ENUM(10),
+#endif
+#if NR_CPUS > 11
+	CPU_ENUM(11),
+#endif
+#if NR_CPUS > 12
+	CPU_ENUM(12),
+#endif
+#if NR_CPUS > 13
+	CPU_ENUM(13),
+#endif
+#if NR_CPUS > 14
+	CPU_ENUM(14),
+#endif
+#if NR_CPUS > 15
+	CPU_ENUM(15),
+#endif
+#if NR_CPUS > 16
+	CPU_ENUM(16),
+#endif
+#if NR_CPUS > 17
+	CPU_ENUM(17),
+#endif
+#if NR_CPUS > 18
+	CPU_ENUM(18),
+#endif
+#if NR_CPUS > 19
+	CPU_ENUM(19),
+#endif
+#if NR_CPUS > 20
+	CPU_ENUM(20),
+#endif
+#if NR_CPUS > 21
+	CPU_ENUM(21),
+#endif
+#if NR_CPUS > 22
+	CPU_ENUM(22),
+#endif
+#if NR_CPUS > 23
+	CPU_ENUM(23),
+#endif
+#if NR_CPUS > 24
+	CPU_ENUM(24),
+#endif
+#if NR_CPUS > 25
+	CPU_ENUM(25),
+#endif
+#if NR_CPUS > 26
+	CPU_ENUM(26),
+#endif
+#if NR_CPUS > 27
+	CPU_ENUM(27),
+#endif
+#if NR_CPUS > 28
+	CPU_ENUM(28),
+#endif
+#if NR_CPUS > 29
+	CPU_ENUM(29),
+#endif
+#if NR_CPUS > 30
+	CPU_ENUM(30),
+#endif
+#if NR_CPUS > 31
+	CPU_ENUM(31),
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+	{
+		ctl_name:	0,
+	}
+};
+
+static ctl_table ctl_cpu[2] = {
+	{
+		ctl_name:	CTL_CPU,
+		procname:	"cpu",
+		mode:		0555,
+		child:		ctl_cpu_table,
+	},
+	{
+		ctl_name:	0,
+	}
+};
+
+struct ctl_table_header *cpufreq_sysctl_table;
+
+static inline void cpufreq_sysctl_init(void)
+{
+	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
+}
+
+static inline void cpufreq_sysctl_exit(void)
+{
+	unregister_sysctl_table(cpufreq_sysctl_table);
+}
+
+#else
+#define cpufreq_sysctl_init()
+#define cpufreq_sysctl_exit()
+#endif /* CONFIG_SYSCTL */
+#endif /* CONFIG_CPU_FREQ_24_API */
+
+
+
+/*********************************************************************
  *                     NOTIFIER LISTS INTERFACE                      *
  *********************************************************************/
 
@@ -484,6 +880,14 @@
 		cpufreq_driver->policy[policy->cpu].policy = policy->policy;
 	}
 	
+#ifdef CONFIG_CPU_FREQ_24_API
+	if (policy->cpu == CPUFREQ_ALL_CPUS) {
+		for (i=0;i<NR_CPUS;i++)
+			cpu_cur_freq[i] = policy->max;
+	} else
+		cpu_cur_freq[policy->cpu] = policy->max;
+#endif
+
 	cpufreq_driver->setpolicy(policy);
 	
 	up(&cpufreq_driver_sem);
@@ -592,6 +996,20 @@
 	cpufreq_proc_init();
 #endif
 
+#ifdef CONFIG_CPU_FREQ_24_API
+	down(&cpufreq_driver_sem);
+	cpu_min_freq          = driver_data->cpu_min_freq;
+	cpu_max_freq          = driver_data->policy[0].max_cpu_freq;
+	{
+		unsigned int i;
+		for (i=0; i<NR_CPUS; i++) {
+			cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
+		}
+	}
+	up(&cpufreq_driver_sem);
+
+	cpufreq_sysctl_init();
+#endif
 	if (ret) {
 		down(&cpufreq_driver_sem);
 		cpufreq_driver = NULL;
@@ -628,6 +1046,10 @@
 	cpufreq_proc_exit();
 #endif
 
+#ifdef CONFIG_CPU_FREQ_24_API
+	cpufreq_sysctl_exit();
+#endif
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cpufreq_unregister);
@@ -666,6 +1088,10 @@
 
 #ifdef CONFIG_CPU_FREQ_26_API
 		cpufreq_set_policy(&policy);
+#endif
+
+#ifdef CONFIG_CPU_FREQ_24_API
+		cpufreq_set(cpu_cur_freq[i], i);
 #endif
 	}
 


[-- Attachment #2: Type: application/pgp-signature, Size: 240 bytes --]

                 reply	other threads:[~2002-09-17  9:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020917113706.J25385@brodo.de \
    --to=linux@brodo.de \
    --cc=cpufreq@www.linux.org.uk \
    --cc=hpa@transmeta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.