Fwd: [PATCH] cpufreq (1/7): fix cpufreq core breakage(s)

Russell King (rmk@arm.linux.org.uk)
Sun, 9 Mar 2003 19:36:22 +0000


----- Forwarded message from Dominik Brodowski <linux@brodo.de> -----

From: Dominik Brodowski <linux@brodo.de>
To: torvalds@transmeta.com
Cc: cpufreq@www.linux.org.uk
Subject: [PATCH] cpufreq (1/7): fix cpufreq core breakage(s)
Date: Fri, 7 Mar 2003 11:08:26 +0100

- update two more cpufreq-related sysfs files to the new interface
code
- always store the new, user-requested policy in another struct
cpufreq_policy so that we can safely fall back to the old one in
case something fails (this equals the behaviour before Pat's patch)
- the kobject which was registered in cpufreq_add_dev was inside a variable
private to this function -- so the whole cpufreq sysfs interface returned
-EINVAL.

cpufreq.c | 136 ++++++++++++++++++++++++++++++++------------------------------
1 files changed, 71 insertions(+), 65 deletions(-)
(only so large as some code had to be moved up in order to avoid
forward declarations)

Please apply,
Dominik

--- linux-original/kernel/cpufreq.c 2003-03-07 10:54:08.000000000 +0100
+++ linux/kernel/cpufreq.c 2003-03-07 10:56:53.000000000 +0100
@@ -143,12 +143,17 @@
(struct cpufreq_policy * policy, const char *buf, size_t count) \
{ \
unsigned int ret = -EINVAL; \
+ struct cpufreq_policy new_policy; \
\
- ret = sscanf (buf, "%u", &policy->object); \
+ ret = cpufreq_get_policy(&new_policy, policy->cpu); \
+ if (ret) \
+ return ret; \
+ \
+ ret = sscanf (buf, "%u", &new_policy.object); \
if (ret != 1) \
return -EINVAL; \
\
- ret = cpufreq_set_policy(policy); \
+ ret = cpufreq_set_policy(&new_policy); \
\
return ret ? ret : count; \
}
@@ -192,19 +197,64 @@
{
unsigned int ret = -EINVAL;
char str_governor[16];
+ struct cpufreq_policy new_policy;
+
+ ret = cpufreq_get_policy(&new_policy, policy->cpu);
+ if (ret)
+ return ret;

ret = sscanf (buf, "%15s", str_governor);
if (ret != 1)
return -EINVAL;

- if (cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor))
+ if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
return -EINVAL;

- ret = cpufreq_set_policy(policy);
+ ret = cpufreq_set_policy(&new_policy);

return ret ? ret : count;
}

+/**
+ * show_scaling_driver - show the cpufreq driver currently loaded
+ */
+static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
+{
+ char value[CPUFREQ_NAME_LEN];
+
+ down(&cpufreq_driver_sem);
+ if (cpufreq_driver)
+ strncpy(value, cpufreq_driver->name, CPUFREQ_NAME_LEN);
+ up(&cpufreq_driver_sem);
+
+ return sprintf(buf, "%s\n", value);
+}
+
+/**
+ * show_scaling_available_governors - show the available CPUfreq governors
+ */
+static ssize_t show_scaling_available_governors(struct cpufreq_policy * policy, char *buf)
+{
+ ssize_t i = 0;
+ struct cpufreq_governor *t;
+
+ i += sprintf(buf, "performance powersave");
+
+ down(&cpufreq_driver_sem);
+ if (!cpufreq_driver || !cpufreq_driver->target)
+ goto out;
+
+ list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
+ if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
+ goto out;
+ i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name);
+ }
+ out:
+ up(&cpufreq_driver_sem);
+ i += sprintf(&buf[i], "\n");
+ return i;
+}
+

struct freq_attr {
struct attribute attr;
@@ -227,6 +277,8 @@

define_one_ro(cpuinfo_min_freq);
define_one_ro(cpuinfo_max_freq);
+define_one_ro(scaling_available_governors);
+define_one_ro(scaling_driver);
define_one_rw(scaling_min_freq);
define_one_rw(scaling_max_freq);
define_one_rw(scaling_governor);
@@ -237,6 +289,8 @@
&scaling_min_freq.attr,
&scaling_max_freq.attr,
&scaling_governor.attr,
+ &scaling_driver.attr,
+ &scaling_available_governors.attr,
NULL
};

@@ -271,56 +325,6 @@


/**
- * show_scaling_governor - show the current policy for the specified CPU
- */
-static ssize_t show_scaling_driver (struct device *dev, char *buf)
-{
- char value[CPUFREQ_NAME_LEN];
-
- if (!dev)
- return 0;
-
- down(&cpufreq_driver_sem);
- if (cpufreq_driver)
- strncpy(value, cpufreq_driver->name, CPUFREQ_NAME_LEN);
- up(&cpufreq_driver_sem);
-
- return sprintf(buf, "%s\n", value);
-}
-
-/**
- * show_available_govs - show the available CPUfreq governors
- */
-static ssize_t show_available_govs(struct device *dev, char *buf)
-{
- ssize_t i = 0;
- struct cpufreq_governor *t;
-
- if (!dev)
- return 0;
-
- i += sprintf(buf, "performance powersave");
-
- down(&cpufreq_driver_sem);
- if (!cpufreq_driver || !cpufreq_driver->target)
- goto out;
-
- list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
- if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
- goto out;
- i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name);
- }
- out:
- up(&cpufreq_driver_sem);
- i += sprintf(&buf[i], "\n");
- return i;
-}
-
-
-static DEVICE_ATTR(scaling_driver, S_IRUGO, show_scaling_driver, NULL);
-static DEVICE_ATTR(available_scaling_governors, S_IRUGO, show_available_govs, NULL);
-
-/**
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
@@ -329,7 +333,8 @@
{
unsigned int cpu = to_cpu_nr(dev);
int ret = 0;
- struct cpufreq_policy policy;
+ struct cpufreq_policy new_policy;
+ struct cpufreq_policy *policy;

down(&cpufreq_driver_sem);
if (!cpufreq_driver) {
@@ -340,9 +345,10 @@
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
- cpufreq_driver->policy[cpu].cpu = cpu;
+ policy = &cpufreq_driver->policy[cpu];
+ policy->cpu = cpu;
if (cpufreq_driver->init) {
- ret = cpufreq_driver->init(&cpufreq_driver->policy[cpu]);
+ ret = cpufreq_driver->init(policy);
if (ret) {
up(&cpufreq_driver_sem);
return -ENODEV;
@@ -350,34 +356,27 @@
}

/* set default policy on this CPU */
- memcpy(&policy,
- &cpufreq_driver->policy[cpu],
+ memcpy(&new_policy,
+ policy,
sizeof(struct cpufreq_policy));

- /* 2.4-API init for this CPU */
-#ifdef CONFIG_CPU_FREQ_24_API
- cpu_min_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
- cpu_max_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
- cpu_cur_freq[cpu] = cpufreq_driver->cpu_cur_freq[cpu];
-#endif
-
if (cpufreq_driver->target)
cpufreq_governor(cpu, CPUFREQ_GOV_START);

up(&cpufreq_driver_sem);
- ret = cpufreq_set_policy(&policy);
+ ret = cpufreq_set_policy(&new_policy);
if (ret)
return -EINVAL;
down(&cpufreq_driver_sem);

/* prepare interface data */
- policy.kobj.parent = &dev->kobj;
- policy.kobj.ktype = &ktype_cpufreq;
- policy.dev = dev;
- strncpy(policy.kobj.name,
+ policy->kobj.parent = &dev->kobj;
+ policy->kobj.ktype = &ktype_cpufreq;
+ policy->dev = dev;
+ strncpy(policy->kobj.name,
cpufreq_interface.name, KOBJ_NAME_LEN);

- ret = kobject_register(&policy.kobj);
+ ret = kobject_register(&policy->kobj);

up(&cpufreq_driver_sem);
return ret;

_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq

----- End forwarded message -----

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/