cpufreq: Don't create empty /sys/devices/system/cpu/cpufreq directory
authorViresh Kumar <viresh.kumar@linaro.org>
Fri, 17 May 2013 10:39:09 +0000 (16:09 +0530)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 27 May 2013 11:24:02 +0000 (13:24 +0200)
When we don't have any file in cpu/cpufreq directory we shouldn't
create it. Specially with the introduction of per-policy governor
instance patchset, even governors are moved to
cpu/cpu*/cpufreq/governor-name directory and so this directory is
just not required.

Lets have it only when required.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_governor.c
include/linux/cpufreq.h

index 11b8b4b..8c02622 100644 (file)
@@ -947,7 +947,7 @@ static void __init acpi_cpufreq_boost_init(void)
        /* We create the boost file in any case, though for systems without
         * hardware support it will be read-only and hardwired to return 0.
         */
-       if (sysfs_create_file(cpufreq_global_kobject, &(global_boost.attr)))
+       if (cpufreq_sysfs_create_file(&(global_boost.attr)))
                pr_warn(PFX "could not register global boost sysfs file\n");
        else
                pr_debug("registered global boost sysfs file\n");
@@ -955,7 +955,7 @@ static void __init acpi_cpufreq_boost_init(void)
 
 static void __exit acpi_cpufreq_boost_exit(void)
 {
-       sysfs_remove_file(cpufreq_global_kobject, &(global_boost.attr));
+       cpufreq_sysfs_remove_file(&(global_boost.attr));
 
        if (msrs) {
                unregister_cpu_notifier(&boost_nb);
index c6ab218..ce9273a 100644 (file)
@@ -678,9 +678,6 @@ static struct attribute *default_attrs[] = {
        NULL
 };
 
-struct kobject *cpufreq_global_kobject;
-EXPORT_SYMBOL(cpufreq_global_kobject);
-
 #define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
 #define to_attr(a) container_of(a, struct freq_attr, attr)
 
@@ -751,6 +748,49 @@ static struct kobj_type ktype_cpufreq = {
        .release        = cpufreq_sysfs_release,
 };
 
+struct kobject *cpufreq_global_kobject;
+EXPORT_SYMBOL(cpufreq_global_kobject);
+
+static int cpufreq_global_kobject_usage;
+
+int cpufreq_get_global_kobject(void)
+{
+       if (!cpufreq_global_kobject_usage++)
+               return kobject_add(cpufreq_global_kobject,
+                               &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
+
+       return 0;
+}
+EXPORT_SYMBOL(cpufreq_get_global_kobject);
+
+void cpufreq_put_global_kobject(void)
+{
+       if (!--cpufreq_global_kobject_usage)
+               kobject_del(cpufreq_global_kobject);
+}
+EXPORT_SYMBOL(cpufreq_put_global_kobject);
+
+int cpufreq_sysfs_create_file(const struct attribute *attr)
+{
+       int ret = cpufreq_get_global_kobject();
+
+       if (!ret) {
+               ret = sysfs_create_file(cpufreq_global_kobject, attr);
+               if (ret)
+                       cpufreq_put_global_kobject();
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(cpufreq_sysfs_create_file);
+
+void cpufreq_sysfs_remove_file(const struct attribute *attr)
+{
+       sysfs_remove_file(cpufreq_global_kobject, attr);
+       cpufreq_put_global_kobject();
+}
+EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
+
 /* symlink affected CPUs */
 static int cpufreq_add_dev_symlink(unsigned int cpu,
                                   struct cpufreq_policy *policy)
@@ -2020,7 +2060,7 @@ static int __init cpufreq_core_init(void)
                init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
        }
 
-       cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
+       cpufreq_global_kobject = kobject_create();
        BUG_ON(!cpufreq_global_kobject);
        register_syscore_ops(&cpufreq_syscore_ops);
 
index b6cfd55..7532570 100644 (file)
@@ -231,6 +231,9 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        return rc;
                }
 
+               if (!have_governor_per_policy())
+                       WARN_ON(cpufreq_get_global_kobject());
+
                rc = sysfs_create_group(get_governor_parent_kobj(policy),
                                get_sysfs_attr(dbs_data));
                if (rc) {
@@ -269,6 +272,9 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        sysfs_remove_group(get_governor_parent_kobj(policy),
                                        get_sysfs_attr(dbs_data));
 
+                       if (!have_governor_per_policy())
+                               cpufreq_put_global_kobject();
+
                        if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
                                (policy->governor->initialized == 1)) {
                                struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
index fbf392a..1b5b5ef 100644 (file)
@@ -71,6 +71,10 @@ struct cpufreq_governor;
 
 /* /sys/devices/system/cpu/cpufreq: entry point for global variables */
 extern struct kobject *cpufreq_global_kobject;
+int cpufreq_get_global_kobject(void);
+void cpufreq_put_global_kobject(void);
+int cpufreq_sysfs_create_file(const struct attribute *attr);
+void cpufreq_sysfs_remove_file(const struct attribute *attr);
 
 #define CPUFREQ_ETERNAL                        (-1)
 struct cpufreq_cpuinfo {