|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH v2 6/8] cpufreq: introduce cpufreq_drv_ops
This patch allows to use more than one high-level
cpufreq driver. This patch is needed for implementation
xen-based high-level cpufreq driver.
Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@xxxxxxxxxxxxxxx>
---
drivers/cpufreq/Kconfig | 4 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/acpi-cpufreq.c | 5 +-
drivers/cpufreq/cpufreq.c | 116 ++++++++++++-----------
drivers/cpufreq/cpufreq_drv_ops.c | 187 +++++++++++++++++++++++++++++++++++++
drivers/cpufreq/cpufreq_drv_ops.h | 50 ++++++++++
drivers/cpufreq/cpufreq_governor.c | 4 +-
include/linux/cpufreq.h | 2 +-
8 files changed, 312 insertions(+), 57 deletions(-)
create mode 100644 drivers/cpufreq/cpufreq_drv_ops.c
create mode 100644 drivers/cpufreq/cpufreq_drv_ops.h
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index cbcb21e..42a1aed 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -1,7 +1,11 @@
menu "CPU Frequency scaling"
+config CPUFREQ_DRV_OPS
+ bool
+
config CPU_FREQ
bool "CPU Frequency scaling"
+ select CPUFREQ_DRV_OPS
help
CPU Frequency scaling allows you to change the clock speed of
CPUs on the fly. This is a nice method to save power, because
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fadc4d4..f12a0d3 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -1,5 +1,6 @@
# CPUfreq core
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPUFREQ_DRV_OPS) += cpufreq_drv_ops.o
# CPUfreq stats
obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 7b0d49d..2c2a33f 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -950,7 +950,8 @@ 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 (sysfs_create_file(get_cpufreq_global_kobject(),
+ &(global_boost.attr)))
pr_warn(PFX "could not register global boost sysfs file\n");
else
pr_debug("registered global boost sysfs file\n");
@@ -958,7 +959,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));
+ sysfs_remove_file(get_cpufreq_global_kobject(), &(global_boost.attr));
if (msrs) {
unregister_cpu_notifier(&boost_nb);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 6ed3c13..1b24bc3e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -33,6 +33,7 @@
#include <linux/syscore_ops.h>
#include <trace/events/power.h>
+#include "cpufreq_drv_ops.h"
/**
* The "cpufreq driver" - the arch- or hardware-dependent low
@@ -178,11 +179,10 @@ err_out:
return NULL;
}
-struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
+struct cpufreq_policy *kern_cpufreq_cpu_get(unsigned int cpu)
{
return __cpufreq_cpu_get(cpu, false);
}
-EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
{
@@ -196,11 +196,10 @@ static void __cpufreq_cpu_put(struct cpufreq_policy
*data, bool sysfs)
module_put(cpufreq_driver->owner);
}
-void cpufreq_cpu_put(struct cpufreq_policy *data)
+void kern_cpufreq_cpu_put(struct cpufreq_policy *data)
{
__cpufreq_cpu_put(data, false);
}
-EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
{
@@ -258,7 +257,8 @@ static inline void adjust_jiffies(unsigned long val, struct
cpufreq_freqs *ci)
* function. It is called twice on all CPU frequency changes that have
* external effects.
*/
-void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
+void kern_cpufreq_notify_transition(struct cpufreq_freqs *freqs,
+ unsigned int state)
{
struct cpufreq_policy *policy;
@@ -303,9 +303,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs,
unsigned int state)
break;
}
}
-EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
-
-
/*********************************************************************
* SYSFS INTERFACE *
@@ -628,7 +625,10 @@ static struct attribute *default_attrs[] = {
};
struct kobject *cpufreq_global_kobject;
-EXPORT_SYMBOL(cpufreq_global_kobject);
+struct kobject *get_kern_cpufreq_global_kobject(void)
+{
+ return 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)
@@ -1214,7 +1214,7 @@ static void cpufreq_out_of_sync(unsigned int cpu,
unsigned int old_freq,
* This is the last known freq, without actually getting it from the driver.
* Return value will be same as what is shown in scaling_cur_freq in sysfs.
*/
-unsigned int cpufreq_quick_get(unsigned int cpu)
+unsigned int kern_cpufreq_quick_get(unsigned int cpu)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
unsigned int ret_freq = 0;
@@ -1226,7 +1226,7 @@ unsigned int cpufreq_quick_get(unsigned int cpu)
return ret_freq;
}
-EXPORT_SYMBOL(cpufreq_quick_get);
+EXPORT_SYMBOL(kern_cpufreq_quick_get);
/**
* cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
@@ -1234,7 +1234,7 @@ EXPORT_SYMBOL(cpufreq_quick_get);
*
* Just return the max possible frequency for a given CPU.
*/
-unsigned int cpufreq_quick_get_max(unsigned int cpu)
+unsigned int kern_cpufreq_quick_get_max(unsigned int cpu)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
unsigned int ret_freq = 0;
@@ -1246,7 +1246,7 @@ unsigned int cpufreq_quick_get_max(unsigned int cpu)
return ret_freq;
}
-EXPORT_SYMBOL(cpufreq_quick_get_max);
+EXPORT_SYMBOL(kern_cpufreq_quick_get_max);
static unsigned int __cpufreq_get(unsigned int cpu)
@@ -1278,7 +1278,7 @@ static unsigned int __cpufreq_get(unsigned int cpu)
*
* Get the CPU current (static) CPU frequency
*/
-unsigned int cpufreq_get(unsigned int cpu)
+unsigned int kern_cpufreq_get(unsigned int cpu)
{
unsigned int ret_freq = 0;
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
@@ -1298,7 +1298,7 @@ out_policy:
out:
return ret_freq;
}
-EXPORT_SYMBOL(cpufreq_get);
+EXPORT_SYMBOL(kern_cpufreq_get);
static struct subsys_interface cpufreq_interface = {
.name = "cpufreq",
@@ -1387,26 +1387,25 @@ static struct syscore_ops cpufreq_syscore_ops = {
};
/**
- * cpufreq_get_current_driver - return current driver's name
+ * kern_cpufreq_get_current_driver - return current driver's name
*
* Return the name string of the currently loaded cpufreq driver
* or NULL, if none.
*/
-const char *cpufreq_get_current_driver(void)
+const char *kern_cpufreq_get_current_driver(void)
{
if (cpufreq_driver)
return cpufreq_driver->name;
return NULL;
}
-EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
/*********************************************************************
* NOTIFIER LISTS INTERFACE *
*********************************************************************/
/**
- * cpufreq_register_notifier - register a driver with cpufreq
+ * kern_cpufreq_register_notifier - register a driver with cpufreq
* @nb: notifier function to register
* @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
*
@@ -1418,7 +1417,7 @@ EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
* This function may sleep, and has the same return conditions as
* blocking_notifier_chain_register.
*/
-int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
+int kern_cpufreq_register_notifier(struct notifier_block *nb, unsigned int
list)
{
int ret;
@@ -1439,11 +1438,11 @@ int cpufreq_register_notifier(struct notifier_block
*nb, unsigned int list)
return ret;
}
-EXPORT_SYMBOL(cpufreq_register_notifier);
+EXPORT_SYMBOL(kern_cpufreq_register_notifier);
/**
- * cpufreq_unregister_notifier - unregister a driver with cpufreq
+ * kern_cpufreq_unregister_notifier - unregister a driver with cpufreq
* @nb: notifier block to be unregistered
* @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
*
@@ -1452,7 +1451,8 @@ EXPORT_SYMBOL(cpufreq_register_notifier);
* This function may sleep, and has the same return conditions as
* blocking_notifier_chain_unregister.
*/
-int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
+int kern_cpufreq_unregister_notifier(struct notifier_block *nb,
+ unsigned int list)
{
int ret;
@@ -1471,7 +1471,7 @@ int cpufreq_unregister_notifier(struct notifier_block
*nb, unsigned int list)
return ret;
}
-EXPORT_SYMBOL(cpufreq_unregister_notifier);
+EXPORT_SYMBOL(kern_cpufreq_unregister_notifier);
/*********************************************************************
@@ -1479,7 +1479,7 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
*********************************************************************/
-int __cpufreq_driver_target(struct cpufreq_policy *policy,
+int __kern_cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
@@ -1506,9 +1506,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
return retval;
}
-EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
-int cpufreq_driver_target(struct cpufreq_policy *policy,
+int kern_cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
@@ -1530,9 +1529,9 @@ fail:
no_policy:
return ret;
}
-EXPORT_SYMBOL_GPL(cpufreq_driver_target);
-int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
+int __kern_cpufreq_driver_getavg(struct cpufreq_policy *policy,
+ unsigned int cpu)
{
int ret = 0;
@@ -1548,7 +1547,6 @@ int __cpufreq_driver_getavg(struct cpufreq_policy
*policy, unsigned int cpu)
cpufreq_cpu_put(policy);
return ret;
}
-EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
/*
* when "event" is CPUFREQ_GOV_LIMITS
@@ -1602,7 +1600,7 @@ static int __cpufreq_governor(struct cpufreq_policy
*policy,
}
-int cpufreq_register_governor(struct cpufreq_governor *governor)
+int kern_cpufreq_register_governor(struct cpufreq_governor *governor)
{
int err;
@@ -1623,10 +1621,8 @@ int cpufreq_register_governor(struct cpufreq_governor
*governor)
mutex_unlock(&cpufreq_governor_mutex);
return err;
}
-EXPORT_SYMBOL_GPL(cpufreq_register_governor);
-
-void cpufreq_unregister_governor(struct cpufreq_governor *governor)
+void kern_cpufreq_unregister_governor(struct cpufreq_governor *governor)
{
#ifdef CONFIG_HOTPLUG_CPU
int cpu;
@@ -1652,22 +1648,19 @@ void cpufreq_unregister_governor(struct
cpufreq_governor *governor)
mutex_unlock(&cpufreq_governor_mutex);
return;
}
-EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
-
-
/*********************************************************************
* POLICY INTERFACE *
*********************************************************************/
/**
- * cpufreq_get_policy - get the current cpufreq_policy
+ * kern_cpufreq_get_policy - get the current cpufreq_policy
* @policy: struct cpufreq_policy into which the current cpufreq_policy
* is written
*
* Reads the current cpufreq policy.
*/
-int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
+int kern_cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
{
struct cpufreq_policy *cpu_policy;
if (!policy)
@@ -1682,7 +1675,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy,
unsigned int cpu)
cpufreq_cpu_put(cpu_policy);
return 0;
}
-EXPORT_SYMBOL(cpufreq_get_policy);
+EXPORT_SYMBOL(kern_cpufreq_get_policy);
/*
@@ -1774,13 +1767,13 @@ error_out:
}
/**
- * cpufreq_update_policy - re-evaluate an existing cpufreq policy
+ * kern_cpufreq_update_policy - re-evaluate an existing cpufreq policy
* @cpu: CPU which shall be re-evaluated
*
* Useful for policy notifiers which have different necessities
* at different times.
*/
-int cpufreq_update_policy(unsigned int cpu)
+int kern_cpufreq_update_policy(unsigned int cpu)
{
struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
struct cpufreq_policy policy;
@@ -1826,7 +1819,7 @@ fail:
no_policy:
return ret;
}
-EXPORT_SYMBOL(cpufreq_update_policy);
+EXPORT_SYMBOL(kern_cpufreq_update_policy);
static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
@@ -1866,7 +1859,7 @@ static struct notifier_block __refdata
cpufreq_cpu_notifier = {
*********************************************************************/
/**
- * cpufreq_register_driver - register a CPU Frequency driver
+ * kern_cpufreq_register_driver - register a CPU Frequency driver
* @driver_data: A struct cpufreq_driver containing the values#
* submitted by the CPU Frequency driver.
*
@@ -1875,7 +1868,7 @@ static struct notifier_block __refdata
cpufreq_cpu_notifier = {
* (and isn't unregistered in the meantime).
*
*/
-int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+int kern_cpufreq_register_driver(struct cpufreq_driver *driver_data)
{
unsigned long flags;
int ret;
@@ -1935,18 +1928,16 @@ err_null_driver:
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
return ret;
}
-EXPORT_SYMBOL_GPL(cpufreq_register_driver);
-
/**
- * cpufreq_unregister_driver - unregister the current CPUFreq driver
+ * kern_cpufreq_unregister_driver - unregister the current CPUFreq driver
*
* Unregister the current CPUFreq driver. Only call this if you have
* the right to do so, i.e. if you have succeeded in initialising before!
* Returns zero if successful, and -EINVAL if the cpufreq_driver is
* currently not initialised.
*/
-int cpufreq_unregister_driver(struct cpufreq_driver *driver)
+int kern_cpufreq_unregister_driver(struct cpufreq_driver *driver)
{
unsigned long flags;
@@ -1964,9 +1955,30 @@ int cpufreq_unregister_driver(struct cpufreq_driver
*driver)
return 0;
}
-EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
-static int __init cpufreq_core_init(void)
+struct cpufreq_drv_ops kern_cpufreq_drv_ops = {
+ .get_global_kobject = get_kern_cpufreq_global_kobject,
+ .cpu_get = kern_cpufreq_cpu_get,
+ .cpu_put = kern_cpufreq_cpu_put,
+ .notify_transition = kern_cpufreq_notify_transition,
+ .quick_get = kern_cpufreq_quick_get,
+ .quick_get_max = kern_cpufreq_quick_get_max,
+ .get = kern_cpufreq_get,
+ .register_notifier = kern_cpufreq_register_notifier,
+ .unregister_notifier = kern_cpufreq_unregister_notifier,
+ .get_current_driver = kern_cpufreq_get_current_driver,
+ .__driver_target = __kern_cpufreq_driver_target,
+ .driver_target = kern_cpufreq_driver_target,
+ .__driver_getavg = __kern_cpufreq_driver_getavg,
+ .register_governor = kern_cpufreq_register_governor,
+ .unregister_governor = kern_cpufreq_unregister_governor,
+ .get_policy = kern_cpufreq_get_policy,
+ .update_policy = kern_cpufreq_update_policy,
+ .register_driver = kern_cpufreq_register_driver,
+ .unregister_driver = kern_cpufreq_unregister_driver,
+};
+
+static int __init kern_cpufreq_core_init(void)
{
int cpu;
@@ -1984,4 +1996,4 @@ static int __init cpufreq_core_init(void)
return 0;
}
-core_initcall(cpufreq_core_init);
+core_initcall(kern_cpufreq_core_init);
diff --git a/drivers/cpufreq/cpufreq_drv_ops.c
b/drivers/cpufreq/cpufreq_drv_ops.c
new file mode 100644
index 0000000..c971442
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_drv_ops.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2014 GlobalLogic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "cpufreq_drv_ops.h"
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/export.h>
+
+static struct cpufreq_drv_ops *ops;
+
+struct kobject *get_cpufreq_global_kobject(void)
+{
+ if (ops && ops->get_global_kobject)
+ return ops->get_global_kobject();
+ return NULL;
+}
+EXPORT_SYMBOL(get_cpufreq_global_kobject);
+
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
+{
+ if (ops && ops->cpu_get)
+ return ops->cpu_get(cpu);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
+
+void cpufreq_cpu_put(struct cpufreq_policy *data)
+{
+ if (ops && ops->cpu_put)
+ ops->cpu_put(data);
+}
+EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
+
+void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
+{
+ if (ops && ops->notify_transition)
+ ops->notify_transition(freqs, state);
+}
+EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
+
+#ifdef CONFIG_CPU_FREQ
+unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+ if (ops && ops->quick_get)
+ return ops->quick_get(cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_quick_get);
+
+unsigned int cpufreq_quick_get_max(unsigned int cpu)
+{
+ if (ops && ops->quick_get_max)
+ return ops->quick_get_max(cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_quick_get_max);
+
+unsigned int cpufreq_get(unsigned int cpu)
+{
+ if (ops && ops->get)
+ return ops->get(cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
+{
+ if (ops && ops->register_notifier)
+ return ops->register_notifier(nb, list);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_register_notifier);
+
+int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
+{
+ if (ops && ops->unregister_notifier)
+ return ops->unregister_notifier(nb, list);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_unregister_notifier);
+#endif
+
+const char *cpufreq_get_current_driver(void)
+{
+ if (ops && ops->get_current_driver)
+ return ops->get_current_driver();
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
+
+int __cpufreq_driver_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ if (ops && ops->__driver_target)
+ return ops->__driver_target(policy, target_freq, relation);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
+
+int cpufreq_driver_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ if (ops && ops->driver_target)
+ return ops->driver_target(policy, target_freq, relation);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(cpufreq_driver_target);
+
+int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
+{
+ if (ops && ops->__driver_getavg)
+ return ops->__driver_getavg(policy, cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
+
+int cpufreq_register_governor(struct cpufreq_governor *governor)
+{
+ if (ops && ops->register_governor)
+ return ops->register_governor(governor);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(cpufreq_register_governor);
+
+void cpufreq_unregister_governor(struct cpufreq_governor *governor)
+{
+ if (ops && ops->unregister_governor)
+ ops->unregister_governor(governor);
+}
+EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
+
+int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
+{
+ if (ops && ops->get_policy)
+ return ops->get_policy(policy, cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_get_policy);
+
+int cpufreq_update_policy(unsigned int cpu)
+{
+ if (ops && ops->update_policy)
+ return ops->update_policy(cpu);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(cpufreq_update_policy);
+
+int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+{
+ if (ops && ops->register_driver)
+ return ops->register_driver(driver_data);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(cpufreq_register_driver);
+
+int cpufreq_unregister_driver(struct cpufreq_driver *driver)
+{
+ if (ops && ops->unregister_driver)
+ return ops->unregister_driver(driver);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
+
+static int __init cpufreq_drv_ops_init(void)
+{
+#ifdef CONFIG_CPU_FREQ
+ ops = &kern_cpufreq_drv_ops;
+ pr_debug("using kern_cpufreq_drv_ops\n");
+#endif
+
+ return 0;
+}
+core_initcall(cpufreq_drv_ops_init);
diff --git a/drivers/cpufreq/cpufreq_drv_ops.h
b/drivers/cpufreq/cpufreq_drv_ops.h
new file mode 100644
index 0000000..5cc8e05
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_drv_ops.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 GlobalLogic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _CPUFREQ_DRV_OPS_H
+#define _CPUFREQ_DRV_OPS_H
+
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+
+struct cpufreq_drv_ops {
+ struct kobject *(*get_global_kobject)(void);
+ struct cpufreq_policy *(*cpu_get)(unsigned int);
+ void (*cpu_put)(struct cpufreq_policy *);
+ void (*notify_transition)(struct cpufreq_freqs *, unsigned int);
+#ifdef CONFIG_CPU_FREQ
+ unsigned int (*quick_get)(unsigned int);
+ unsigned int (*quick_get_max)(unsigned int);
+ unsigned int (*get)(unsigned int);
+ int (*register_notifier)(struct notifier_block *, unsigned int);
+ int (*unregister_notifier)(struct notifier_block *, unsigned int);
+#endif
+ const char *(*get_current_driver)(void);
+ int (*__driver_target)(struct cpufreq_policy *,
+ unsigned int, unsigned int);
+ int (*driver_target)(struct cpufreq_policy *,
+ unsigned int, unsigned int);
+ int (*__driver_getavg)(struct cpufreq_policy *, unsigned int);
+ int (*register_governor)(struct cpufreq_governor *);
+ void (*unregister_governor)(struct cpufreq_governor *);
+ int (*get_policy)(struct cpufreq_policy *, unsigned int);
+ int (*update_policy)(unsigned int);
+ int (*register_driver)(struct cpufreq_driver *);
+ int (*unregister_driver)(struct cpufreq_driver *);
+};
+
+#ifdef CONFIG_CPU_FREQ
+extern struct cpufreq_drv_ops kern_cpufreq_drv_ops;
+#endif
+
+#endif /* _CPUFREQ_DRV_OPS_H */
diff --git a/drivers/cpufreq/cpufreq_governor.c
b/drivers/cpufreq/cpufreq_governor.c
index 6c5f1d3..731fa0d 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -226,7 +226,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data,
if (dbs_data->enable != 1)
goto second_time;
- rc = sysfs_create_group(cpufreq_global_kobject,
+ rc = sysfs_create_group(get_cpufreq_global_kobject(),
dbs_data->attr_group);
if (rc) {
mutex_unlock(&dbs_data->mutex);
@@ -291,7 +291,7 @@ second_time:
if (!dbs_data->enable) {
struct cs_ops *ops = dbs_data->gov_ops;
- sysfs_remove_group(cpufreq_global_kobject,
+ sysfs_remove_group(get_cpufreq_global_kobject(),
dbs_data->attr_group);
if (dbs_data->governor == GOV_CONSERVATIVE)
cpufreq_unregister_notifier(ops->notifier_block,
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3d919ea..2852bb23 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -70,7 +70,7 @@ static inline void disable_cpufreq(void) { }
struct cpufreq_governor;
/* /sys/devices/system/cpu/cpufreq: entry point for global variables */
-extern struct kobject *cpufreq_global_kobject;
+struct kobject *get_cpufreq_global_kobject(void);
#define CPUFREQ_ETERNAL (-1)
struct cpufreq_cpuinfo {
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |