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

From: Russell King (rmk@arm.linux.org.uk)
Date: Sun Mar 09 2003 - 14:36:22 EST


----- 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/



This archive was generated by hypermail 2b29 : Sat Mar 15 2003 - 22:00:19 EST