From 2c3b4f8952b94576e4958af9e821716545bee9cc Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 9 Jul 2003 18:19:20 +0100 Subject: [CPUFREQ] Misc cleanups. --- include/linux/cpufreq.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 1bdb797bf9bd..a2fee295ae1a 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -306,8 +306,4 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); #endif /* CONFIG_CPU_FREQ_TABLE */ - -/* Currently exported only for the proc interface, remove when that goes */ -extern struct cpufreq_driver *cpufreq_driver; - #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From 1c576b19a92e6a4b489c033d77bf2bd512fa7b8e Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 9 Jul 2003 18:21:45 +0100 Subject: [CPUFREQ] kobj refcount fixes. Wait with the destruction of cpufreq objects until all references are gone (code partly based on rmk's comparable patch for the PCMCIA subsystem. From Dominik. --- include/linux/cpufreq.h | 2 ++ kernel/cpufreq.c | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index a2fee295ae1a..5a75fc3a69f2 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -20,6 +20,7 @@ #include #include #include +#include #define CPUFREQ_NAME_LEN 16 @@ -71,6 +72,7 @@ struct cpufreq_policy { struct kobject kobj; struct semaphore lock; /* CPU ->setpolicy or ->target may only be called once a time */ + struct completion kobj_unregister; }; #define CPUFREQ_ADJUST (0) diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c index 18245832d8c9..0701eed77ab4 100644 --- a/kernel/cpufreq.c +++ b/kernel/cpufreq.c @@ -23,6 +23,7 @@ #include #include #include +#include /** * The "cpufreq driver" - the arch- or hardware-dependend low @@ -297,6 +298,12 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr, return ret; } +static void cpufreq_sysfs_release(struct kobject * kobj) +{ + struct cpufreq_policy * policy = to_policy(kobj); + complete(&policy->kobj_unregister); +} + static struct sysfs_ops sysfs_ops = { .show = show, .store = store, @@ -305,6 +312,7 @@ static struct sysfs_ops sysfs_ops = { static struct kobj_type ktype_cpufreq = { .sysfs_ops = &sysfs_ops, .default_attrs = default_attrs, + .release = cpufreq_sysfs_release, }; @@ -343,6 +351,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) up(&cpufreq_driver_sem); init_MUTEX(&policy->lock); + init_completion(&policy->kobj_unregister); + /* prepare interface data */ policy->kobj.parent = &sys_dev->kobj; policy->kobj.ktype = &ktype_cpufreq; @@ -361,8 +371,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) /* set default policy */ ret = cpufreq_set_policy(&new_policy); - if (ret) + if (ret) { kobject_unregister(&policy->kobj); + wait_for_completion(&policy->kobj_unregister); + } out: module_put(cpufreq_driver->owner); @@ -400,6 +412,13 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) up(&cpufreq_driver_sem); kobject_put(&cpufreq_driver->policy[cpu].kobj); + + /* we need to make sure that the underlying kobj is actually + * destroyed before we proceed e.g. with cpufreq driver module + * unloading + */ + wait_for_completion(&cpufreq_driver->policy[cpu].kobj_unregister); + return 0; } -- cgit v1.2.3 From 92175044130735b3c9a0ec3567d758903972f6e2 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 9 Jul 2003 18:30:21 +0100 Subject: [CPUFREQ] More misc cleanups. - CPUFREQ_ALL_CPUS is not a valid argument any more, don't mention it in include/linux/cpufreq.h - without a driver->init() function a cpufreq driver isn't even loaded, so remove that check in the per-CPU initialization - whitespace and clarification changes to linux/cpufreq. All from Dominik again.. --- drivers/cpufreq/proc_intf.c | 2 ++ include/linux/cpufreq.h | 67 ++++++++++++++++++++++++--------------------- kernel/cpufreq.c | 8 ++---- 3 files changed, 41 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c index dc89b83710b8..d314e526af9c 100644 --- a/drivers/cpufreq/proc_intf.c +++ b/drivers/cpufreq/proc_intf.c @@ -13,6 +13,8 @@ #include +#define CPUFREQ_ALL_CPUS ((NR_CPUS)) + /** * cpufreq_parse_policy - parse a policy string * @input_string: the string to parse. diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 5a75fc3a69f2..dc29d5c4e713 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -32,17 +32,15 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); -#define CPUFREQ_TRANSITION_NOTIFIER (0) -#define CPUFREQ_POLICY_NOTIFIER (1) - -#define CPUFREQ_ALL_CPUS ((NR_CPUS)) +#define CPUFREQ_TRANSITION_NOTIFIER (0) +#define CPUFREQ_POLICY_NOTIFIER (1) /********************** cpufreq policy notifiers *********************/ -#define CPUFREQ_POLICY_POWERSAVE (1) -#define CPUFREQ_POLICY_PERFORMANCE (2) -#define CPUFREQ_POLICY_GOVERNOR (3) +#define CPUFREQ_POLICY_POWERSAVE (1) +#define CPUFREQ_POLICY_PERFORMANCE (2) +#define CPUFREQ_POLICY_GOVERNOR (3) /* Frequency values here are CPU kHz so that hardware which doesn't run * with some frequencies can complain without having to guess what per @@ -53,31 +51,34 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); struct cpufreq_governor; -#define CPUFREQ_ETERNAL (-1) +#define CPUFREQ_ETERNAL (-1) struct cpufreq_cpuinfo { - unsigned int max_freq; - unsigned int min_freq; - unsigned int transition_latency; + unsigned int max_freq; + unsigned int min_freq; + unsigned int transition_latency; /* in 10^(-9) s */ }; struct cpufreq_policy { - unsigned int cpu; /* cpu nr or CPUFREQ_ALL_CPUS */ - unsigned int min; /* in kHz */ - unsigned int max; /* in kHz */ - unsigned int cur; /* in kHz, only needed if cpufreq + unsigned int cpu; /* cpu nr */ + struct cpufreq_cpuinfo cpuinfo;/* see above */ + + unsigned int min; /* in kHz */ + unsigned int max; /* in kHz */ + unsigned int cur; /* in kHz, only needed if cpufreq * governors are used */ - unsigned int policy; /* see above */ - struct cpufreq_governor *governor; /* see below */ - struct cpufreq_cpuinfo cpuinfo; /* see above */ - struct kobject kobj; + unsigned int policy; /* see above */ + struct cpufreq_governor *governor; /* see below */ + struct semaphore lock; /* CPU ->setpolicy or ->target may only be called once a time */ + + struct kobject kobj; struct completion kobj_unregister; }; -#define CPUFREQ_ADJUST (0) -#define CPUFREQ_INCOMPATIBLE (1) -#define CPUFREQ_NOTIFY (2) +#define CPUFREQ_ADJUST (0) +#define CPUFREQ_INCOMPATIBLE (1) +#define CPUFREQ_NOTIFY (2) /******************** cpufreq transition notifiers *******************/ @@ -86,7 +87,7 @@ struct cpufreq_policy { #define CPUFREQ_POSTCHANGE (1) struct cpufreq_freqs { - unsigned int cpu; /* cpu nr or CPUFREQ_ALL_CPUS */ + unsigned int cpu; /* cpu nr */ unsigned int old; unsigned int new; }; @@ -127,11 +128,11 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu #define CPUFREQ_GOV_LIMITS 3 struct cpufreq_governor { - char name[CPUFREQ_NAME_LEN]; - int (*governor) (struct cpufreq_policy *policy, + char name[CPUFREQ_NAME_LEN]; + int (*governor) (struct cpufreq_policy *policy, unsigned int event); struct list_head governor_list; - struct module *owner; + struct module *owner; }; /* pass a target to the cpufreq driver @@ -156,18 +157,22 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor); struct freq_attr; struct cpufreq_driver { + struct module *owner; + char name[CPUFREQ_NAME_LEN]; + + struct cpufreq_policy *policy; + /* needed by all drivers */ + int (*init) (struct cpufreq_policy *policy); int (*verify) (struct cpufreq_policy *policy); - struct cpufreq_policy *policy; - char name[CPUFREQ_NAME_LEN]; + /* define one out of two */ int (*setpolicy) (struct cpufreq_policy *policy); int (*target) (struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); - struct module *owner; - /* optional, for the moment */ - int (*init) (struct cpufreq_policy *policy); + + /* optional */ int (*exit) (struct cpufreq_policy *policy); struct freq_attr **attr; }; diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c index 435f6d2d2fd3..f4864ce54aae 100644 --- a/kernel/cpufreq.c +++ b/kernel/cpufreq.c @@ -337,11 +337,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) */ policy = &cpufreq_driver->policy[cpu]; policy->cpu = cpu; - if (cpufreq_driver->init) { - ret = cpufreq_driver->init(policy); - if (ret) - goto out; - } + ret = cpufreq_driver->init(policy); + if (ret) + goto out; /* set default policy on this CPU */ down(&cpufreq_driver_sem); -- cgit v1.2.3