From d536bf3dc97417471e2c5098837a1cddd7fbb3c7 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Mon, 2 Sep 2013 11:57:35 +0800 Subject: ACPI / processor: use apic_id and remove duplicated _MAT evaluation Since APIC id is saved in processor struct, just use it and remove the duplicated _MAT evaluation. Signed-off-by: Jiang Liu Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index a5db4aeefa36..3bc74141453f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -116,7 +116,7 @@ void acpi_numa_arch_fixup(void); #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -int acpi_map_lsapic(acpi_handle handle, int *pcpu); +int acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu); int acpi_unmap_lsapic(int cpu); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ -- cgit v1.2.3 From 6dedcca610c6d6189b4a54d32118d1654adb73d2 Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Wed, 25 Sep 2013 15:08:27 -0600 Subject: hotplug, powerpc, x86: Remove cpu_hotplug_driver_lock() cpu_hotplug_driver_lock() serializes CPU online/offline operations when ARCH_CPU_PROBE_RELEASE is set. This lock interface is no longer necessary with the following reason: - lock_device_hotplug() now protects CPU online/offline operations, including the probe & release interfaces enabled by ARCH_CPU_PROBE_RELEASE. The use of cpu_hotplug_driver_lock() is redundant. - cpu_hotplug_driver_lock() is only valid when ARCH_CPU_PROBE_RELEASE is defined, which is misleading and is only enabled on powerpc. This patch removes the cpu_hotplug_driver_lock() interface. As a result, ARCH_CPU_PROBE_RELEASE only enables / disables the cpu probe & release interface as intended. There is no functional change in this patch. Signed-off-by: Toshi Kani Reviewed-by: Nathan Fontenot Signed-off-by: Rafael J. Wysocki --- arch/powerpc/kernel/smp.c | 12 ---------- arch/powerpc/platforms/pseries/dlpar.c | 43 +++++++++++++--------------------- arch/x86/kernel/topology.c | 2 -- drivers/base/cpu.c | 15 +++--------- include/linux/cpu.h | 13 ---------- 5 files changed, 19 insertions(+), 66 deletions(-) (limited to 'include/linux') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8e59abc237d7..930cd8af3503 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -844,18 +844,6 @@ void __cpu_die(unsigned int cpu) smp_ops->cpu_die(cpu); } -static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex); - -void cpu_hotplug_driver_lock() -{ - mutex_lock(&powerpc_cpu_hotplug_driver_mutex); -} - -void cpu_hotplug_driver_unlock() -{ - mutex_unlock(&powerpc_cpu_hotplug_driver_mutex); -} - void cpu_die(void) { if (ppc_md.cpu_die) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 7cfdaae1721a..a8fe5aa3d34f 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -404,46 +404,38 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) unsigned long drc_index; int rc; - cpu_hotplug_driver_lock(); rc = strict_strtoul(buf, 0, &drc_index); - if (rc) { - rc = -EINVAL; - goto out; - } + if (rc) + return -EINVAL; parent = of_find_node_by_path("/cpus"); - if (!parent) { - rc = -ENODEV; - goto out; - } + if (!parent) + return -ENODEV; dn = dlpar_configure_connector(drc_index, parent); - if (!dn) { - rc = -EINVAL; - goto out; - } + if (!dn) + return -EINVAL; of_node_put(parent); rc = dlpar_acquire_drc(drc_index); if (rc) { dlpar_free_cc_nodes(dn); - rc = -EINVAL; - goto out; + return -EINVAL; } rc = dlpar_attach_node(dn); if (rc) { dlpar_release_drc(drc_index); dlpar_free_cc_nodes(dn); - goto out; + return rc; } rc = dlpar_online_cpu(dn); -out: - cpu_hotplug_driver_unlock(); + if (rc) + return rc; - return rc ? rc : count; + return count; } static int dlpar_offline_cpu(struct device_node *dn) @@ -516,30 +508,27 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) return -EINVAL; } - cpu_hotplug_driver_lock(); rc = dlpar_offline_cpu(dn); if (rc) { of_node_put(dn); - rc = -EINVAL; - goto out; + return -EINVAL; } rc = dlpar_release_drc(*drc_index); if (rc) { of_node_put(dn); - goto out; + return rc; } rc = dlpar_detach_node(dn); if (rc) { dlpar_acquire_drc(*drc_index); - goto out; + return rc; } of_node_put(dn); -out: - cpu_hotplug_driver_unlock(); - return rc ? rc : count; + + return count; } static int __init pseries_dlpar_init(void) diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index a3f35ebb3b52..649b010da00b 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -66,7 +66,6 @@ int __ref _debug_hotplug_cpu(int cpu, int action) return -EINVAL; lock_device_hotplug(); - cpu_hotplug_driver_lock(); switch (action) { case 0: @@ -91,7 +90,6 @@ int __ref _debug_hotplug_cpu(int cpu, int action) ret = -EINVAL; } - cpu_hotplug_driver_unlock(); unlock_device_hotplug(); return ret; diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 51f5d7fe2f0b..f48370dfc908 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -44,13 +44,11 @@ static int __ref cpu_subsys_online(struct device *dev) struct cpu *cpu = container_of(dev, struct cpu, dev); int cpuid = dev->id; int from_nid, to_nid; - int ret = -ENODEV; - - cpu_hotplug_driver_lock(); + int ret; from_nid = cpu_to_node(cpuid); if (from_nid == NUMA_NO_NODE) - goto out; + return -ENODEV; ret = cpu_up(cpuid); /* @@ -61,19 +59,12 @@ static int __ref cpu_subsys_online(struct device *dev) if (from_nid != to_nid) change_cpu_under_node(cpu, from_nid, to_nid); - out: - cpu_hotplug_driver_unlock(); return ret; } static int cpu_subsys_offline(struct device *dev) { - int ret; - - cpu_hotplug_driver_lock(); - ret = cpu_down(dev->id); - cpu_hotplug_driver_unlock(); - return ret; + return cpu_down(dev->id); } void unregister_cpu(struct cpu *cpu) diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 801ff9e73679..3434ef7de017 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -185,19 +185,6 @@ extern void cpu_hotplug_enable(void); void clear_tasks_mm_cpumask(int cpu); int cpu_down(unsigned int cpu); -#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE -extern void cpu_hotplug_driver_lock(void); -extern void cpu_hotplug_driver_unlock(void); -#else -static inline void cpu_hotplug_driver_lock(void) -{ -} - -static inline void cpu_hotplug_driver_unlock(void) -{ -} -#endif - #else /* CONFIG_HOTPLUG_CPU */ static inline void cpu_hotplug_begin(void) {} -- cgit v1.2.3 From 27047a603645d0885bcd72d7a0b6cce6e3c94ca7 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 16 Sep 2013 18:56:03 +0530 Subject: cpufreq: Add new helper cpufreq_table_validate_and_show() Almost every cpufreq driver is required to validate its frequency table with: cpufreq_frequency_table_cpuinfo() and then expose it to cpufreq core with: cpufreq_frequency_table_get_attr(). This patch creates another helper routine cpufreq_table_validate_and_show() that will do both these steps in a single call and will return 0 for success, error otherwise. This also fixes potential bugs in cpufreq drivers where people have called cpufreq_frequency_table_get_attr() before calling cpufreq_frequency_table_cpuinfo(), as the later may fail. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/freq_table.c | 12 ++++++++++++ include/linux/cpufreq.h | 2 ++ 2 files changed, 14 insertions(+) (limited to 'include/linux') diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f111454a7aea..11f6fa92a58d 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -219,6 +219,18 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu) } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); +int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table) +{ + int ret = cpufreq_frequency_table_cpuinfo(policy, table); + + if (!ret) + cpufreq_frequency_table_get_attr(table, policy->cpu); + + return ret; +} +EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); + void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy) { pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n", diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index fcabc42d66ab..6b199ed7aa58 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -410,5 +410,7 @@ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu); void cpufreq_frequency_table_put_attr(unsigned int cpu); +int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table); #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From 6461f018e7ad08863b55c386bf694683e4e2e86e Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 2 Oct 2013 14:13:17 +0530 Subject: cpufreq: rewrite cpufreq_driver->flags using shift operator Currently cpufreq_driver's flags are defined directly using 0x1, 0x2, 0x4, 0x8, etc.. As the list grows it becomes less readable.. Use bitwise shift operator << to generate these numbers for respective positions. Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 6b199ed7aa58..00c80a5372db 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -211,13 +211,14 @@ struct cpufreq_driver { }; /* flags */ -#define CPUFREQ_STICKY 0x01 /* the driver isn't removed even if - * all ->init() calls failed */ -#define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel - * "constants" aren't affected by - * frequency transitions */ -#define CPUFREQ_PM_NO_WARN 0x04 /* don't warn on suspend/resume speed - * mismatches */ +#define CPUFREQ_STICKY (1 << 0) /* driver isn't removed even if + all ->init() calls failed */ +#define CPUFREQ_CONST_LOOPS (1 << 1) /* loops_per_jiffy or other + kernel "constants" aren't + affected by frequency + transitions */ +#define CPUFREQ_PM_NO_WARN (1 << 2) /* don't warn on suspend/resume + speed mismatches */ int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); -- cgit v1.2.3 From 0b981e70748861a3e10ea2e2a689bdcee3e15085 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 2 Oct 2013 14:13:18 +0530 Subject: cpufreq: use cpufreq_driver->flags to mark CPUFREQ_HAVE_GOVERNOR_PER_POLICY Use cpufreq_driver->flags to mark CPUFREQ_HAVE_GOVERNOR_PER_POLICY instead of a separate field within cpufreq_driver. This will save some bytes of memory. Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/arm_big_little.c | 4 ++-- drivers/cpufreq/cpufreq.c | 2 +- drivers/cpufreq/cpufreq_governor.h | 5 ++++- include/linux/cpufreq.h | 15 ++++++++------- 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 9acfb82c1cfb..2c7c13494825 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -213,13 +213,13 @@ static struct freq_attr *bL_cpufreq_attr[] = { static struct cpufreq_driver bL_cpufreq_driver = { .name = "arm-big-little", - .flags = CPUFREQ_STICKY, + .flags = CPUFREQ_STICKY | + CPUFREQ_HAVE_GOVERNOR_PER_POLICY, .verify = bL_cpufreq_verify_policy, .target = bL_cpufreq_set_target, .get = bL_cpufreq_get, .init = bL_cpufreq_init, .exit = bL_cpufreq_exit, - .have_governor_per_policy = true, .attr = bL_cpufreq_attr, }; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3a811df43e14..fc9110c9f10d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -133,7 +133,7 @@ static DEFINE_MUTEX(cpufreq_governor_mutex); bool have_governor_per_policy(void) { - return cpufreq_driver->have_governor_per_policy; + return !!(cpufreq_driver->flags & CPUFREQ_HAVE_GOVERNOR_PER_POLICY); } EXPORT_SYMBOL_GPL(have_governor_per_policy); diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 88cd39f7b0e9..b5f2b8618949 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -191,7 +191,10 @@ struct common_dbs_data { struct attribute_group *attr_group_gov_sys; /* one governor - system */ struct attribute_group *attr_group_gov_pol; /* one governor - policy */ - /* Common data for platforms that don't set have_governor_per_policy */ + /* + * Common data for platforms that don't set + * CPUFREQ_HAVE_GOVERNOR_PER_POLICY + */ struct dbs_data *gdbs_data; struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 00c80a5372db..24b84f7e7f8d 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -180,13 +180,6 @@ __ATTR(_name, 0644, show_##_name, store_##_name) struct cpufreq_driver { char name[CPUFREQ_NAME_LEN]; u8 flags; - /* - * This should be set by platforms having multiple clock-domains, i.e. - * supporting multiple policies. With this sysfs directories of governor - * would be created in cpu/cpu/cpufreq/ directory and so they can - * use the same governor with different tunables for different clusters. - */ - bool have_governor_per_policy; /* needed by all drivers */ int (*init) (struct cpufreq_policy *policy); @@ -220,6 +213,14 @@ struct cpufreq_driver { #define CPUFREQ_PM_NO_WARN (1 << 2) /* don't warn on suspend/resume speed mismatches */ +/* + * This should be set by platforms having multiple clock-domains, i.e. + * supporting multiple policies. With this sysfs directories of governor would + * be created in cpu/cpu/cpufreq/ directory and so they can use the same + * governor with different tunables for different clusters. + */ +#define CPUFREQ_HAVE_GOVERNOR_PER_POLICY (1 << 3) + int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); -- cgit v1.2.3 From be49e3465f222b4b796be8a21d14afbfd8f5d20f Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 2 Oct 2013 14:13:19 +0530 Subject: cpufreq: add new routine cpufreq_verify_within_cpu_limits() Most of the users of cpufreq_verify_within_limits() calls it for limiting with min/max from policy->cpuinfo. We can make that code simple by introducing another routine which will do this for them automatically. This patch adds another routine cpufreq_verify_within_cpu_limits() and updates others to use it. Signed-off-by: Viresh Kumar Acked-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-nforce2.c | 4 +--- drivers/cpufreq/davinci-cpufreq.c | 4 +--- drivers/cpufreq/freq_table.c | 6 ++---- drivers/cpufreq/integrator-cpufreq.c | 9 ++------- drivers/cpufreq/intel_pstate.c | 4 +--- drivers/cpufreq/longrun.c | 4 +--- drivers/cpufreq/pcc-cpufreq.c | 3 +-- drivers/cpufreq/sh-cpufreq.c | 7 ++----- drivers/cpufreq/unicore2-cpufreq.c | 4 +--- include/linux/cpufreq.h | 7 +++++++ 10 files changed, 19 insertions(+), 33 deletions(-) (limited to 'include/linux') diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index b83d45f68574..56c964c16a66 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -303,9 +303,7 @@ static int nforce2_verify(struct cpufreq_policy *policy) if (policy->min < (fsb_pol_max * fid * 100)) policy->max = (fsb_pol_max + 1) * fid * 100; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); return 0; } diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index f67196e21fc9..ba03e6f91d47 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -50,9 +50,7 @@ static int davinci_verify_speed(struct cpufreq_policy *policy) if (policy->cpu) return -EINVAL; - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - + cpufreq_verify_within_cpu_limits(policy); policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 10f3cfb6b513..b9336edb9bd6 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -60,8 +60,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu); - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) { if (freq == CPUFREQ_ENTRY_INVALID) @@ -77,8 +76,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, if (!found) { policy->max = next_larger; - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); } pr_debug("verification lead to (%u - %u kHz) for cpu %u\n", diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index f7c99df0880b..8152a9bb7e2c 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c @@ -59,9 +59,7 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) { struct icst_vco vco; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); vco = icst_hz_to_vco(&cclk_params, policy->max * 1000); policy->max = icst_hz(&cclk_params, vco) / 1000; @@ -69,10 +67,7 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) vco = icst_hz_to_vco(&cclk_params, policy->min * 1000); policy->min = icst_hz(&cclk_params, vco) / 1000; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - + cpufreq_verify_within_cpu_limits(policy); return 0; } diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9733f29ed148..a02bd77cbfe8 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -611,9 +611,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) static int intel_pstate_verify_policy(struct cpufreq_policy *policy) { - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 5aa031612d53..074971b12635 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c @@ -129,9 +129,7 @@ static int longrun_verify_policy(struct cpufreq_policy *policy) return -EINVAL; policy->cpu = 0; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index d81c4e5ea0ad..78787e965e0b 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -111,8 +111,7 @@ static struct pcc_cpu __percpu *pcc_cpu_info; static int pcc_cpufreq_verify(struct cpufreq_policy *policy) { - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); return 0; } diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 1362e8894ee1..f1fb944d714c 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c @@ -87,15 +87,12 @@ static int sh_cpufreq_verify(struct cpufreq_policy *policy) if (freq_table) return cpufreq_frequency_table_verify(policy, freq_table); - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); + cpufreq_verify_within_cpu_limits(policy); policy->min = (clk_round_rate(cpuclk, 1) + 500) / 1000; policy->max = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - + cpufreq_verify_within_cpu_limits(policy); return 0; } diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index b225f04d8ae5..14e6d3106355 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c @@ -29,9 +29,7 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy) if (policy->cpu) return -EINVAL; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - + cpufreq_verify_within_cpu_limits(policy); return 0; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 24b84f7e7f8d..c7495915932d 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -242,6 +242,13 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, return; } +static inline void +cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) +{ + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); +} + /********************************************************************* * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ -- cgit v1.2.3 From 184345129c53e76069c209f9912ed7c457eceb31 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 3 Oct 2013 20:27:55 +0530 Subject: cpufreq: define generic .attr, .exit() and .verify() routines Most of the CPUFreq drivers do similar things in .exit() and .verify() routines and .attr. So its better if we have generic routines for them which can be used by cpufreq drivers then. This patch introduces generic .attr, .exit() and .verify() cpufreq drivers. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/freq_table.c | 20 ++++++++++++++++++++ include/linux/cpufreq.h | 8 ++++++++ 2 files changed, 28 insertions(+) (limited to 'include/linux') diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index b9336edb9bd6..3458d27f63b4 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -86,6 +86,20 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); +/* + * Generic routine to verify policy & frequency table, requires driver to call + * cpufreq_frequency_table_get_attr() prior to it. + */ +int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) +{ + struct cpufreq_frequency_table *table = + cpufreq_frequency_get_table(policy->cpu); + if (!table) + return -ENODEV; + + return cpufreq_frequency_table_verify(policy, table); +} +EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, @@ -199,6 +213,12 @@ struct freq_attr cpufreq_freq_attr_scaling_available_freqs = { }; EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); +struct freq_attr *cpufreq_generic_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; +EXPORT_SYMBOL_GPL(cpufreq_generic_attr); + /* * if you use these, you must assure that the frequency table is valid * all the time between get_attr and put_attr! diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c7495915932d..36ccd0bf1304 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -401,6 +401,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); +int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, @@ -416,10 +417,17 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; +extern struct freq_attr *cpufreq_generic_attr[]; void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu); void cpufreq_frequency_table_put_attr(unsigned int cpu); int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); +static inline int cpufreq_generic_exit(struct cpufreq_policy *policy) +{ + cpufreq_frequency_table_put_attr(policy->cpu); + return 0; +} + #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From 70e9e778337973d5bf57004092b360bd3f3c412f Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 3 Oct 2013 20:29:07 +0530 Subject: cpufreq: create cpufreq_generic_init() routine Many CPUFreq drivers for SMP system (where all cores share same clock lines), do similar stuff in their ->init() part. This patch creates a generic routine in cpufreq core which can be used by these so that we can remove some redundant code. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig | 1 + drivers/cpufreq/cpufreq.c | 31 +++++++++++++++++++++++++++++++ include/linux/cpufreq.h | 3 +++ 3 files changed, 35 insertions(+) (limited to 'include/linux') diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 534fcb825153..2d06754f4a04 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -2,6 +2,7 @@ menu "CPU Frequency scaling" config CPU_FREQ bool "CPU Frequency scaling" + select CPU_FREQ_TABLE 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/cpufreq.c b/drivers/cpufreq/cpufreq.c index f033adf06eaf..985f325adc4f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -181,6 +181,37 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) } EXPORT_SYMBOL_GPL(get_cpu_idle_time); +/* + * This is a generic cpufreq init() routine which can be used by cpufreq + * drivers of SMP systems. It will do following: + * - validate & show freq table passed + * - set policies transition latency + * - policy->cpus with all possible CPUs + */ +int cpufreq_generic_init(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + unsigned int transition_latency) +{ + int ret; + + ret = cpufreq_table_validate_and_show(policy, table); + if (ret) { + pr_err("%s: invalid frequency table: %d\n", __func__, ret); + return ret; + } + + policy->cpuinfo.transition_latency = transition_latency; + + /* + * The driver only supports the SMP configuartion where all processors + * share the clock and voltage and clock. + */ + cpumask_setall(policy->cpus); + + return 0; +} +EXPORT_SYMBOL_GPL(cpufreq_generic_init); + struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) { struct cpufreq_policy *policy = NULL; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 36ccd0bf1304..0aba2a6cadaf 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -424,6 +424,9 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); +int cpufreq_generic_init(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + unsigned int transition_latency); static inline int cpufreq_generic_exit(struct cpufreq_policy *policy) { cpufreq_frequency_table_put_attr(policy->cpu); -- cgit v1.2.3 From 5915a3db0c3983f1cd5e046bf70086c7d0c686d2 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Fri, 11 Oct 2013 21:27:43 +0800 Subject: backlight: introduce backlight_device_registered Introduce a new API for modules to query if a specific type of backlight device has been registered. This is useful for some backlight device provider module (e.g. ACPI video) to know if a native control interface(e.g. the interface created by i915) is available and then do things accordingly (e.g. avoid registering its own on Win8 systems). Signed-off-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/video/backlight/backlight.c | 31 +++++++++++++++++++++++++++++++ include/linux/backlight.h | 4 ++++ 2 files changed, 35 insertions(+) (limited to 'include/linux') diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 94a403a9717a..5d05555fe841 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -21,6 +21,9 @@ #include #endif +static struct list_head backlight_dev_list; +static struct mutex backlight_dev_list_mutex; + static const char *const backlight_types[] = { [BACKLIGHT_RAW] = "raw", [BACKLIGHT_PLATFORM] = "platform", @@ -349,10 +352,32 @@ struct backlight_device *backlight_device_register(const char *name, mutex_unlock(&pmac_backlight_mutex); #endif + mutex_lock(&backlight_dev_list_mutex); + list_add(&new_bd->entry, &backlight_dev_list); + mutex_unlock(&backlight_dev_list_mutex); + return new_bd; } EXPORT_SYMBOL(backlight_device_register); +bool backlight_device_registered(enum backlight_type type) +{ + bool found = false; + struct backlight_device *bd; + + mutex_lock(&backlight_dev_list_mutex); + list_for_each_entry(bd, &backlight_dev_list, entry) { + if (bd->props.type == type) { + found = true; + break; + } + } + mutex_unlock(&backlight_dev_list_mutex); + + return found; +} +EXPORT_SYMBOL(backlight_device_registered); + /** * backlight_device_unregister - unregisters a backlight device object. * @bd: the backlight device object to be unregistered and freed. @@ -364,6 +389,10 @@ void backlight_device_unregister(struct backlight_device *bd) if (!bd) return; + mutex_lock(&backlight_dev_list_mutex); + list_del(&bd->entry); + mutex_unlock(&backlight_dev_list_mutex); + #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); if (pmac_backlight == bd) @@ -499,6 +528,8 @@ static int __init backlight_class_init(void) backlight_class->dev_groups = bl_device_groups; backlight_class->pm = &backlight_class_dev_pm_ops; + INIT_LIST_HEAD(&backlight_dev_list); + mutex_init(&backlight_dev_list_mutex); return 0; } diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 53b77949c79d..5f9cd963213d 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -100,6 +100,9 @@ struct backlight_device { /* The framebuffer notifier block */ struct notifier_block fb_notif; + /* list entry of all registered backlight devices */ + struct list_head entry; + struct device dev; }; @@ -123,6 +126,7 @@ extern void devm_backlight_device_unregister(struct device *dev, struct backlight_device *bd); extern void backlight_force_update(struct backlight_device *bd, enum backlight_update_reason reason); +extern bool backlight_device_registered(enum backlight_type type); #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) -- cgit v1.2.3 From 75d2364ea0cab3a95be3f8d1f8dabd20ac4b1b2a Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 11 Oct 2013 16:54:56 -0700 Subject: PowerCap: Add class driver The power capping framework providing a consistent interface between the kernel and user space that allows power capping drivers to expose their settings to user space in a uniform way. The overall design of the framework is described in the documentation added by the previous patch in this series. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jacob Pan Reviewed-by: Rafael J. Wysocki Signed-off-by: Rafael J. Wysocki --- drivers/powercap/Kconfig | 19 ++ drivers/powercap/Makefile | 1 + drivers/powercap/powercap_sys.c | 683 ++++++++++++++++++++++++++++++++++++++++ include/linux/powercap.h | 325 +++++++++++++++++++ 4 files changed, 1028 insertions(+) create mode 100644 drivers/powercap/Kconfig create mode 100644 drivers/powercap/Makefile create mode 100644 drivers/powercap/powercap_sys.c create mode 100644 include/linux/powercap.h (limited to 'include/linux') diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig new file mode 100644 index 000000000000..a37055eb5ebc --- /dev/null +++ b/drivers/powercap/Kconfig @@ -0,0 +1,19 @@ +# +# Generic power capping sysfs interface configuration +# + +menuconfig POWERCAP + bool "Generic powercap sysfs driver" + help + The power capping sysfs interface allows kernel subsystems to expose power + capping settings to user space in a consistent way. Usually, it consists + of multiple control types that determine which settings may be exposed and + power zones representing parts of the system that can be subject to power + capping. + + If you want this code to be compiled in, say Y here. + +if POWERCAP +# Client driver configurations go here. + +endif diff --git a/drivers/powercap/Makefile b/drivers/powercap/Makefile new file mode 100644 index 000000000000..6defbc8dc4bf --- /dev/null +++ b/drivers/powercap/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POWERCAP) += powercap_sys.o diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c new file mode 100644 index 000000000000..c22fa4c78eaa --- /dev/null +++ b/drivers/powercap/powercap_sys.c @@ -0,0 +1,683 @@ +/* + * Power capping class + * Copyright (c) 2013, Intel Corporation. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc. + * + */ + +#include +#include +#include +#include +#include + +#define to_powercap_zone(n) container_of(n, struct powercap_zone, dev) +#define to_powercap_control_type(n) \ + container_of(n, struct powercap_control_type, dev) + +/* Power zone show function */ +#define define_power_zone_show(_attr) \ +static ssize_t _attr##_show(struct device *dev, \ + struct device_attribute *dev_attr,\ + char *buf) \ +{ \ + u64 value; \ + ssize_t len = -EINVAL; \ + struct powercap_zone *power_zone = to_powercap_zone(dev); \ + \ + if (power_zone->ops->get_##_attr) { \ + if (!power_zone->ops->get_##_attr(power_zone, &value)) \ + len = sprintf(buf, "%lld\n", value); \ + } \ + \ + return len; \ +} + +/* The only meaningful input is 0 (reset), others are silently ignored */ +#define define_power_zone_store(_attr) \ +static ssize_t _attr##_store(struct device *dev,\ + struct device_attribute *dev_attr, \ + const char *buf, size_t count) \ +{ \ + int err; \ + struct powercap_zone *power_zone = to_powercap_zone(dev); \ + u64 value; \ + \ + err = kstrtoull(buf, 10, &value); \ + if (err) \ + return -EINVAL; \ + if (value) \ + return count; \ + if (power_zone->ops->reset_##_attr) { \ + if (!power_zone->ops->reset_##_attr(power_zone)) \ + return count; \ + } \ + \ + return -EINVAL; \ +} + +/* Power zone constraint show function */ +#define define_power_zone_constraint_show(_attr) \ +static ssize_t show_constraint_##_attr(struct device *dev, \ + struct device_attribute *dev_attr,\ + char *buf) \ +{ \ + u64 value; \ + ssize_t len = -ENODATA; \ + struct powercap_zone *power_zone = to_powercap_zone(dev); \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ + if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ + pconst = &power_zone->constraints[id]; \ + if (pconst && pconst->ops && pconst->ops->get_##_attr) { \ + if (!pconst->ops->get_##_attr(power_zone, id, &value)) \ + len = sprintf(buf, "%lld\n", value); \ + } \ + \ + return len; \ +} + +/* Power zone constraint store function */ +#define define_power_zone_constraint_store(_attr) \ +static ssize_t store_constraint_##_attr(struct device *dev,\ + struct device_attribute *dev_attr, \ + const char *buf, size_t count) \ +{ \ + int err; \ + u64 value; \ + struct powercap_zone *power_zone = to_powercap_zone(dev); \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ + if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ + pconst = &power_zone->constraints[id]; \ + err = kstrtoull(buf, 10, &value); \ + if (err) \ + return -EINVAL; \ + if (pconst && pconst->ops && pconst->ops->set_##_attr) { \ + if (!pconst->ops->set_##_attr(power_zone, id, value)) \ + return count; \ + } \ + \ + return -ENODATA; \ +} + +/* Power zone information callbacks */ +define_power_zone_show(power_uw); +define_power_zone_show(max_power_range_uw); +define_power_zone_show(energy_uj); +define_power_zone_store(energy_uj); +define_power_zone_show(max_energy_range_uj); + +/* Power zone attributes */ +static DEVICE_ATTR_RO(max_power_range_uw); +static DEVICE_ATTR_RO(power_uw); +static DEVICE_ATTR_RO(max_energy_range_uj); +static DEVICE_ATTR_RW(energy_uj); + +/* Power zone constraint attributes callbacks */ +define_power_zone_constraint_show(power_limit_uw); +define_power_zone_constraint_store(power_limit_uw); +define_power_zone_constraint_show(time_window_us); +define_power_zone_constraint_store(time_window_us); +define_power_zone_constraint_show(max_power_uw); +define_power_zone_constraint_show(min_power_uw); +define_power_zone_constraint_show(max_time_window_us); +define_power_zone_constraint_show(min_time_window_us); + +/* For one time seeding of constraint device attributes */ +struct powercap_constraint_attr { + struct device_attribute power_limit_attr; + struct device_attribute time_window_attr; + struct device_attribute max_power_attr; + struct device_attribute min_power_attr; + struct device_attribute max_time_window_attr; + struct device_attribute min_time_window_attr; + struct device_attribute name_attr; +}; + +static struct powercap_constraint_attr + constraint_attrs[MAX_CONSTRAINTS_PER_ZONE]; + +/* A list of powercap control_types */ +static LIST_HEAD(powercap_cntrl_list); +/* Mutex to protect list of powercap control_types */ +static DEFINE_MUTEX(powercap_cntrl_list_lock); + +#define POWERCAP_CONSTRAINT_NAME_LEN 30 /* Some limit to avoid overflow */ +static ssize_t show_constraint_name(struct device *dev, + struct device_attribute *dev_attr, + char *buf) +{ + const char *name; + struct powercap_zone *power_zone = to_powercap_zone(dev); + int id; + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + + if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; + pconst = &power_zone->constraints[id]; + + if (pconst && pconst->ops && pconst->ops->get_name) { + name = pconst->ops->get_name(power_zone, id); + if (name) { + snprintf(buf, POWERCAP_CONSTRAINT_NAME_LEN, + "%s\n", name); + buf[POWERCAP_CONSTRAINT_NAME_LEN] = '\0'; + len = strlen(buf); + } + } + + return len; +} + +static int create_constraint_attribute(int id, const char *name, + int mode, + struct device_attribute *dev_attr, + ssize_t (*show)(struct device *, + struct device_attribute *, char *), + ssize_t (*store)(struct device *, + struct device_attribute *, + const char *, size_t) + ) +{ + + dev_attr->attr.name = kasprintf(GFP_KERNEL, "constraint_%d_%s", + id, name); + if (!dev_attr->attr.name) + return -ENOMEM; + dev_attr->attr.mode = mode; + dev_attr->show = show; + dev_attr->store = store; + + return 0; +} + +static void free_constraint_attributes(void) +{ + int i; + + for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) { + kfree(constraint_attrs[i].power_limit_attr.attr.name); + kfree(constraint_attrs[i].time_window_attr.attr.name); + kfree(constraint_attrs[i].name_attr.attr.name); + kfree(constraint_attrs[i].max_power_attr.attr.name); + kfree(constraint_attrs[i].min_power_attr.attr.name); + kfree(constraint_attrs[i].max_time_window_attr.attr.name); + kfree(constraint_attrs[i].min_time_window_attr.attr.name); + } +} + +static int seed_constraint_attributes(void) +{ + int i; + int ret; + + for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) { + ret = create_constraint_attribute(i, "power_limit_uw", + S_IWUSR | S_IRUGO, + &constraint_attrs[i].power_limit_attr, + show_constraint_power_limit_uw, + store_constraint_power_limit_uw); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "time_window_us", + S_IWUSR | S_IRUGO, + &constraint_attrs[i].time_window_attr, + show_constraint_time_window_us, + store_constraint_time_window_us); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "name", S_IRUGO, + &constraint_attrs[i].name_attr, + show_constraint_name, + NULL); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "max_power_uw", S_IRUGO, + &constraint_attrs[i].max_power_attr, + show_constraint_max_power_uw, + NULL); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "min_power_uw", S_IRUGO, + &constraint_attrs[i].min_power_attr, + show_constraint_min_power_uw, + NULL); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "max_time_window_us", + S_IRUGO, + &constraint_attrs[i].max_time_window_attr, + show_constraint_max_time_window_us, + NULL); + if (ret) + goto err_alloc; + ret = create_constraint_attribute(i, "min_time_window_us", + S_IRUGO, + &constraint_attrs[i].min_time_window_attr, + show_constraint_min_time_window_us, + NULL); + if (ret) + goto err_alloc; + + } + + return 0; + +err_alloc: + free_constraint_attributes(); + + return ret; +} + +static int create_constraints(struct powercap_zone *power_zone, + int nr_constraints, + struct powercap_zone_constraint_ops *const_ops) +{ + int i; + int ret = 0; + int count; + struct powercap_zone_constraint *pconst; + + if (!power_zone || !const_ops || !const_ops->get_power_limit_uw || + !const_ops->set_power_limit_uw || + !const_ops->get_time_window_us || + !const_ops->set_time_window_us) + return -EINVAL; + + count = power_zone->zone_attr_count; + for (i = 0; i < nr_constraints; ++i) { + pconst = &power_zone->constraints[i]; + pconst->ops = const_ops; + pconst->id = power_zone->const_id_cnt; + power_zone->const_id_cnt++; + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].power_limit_attr.attr; + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].time_window_attr.attr; + if (pconst->ops->get_name) + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].name_attr.attr; + if (pconst->ops->get_max_power_uw) + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].max_power_attr.attr; + if (pconst->ops->get_min_power_uw) + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].min_power_attr.attr; + if (pconst->ops->get_max_time_window_us) + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].max_time_window_attr.attr; + if (pconst->ops->get_min_time_window_us) + power_zone->zone_dev_attrs[count++] = + &constraint_attrs[i].min_time_window_attr.attr; + } + power_zone->zone_attr_count = count; + + return ret; +} + +static bool control_type_valid(void *control_type) +{ + struct powercap_control_type *pos = NULL; + bool found = false; + + mutex_lock(&powercap_cntrl_list_lock); + + list_for_each_entry(pos, &powercap_cntrl_list, node) { + if (pos == control_type) { + found = true; + break; + } + } + mutex_unlock(&powercap_cntrl_list_lock); + + return found; +} + +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct powercap_zone *power_zone = to_powercap_zone(dev); + + return sprintf(buf, "%s\n", power_zone->name); +} + +static DEVICE_ATTR_RO(name); + +/* Create zone and attributes in sysfs */ +static void create_power_zone_common_attributes( + struct powercap_zone *power_zone) +{ + int count = 0; + + power_zone->zone_dev_attrs[count++] = &dev_attr_name.attr; + if (power_zone->ops->get_max_energy_range_uj) + power_zone->zone_dev_attrs[count++] = + &dev_attr_max_energy_range_uj.attr; + if (power_zone->ops->get_energy_uj) + power_zone->zone_dev_attrs[count++] = + &dev_attr_energy_uj.attr; + if (power_zone->ops->get_power_uw) + power_zone->zone_dev_attrs[count++] = + &dev_attr_power_uw.attr; + if (power_zone->ops->get_max_power_range_uw) + power_zone->zone_dev_attrs[count++] = + &dev_attr_max_power_range_uw.attr; + power_zone->zone_dev_attrs[count] = NULL; + power_zone->zone_attr_count = count; +} + +static void powercap_release(struct device *dev) +{ + bool allocated; + + if (dev->parent) { + struct powercap_zone *power_zone = to_powercap_zone(dev); + + /* Store flag as the release() may free memory */ + allocated = power_zone->allocated; + /* Remove id from parent idr struct */ + idr_remove(power_zone->parent_idr, power_zone->id); + /* Destroy idrs allocated for this zone */ + idr_destroy(&power_zone->idr); + kfree(power_zone->name); + kfree(power_zone->zone_dev_attrs); + kfree(power_zone->constraints); + if (power_zone->ops->release) + power_zone->ops->release(power_zone); + if (allocated) + kfree(power_zone); + } else { + struct powercap_control_type *control_type = + to_powercap_control_type(dev); + + /* Store flag as the release() may free memory */ + allocated = control_type->allocated; + idr_destroy(&control_type->idr); + mutex_destroy(&control_type->lock); + if (control_type->ops && control_type->ops->release) + control_type->ops->release(control_type); + if (allocated) + kfree(control_type); + } +} + +static ssize_t enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + bool mode = true; + + /* Default is enabled */ + if (dev->parent) { + struct powercap_zone *power_zone = to_powercap_zone(dev); + if (power_zone->ops->get_enable) + if (power_zone->ops->get_enable(power_zone, &mode)) + mode = false; + } else { + struct powercap_control_type *control_type = + to_powercap_control_type(dev); + if (control_type->ops && control_type->ops->get_enable) + if (control_type->ops->get_enable(control_type, &mode)) + mode = false; + } + + return sprintf(buf, "%d\n", mode); +} + +static ssize_t enabled_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + bool mode; + + if (strtobool(buf, &mode)) + return -EINVAL; + if (dev->parent) { + struct powercap_zone *power_zone = to_powercap_zone(dev); + if (power_zone->ops->set_enable) + if (!power_zone->ops->set_enable(power_zone, mode)) + return len; + } else { + struct powercap_control_type *control_type = + to_powercap_control_type(dev); + if (control_type->ops && control_type->ops->set_enable) + if (!control_type->ops->set_enable(control_type, mode)) + return len; + } + + return -ENOSYS; +} + +static struct device_attribute powercap_def_attrs[] = { + __ATTR(enabled, S_IWUSR | S_IRUGO, enabled_show, + enabled_store), + __ATTR_NULL +}; + +static struct class powercap_class = { + .name = "powercap", + .dev_release = powercap_release, + .dev_attrs = powercap_def_attrs, +}; + +struct powercap_zone *powercap_register_zone( + struct powercap_zone *power_zone, + struct powercap_control_type *control_type, + const char *name, + struct powercap_zone *parent, + const struct powercap_zone_ops *ops, + int nr_constraints, + struct powercap_zone_constraint_ops *const_ops) +{ + int result; + int nr_attrs; + + if (!name || !control_type || !ops || + nr_constraints > MAX_CONSTRAINTS_PER_ZONE || + (!ops->get_energy_uj && !ops->get_power_uw) || + !control_type_valid(control_type)) + return ERR_PTR(-EINVAL); + + if (power_zone) { + if (!ops->release) + return ERR_PTR(-EINVAL); + memset(power_zone, 0, sizeof(*power_zone)); + } else { + power_zone = kzalloc(sizeof(*power_zone), GFP_KERNEL); + if (!power_zone) + return ERR_PTR(-ENOMEM); + power_zone->allocated = true; + } + power_zone->ops = ops; + power_zone->control_type_inst = control_type; + if (!parent) { + power_zone->dev.parent = &control_type->dev; + power_zone->parent_idr = &control_type->idr; + } else { + power_zone->dev.parent = &parent->dev; + power_zone->parent_idr = &parent->idr; + } + power_zone->dev.class = &powercap_class; + + mutex_lock(&control_type->lock); + /* Using idr to get the unique id */ + result = idr_alloc(power_zone->parent_idr, NULL, 0, 0, GFP_KERNEL); + if (result < 0) + goto err_idr_alloc; + + power_zone->id = result; + idr_init(&power_zone->idr); + power_zone->name = kstrdup(name, GFP_KERNEL); + if (!power_zone->name) + goto err_name_alloc; + dev_set_name(&power_zone->dev, "%s:%x", + dev_name(power_zone->dev.parent), + power_zone->id); + power_zone->constraints = kzalloc(sizeof(*power_zone->constraints) * + nr_constraints, GFP_KERNEL); + if (!power_zone->constraints) + goto err_const_alloc; + + nr_attrs = nr_constraints * POWERCAP_CONSTRAINTS_ATTRS + + POWERCAP_ZONE_MAX_ATTRS + 1; + power_zone->zone_dev_attrs = kzalloc(sizeof(void *) * + nr_attrs, GFP_KERNEL); + if (!power_zone->zone_dev_attrs) + goto err_attr_alloc; + create_power_zone_common_attributes(power_zone); + result = create_constraints(power_zone, nr_constraints, const_ops); + if (result) + goto err_dev_ret; + + power_zone->zone_dev_attrs[power_zone->zone_attr_count] = NULL; + power_zone->dev_zone_attr_group.attrs = power_zone->zone_dev_attrs; + power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group; + power_zone->dev_attr_groups[1] = NULL; + power_zone->dev.groups = power_zone->dev_attr_groups; + result = device_register(&power_zone->dev); + if (result) + goto err_dev_ret; + + control_type->nr_zones++; + mutex_unlock(&control_type->lock); + + return power_zone; + +err_dev_ret: + kfree(power_zone->zone_dev_attrs); +err_attr_alloc: + kfree(power_zone->constraints); +err_const_alloc: + kfree(power_zone->name); +err_name_alloc: + idr_remove(power_zone->parent_idr, power_zone->id); +err_idr_alloc: + if (power_zone->allocated) + kfree(power_zone); + mutex_unlock(&control_type->lock); + + return ERR_PTR(result); +} +EXPORT_SYMBOL_GPL(powercap_register_zone); + +int powercap_unregister_zone(struct powercap_control_type *control_type, + struct powercap_zone *power_zone) +{ + if (!power_zone || !control_type) + return -EINVAL; + + mutex_lock(&control_type->lock); + control_type->nr_zones--; + mutex_unlock(&control_type->lock); + + device_unregister(&power_zone->dev); + + return 0; +} +EXPORT_SYMBOL_GPL(powercap_unregister_zone); + +struct powercap_control_type *powercap_register_control_type( + struct powercap_control_type *control_type, + const char *name, + const struct powercap_control_type_ops *ops) +{ + int result; + + if (!name) + return ERR_PTR(-EINVAL); + if (control_type) { + if (!ops || !ops->release) + return ERR_PTR(-EINVAL); + memset(control_type, 0, sizeof(*control_type)); + } else { + control_type = kzalloc(sizeof(*control_type), GFP_KERNEL); + if (!control_type) + return ERR_PTR(-ENOMEM); + control_type->allocated = true; + } + mutex_init(&control_type->lock); + control_type->ops = ops; + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, name); + result = device_register(&control_type->dev); + if (result) { + if (control_type->allocated) + kfree(control_type); + return ERR_PTR(result); + } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + + return control_type; +} +EXPORT_SYMBOL_GPL(powercap_register_control_type); + +int powercap_unregister_control_type(struct powercap_control_type *control_type) +{ + struct powercap_control_type *pos = NULL; + + if (control_type->nr_zones) { + dev_err(&control_type->dev, "Zones of this type still not freed\n"); + return -EINVAL; + } + mutex_lock(&powercap_cntrl_list_lock); + list_for_each_entry(pos, &powercap_cntrl_list, node) { + if (pos == control_type) { + list_del(&control_type->node); + mutex_unlock(&powercap_cntrl_list_lock); + device_unregister(&control_type->dev); + return 0; + } + } + mutex_unlock(&powercap_cntrl_list_lock); + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(powercap_unregister_control_type); + +static int __init powercap_init(void) +{ + int result = 0; + + result = seed_constraint_attributes(); + if (result) + return result; + + result = class_register(&powercap_class); + + return result; +} + +device_initcall(powercap_init); + +MODULE_DESCRIPTION("PowerCap sysfs Driver"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/powercap.h b/include/linux/powercap.h new file mode 100644 index 000000000000..4e250417ee30 --- /dev/null +++ b/include/linux/powercap.h @@ -0,0 +1,325 @@ +/* + * powercap.h: Data types and headers for sysfs power capping interface + * Copyright (c) 2013, Intel Corporation. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc. + * + */ + +#ifndef __POWERCAP_H__ +#define __POWERCAP_H__ + +#include +#include + +/* + * A power cap class device can contain multiple powercap control_types. + * Each control_type can have multiple power zones, which can be independently + * controlled. Each power zone can have one or more constraints. + */ + +struct powercap_control_type; +struct powercap_zone; +struct powercap_zone_constraint; + +/** + * struct powercap_control_type_ops - Define control type callbacks + * @set_enable: Enable/Disable whole control type. + * Default is enabled. But this callback allows all zones + * to be in disable state and remove any applied power + * limits. If disabled power zone can only be monitored + * not controlled. + * @get_enable: get Enable/Disable status. + * @release: Callback to inform that last reference to this + * control type is closed. So it is safe to free data + * structure associated with this control type. + * This callback is mandatory if the client own memory + * for the control type. + * + * This structure defines control type callbacks to be implemented by client + * drivers + */ +struct powercap_control_type_ops { + int (*set_enable) (struct powercap_control_type *, bool mode); + int (*get_enable) (struct powercap_control_type *, bool *mode); + int (*release) (struct powercap_control_type *); +}; + +/** + * struct powercap_control_type- Defines a powercap control_type + * @name: name of control_type + * @dev: device for this control_type + * @idr: idr to have unique id for its child + * @root_node: Root holding power zones for this control_type + * @ops: Pointer to callback struct + * @node_lock: mutex for control type + * @allocated: This is possible that client owns the memory + * used by this structure. In this case + * this flag is set to false by framework to + * prevent deallocation during release process. + * Otherwise this flag is set to true. + * @ctrl_inst: link to the control_type list + * + * Defines powercap control_type. This acts as a container for power + * zones, which use same method to control power. E.g. RAPL, RAPL-PCI etc. + * All fields are private and should not be used by client drivers. + */ +struct powercap_control_type { + struct device dev; + struct idr idr; + int nr_zones; + const struct powercap_control_type_ops *ops; + struct mutex lock; + bool allocated; + struct list_head node; +}; + +/** + * struct powercap_zone_ops - Define power zone callbacks + * @get_max_energy_range_uj: Get maximum range of energy counter in + * micro-joules. + * @get_energy_uj: Get current energy counter in micro-joules. + * @reset_energy_uj: Reset micro-joules energy counter. + * @get_max_power_range_uw: Get maximum range of power counter in + * micro-watts. + * @get_power_uw: Get current power counter in micro-watts. + * @set_enable: Enable/Disable power zone controls. + * Default is enabled. + * @get_enable: get Enable/Disable status. + * @release: Callback to inform that last reference to this + * control type is closed. So it is safe to free + * data structure associated with this + * control type. Mandatory, if client driver owns + * the power_zone memory. + * + * This structure defines zone callbacks to be implemented by client drivers. + * Client drives can define both energy and power related callbacks. But at + * the least one type (either power or energy) is mandatory. Client drivers + * should handle mutual exclusion, if required in callbacks. + */ +struct powercap_zone_ops { + int (*get_max_energy_range_uj) (struct powercap_zone *, u64 *); + int (*get_energy_uj) (struct powercap_zone *, u64 *); + int (*reset_energy_uj) (struct powercap_zone *); + int (*get_max_power_range_uw) (struct powercap_zone *, u64 *); + int (*get_power_uw) (struct powercap_zone *, u64 *); + int (*set_enable) (struct powercap_zone *, bool mode); + int (*get_enable) (struct powercap_zone *, bool *mode); + int (*release) (struct powercap_zone *); +}; + +#define POWERCAP_ZONE_MAX_ATTRS 6 +#define POWERCAP_CONSTRAINTS_ATTRS 8 +#define MAX_CONSTRAINTS_PER_ZONE 10 +/** + * struct powercap_zone- Defines instance of a power cap zone + * @id: Unique id + * @name: Power zone name. + * @control_type_inst: Control type instance for this zone. + * @ops: Pointer to the zone operation structure. + * @dev: Instance of a device. + * @const_id_cnt: Number of constraint defined. + * @idr: Instance to an idr entry for children zones. + * @parent_idr: To remove reference from the parent idr. + * @private_data: Private data pointer if any for this zone. + * @zone_dev_attrs: Attributes associated with this device. + * @zone_attr_count: Attribute count. + * @dev_zone_attr_group: Attribute group for attributes. + * @dev_attr_groups: Attribute group store to register with device. + * @allocated: This is possible that client owns the memory + * used by this structure. In this case + * this flag is set to false by framework to + * prevent deallocation during release process. + * Otherwise this flag is set to true. + * @constraint_ptr: List of constraints for this zone. + * + * This defines a power zone instance. The fields of this structure are + * private, and should not be used by client drivers. + */ +struct powercap_zone { + int id; + char *name; + void *control_type_inst; + const struct powercap_zone_ops *ops; + struct device dev; + int const_id_cnt; + struct idr idr; + struct idr *parent_idr; + void *private_data; + struct attribute **zone_dev_attrs; + int zone_attr_count; + struct attribute_group dev_zone_attr_group; + const struct attribute_group *dev_attr_groups[2]; /* 1 group + NULL */ + bool allocated; + struct powercap_zone_constraint *constraints; +}; + +/** + * struct powercap_zone_constraint_ops - Define constraint callbacks + * @set_power_limit_uw: Set power limit in micro-watts. + * @get_power_limit_uw: Get power limit in micro-watts. + * @set_time_window_us: Set time window in micro-seconds. + * @get_time_window_us: Get time window in micro-seconds. + * @get_max_power_uw: Get max power allowed in micro-watts. + * @get_min_power_uw: Get min power allowed in micro-watts. + * @get_max_time_window_us: Get max time window allowed in micro-seconds. + * @get_min_time_window_us: Get min time window allowed in micro-seconds. + * @get_name: Get the name of constraint + * + * This structure is used to define the constraint callbacks for the client + * drivers. The following callbacks are mandatory and can't be NULL: + * set_power_limit_uw + * get_power_limit_uw + * set_time_window_us + * get_time_window_us + * get_name + * Client drivers should handle mutual exclusion, if required in callbacks. + */ +struct powercap_zone_constraint_ops { + int (*set_power_limit_uw) (struct powercap_zone *, int, u64); + int (*get_power_limit_uw) (struct powercap_zone *, int, u64 *); + int (*set_time_window_us) (struct powercap_zone *, int, u64); + int (*get_time_window_us) (struct powercap_zone *, int, u64 *); + int (*get_max_power_uw) (struct powercap_zone *, int, u64 *); + int (*get_min_power_uw) (struct powercap_zone *, int, u64 *); + int (*get_max_time_window_us) (struct powercap_zone *, int, u64 *); + int (*get_min_time_window_us) (struct powercap_zone *, int, u64 *); + const char *(*get_name) (struct powercap_zone *, int); +}; + +/** + * struct powercap_zone_constraint- Defines instance of a constraint + * @id: Instance Id of this constraint. + * @power_zone: Pointer to the power zone for this constraint. + * @ops: Pointer to the constraint callbacks. + * + * This defines a constraint instance. + */ +struct powercap_zone_constraint { + int id; + struct powercap_zone *power_zone; + struct powercap_zone_constraint_ops *ops; +}; + + +/* For clients to get their device pointer, may be used for dev_dbgs */ +#define POWERCAP_GET_DEV(power_zone) (&power_zone->dev) + +/** +* powercap_set_zone_data() - Set private data for a zone +* @power_zone: A pointer to the valid zone instance. +* @pdata: A pointer to the user private data. +* +* Allows client drivers to associate some private data to zone instance. +*/ +static inline void powercap_set_zone_data(struct powercap_zone *power_zone, + void *pdata) +{ + if (power_zone) + power_zone->private_data = pdata; +} + +/** +* powercap_get_zone_data() - Get private data for a zone +* @power_zone: A pointer to the valid zone instance. +* +* Allows client drivers to get private data associate with a zone, +* using call to powercap_set_zone_data. +*/ +static inline void *powercap_get_zone_data(struct powercap_zone *power_zone) +{ + if (power_zone) + return power_zone->private_data; + return NULL; +} + +/** +* powercap_register_control_type() - Register a control_type with framework +* @control_type: Pointer to client allocated memory for the control type +* structure storage. If this is NULL, powercap framework +* will allocate memory and own it. +* Advantage of this parameter is that client can embed +* this data in its data structures and allocate in a +* single call, preventing multiple allocations. +* @control_type_name: The Name of this control_type, which will be shown +* in the sysfs Interface. +* @ops: Callbacks for control type. This parameter is optional. +* +* Used to create a control_type with the power capping class. Here control_type +* can represent a type of technology, which can control a range of power zones. +* For example a control_type can be RAPL (Running Average Power Limit) +* Intel® 64 and IA-32 Processor Architectures. The name can be any string +* which must be unique, otherwise this function returns NULL. +* A pointer to the control_type instance is returned on success. +*/ +struct powercap_control_type *powercap_register_control_type( + struct powercap_control_type *control_type, + const char *name, + const struct powercap_control_type_ops *ops); + +/** +* powercap_unregister_control_type() - Unregister a control_type from framework +* @instance: A pointer to the valid control_type instance. +* +* Used to unregister a control_type with the power capping class. +* All power zones registered under this control type have to be unregistered +* before calling this function, or it will fail with an error code. +*/ +int powercap_unregister_control_type(struct powercap_control_type *instance); + +/* Zone register/unregister API */ + +/** +* powercap_register_zone() - Register a power zone +* @power_zone: Pointer to client allocated memory for the power zone structure +* storage. If this is NULL, powercap framework will allocate +* memory and own it. Advantage of this parameter is that client +* can embed this data in its data structures and allocate in a +* single call, preventing multiple allocations. +* @control_type: A control_type instance under which this zone operates. +* @name: A name for this zone. +* @parent: A pointer to the parent power zone instance if any or NULL +* @ops: Pointer to zone operation callback structure. +* @no_constraints: Number of constraints for this zone +* @const_ops: Pointer to constraint callback structure +* +* Register a power zone under a given control type. A power zone must register +* a pointer to a structure representing zone callbacks. +* A power zone can be located under a parent power zone, in which case @parent +* should point to it. Otherwise, if @parent is NULL, the new power zone will +* be located directly under the given control type +* For each power zone there may be a number of constraints that appear in the +* sysfs under that zone as attributes with unique numeric IDs. +* Returns pointer to the power_zone on success. +*/ +struct powercap_zone *powercap_register_zone( + struct powercap_zone *power_zone, + struct powercap_control_type *control_type, + const char *name, + struct powercap_zone *parent, + const struct powercap_zone_ops *ops, + int nr_constraints, + struct powercap_zone_constraint_ops *const_ops); + +/** +* powercap_unregister_zone() - Unregister a zone device +* @control_type: A pointer to the valid instance of a control_type. +* @power_zone: A pointer to the valid zone instance for a control_type +* +* Used to unregister a zone device for a control_type. Caller should +* make sure that children for this zone are unregistered first. +*/ +int powercap_unregister_zone(struct powercap_control_type *control_type, + struct powercap_zone *power_zone); + +#endif -- cgit v1.2.3 From bfd1ff6375c82930bfb3b401eee2c96720fa8e84 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 11 Oct 2013 16:54:59 -0700 Subject: bitops: Introduce BIT_ULL Adding BIT(x) equivalent for unsigned long long type, BIT_ULL(x). Also added BIT_ULL_MASK and BIT_ULL_WORD. Suggested-by: Joe Perches Signed-off-by: Srinivas Pandruvada Signed-off-by: Jacob Pan Signed-off-by: Rafael J. Wysocki --- include/linux/bitops.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/bitops.h b/include/linux/bitops.h index a3b6b82108b9..5a1c8b71ccd8 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -4,8 +4,11 @@ #ifdef __KERNEL__ #define BIT(nr) (1UL << (nr)) +#define BIT_ULL(nr) (1ULL << (nr)) #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #endif -- cgit v1.2.3 From 5d4879cda67b09f086807821cf594ee079d6dfbe Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 19 Sep 2013 16:03:50 -0500 Subject: PM / OPP: rename functions to dev_pm_opp* Since Operating Performance Points (OPP) functions are specific to device specific power management, be specific and rename opp_* accessors in OPP library with dev_pm_opp_* equivalent. Affected functions are: opp_get_voltage opp_get_freq opp_get_opp_count opp_find_freq_exact opp_find_freq_floor opp_find_freq_ceil opp_add opp_enable opp_disable opp_get_notifier opp_init_cpufreq_table opp_free_cpufreq_table Reported-by: Randy Dunlap Signed-off-by: Nishanth Menon Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/power/opp.txt | 102 ++++++++++++++++---------------- arch/arm/mach-imx/mach-imx6q.c | 2 +- arch/arm/mach-omap2/board-omap3beagle.c | 8 +-- arch/arm/mach-omap2/opp.c | 4 +- arch/arm/mach-omap2/pm.c | 4 +- drivers/base/power/opp.c | 82 ++++++++++++------------- drivers/cpufreq/arm_big_little.c | 6 +- drivers/cpufreq/cpufreq-cpu0.c | 18 +++--- drivers/cpufreq/exynos5440-cpufreq.c | 13 ++-- drivers/cpufreq/imx6q-cpufreq.c | 20 +++---- drivers/cpufreq/omap-cpufreq.c | 8 +-- drivers/devfreq/devfreq.c | 14 ++--- drivers/devfreq/exynos/exynos4_bus.c | 21 +++---- drivers/devfreq/exynos/exynos5_bus.c | 18 +++--- include/linux/opp.h | 50 ++++++++-------- 15 files changed, 187 insertions(+), 183 deletions(-) (limited to 'include/linux') diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index 425c51d56aef..185367b1848f 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt @@ -71,14 +71,14 @@ operations until that OPP could be re-enabled if possible. OPP library facilitates this concept in it's implementation. The following operational functions operate only on available opps: -opp_find_freq_{ceil, floor}, opp_get_voltage, opp_get_freq, opp_get_opp_count -and opp_init_cpufreq_table +opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count +and dev_pm_opp_init_cpufreq_table -opp_find_freq_exact is meant to be used to find the opp pointer which can then -be used for opp_enable/disable functions to make an opp available as required. +dev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then +be used for dev_pm_opp_enable/disable functions to make an opp available as required. WARNING: Users of OPP library should refresh their availability count using -get_opp_count if opp_enable/disable functions are invoked for a device, the +get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the exact mechanism to trigger these or the notification mechanism to other dependent subsystems such as cpufreq are left to the discretion of the SoC specific framework which uses the OPP library. Similar care needs to be taken @@ -96,24 +96,24 @@ using RCU read locks. The opp_find_freq_{exact,ceil,floor}, opp_get_{voltage, freq, opp_count} fall into this category. opp_{add,enable,disable} are updaters which use mutex and implement it's own -RCU locking mechanisms. opp_init_cpufreq_table acts as an updater and uses +RCU locking mechanisms. dev_pm_opp_init_cpufreq_table acts as an updater and uses mutex to implment RCU updater strategy. These functions should *NOT* be called under RCU locks and other contexts that prevent blocking functions in RCU or mutex operations from working. 2. Initial OPP List Registration ================================ -The SoC implementation calls opp_add function iteratively to add OPPs per +The SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per device. It is expected that the SoC framework will register the OPP entries optimally- typical numbers range to be less than 5. The list generated by registering the OPPs is maintained by OPP library throughout the device operation. The SoC framework can subsequently control the availability of the -OPPs dynamically using the opp_enable / disable functions. +OPPs dynamically using the dev_pm_opp_enable / disable functions. -opp_add - Add a new OPP for a specific domain represented by the device pointer. +dev_pm_opp_add - Add a new OPP for a specific domain represented by the device pointer. The OPP is defined using the frequency and voltage. Once added, the OPP is assumed to be available and control of it's availability can be done - with the opp_enable/disable functions. OPP library internally stores + with the dev_pm_opp_enable/disable functions. OPP library internally stores and manages this information in the opp struct. This function may be used by SoC framework to define a optimal list as per the demands of SoC usage environment. @@ -124,7 +124,7 @@ opp_add - Add a new OPP for a specific domain represented by the device pointer. soc_pm_init() { /* Do things */ - r = opp_add(mpu_dev, 1000000, 900000); + r = dev_pm_opp_add(mpu_dev, 1000000, 900000); if (!r) { pr_err("%s: unable to register mpu opp(%d)\n", r); goto no_cpufreq; @@ -143,44 +143,44 @@ functions return the matching pointer representing the opp if a match is found, else returns error. These errors are expected to be handled by standard error checks such as IS_ERR() and appropriate actions taken by the caller. -opp_find_freq_exact - Search for an OPP based on an *exact* frequency and +dev_pm_opp_find_freq_exact - Search for an OPP based on an *exact* frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to - find the OPP prior to call the opp_enable to actually make it available. + find the OPP prior to call the dev_pm_opp_enable to actually make it available. rcu_read_lock(); - opp = opp_find_freq_exact(dev, 1000000000, false); + opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); rcu_read_unlock(); /* dont operate on the pointer.. just do a sanity check.. */ if (IS_ERR(opp)) { pr_err("frequency not disabled!\n"); /* trigger appropriate actions.. */ } else { - opp_enable(dev,1000000000); + dev_pm_opp_enable(dev,1000000000); } NOTE: This is the only search function that operates on OPPs which are not available. -opp_find_freq_floor - Search for an available OPP which is *at most* the +dev_pm_opp_find_freq_floor - Search for an available OPP which is *at most* the provided frequency. This function is useful while searching for a lesser match OR operating on OPP information in the order of decreasing frequency. Example: To find the highest opp for a device: freq = ULONG_MAX; rcu_read_lock(); - opp_find_freq_floor(dev, &freq); + dev_pm_opp_find_freq_floor(dev, &freq); rcu_read_unlock(); -opp_find_freq_ceil - Search for an available OPP which is *at least* the +dev_pm_opp_find_freq_ceil - Search for an available OPP which is *at least* the provided frequency. This function is useful while searching for a higher match OR operating on OPP information in the order of increasing frequency. Example 1: To find the lowest opp for a device: freq = 0; rcu_read_lock(); - opp_find_freq_ceil(dev, &freq); + dev_pm_opp_find_freq_ceil(dev, &freq); rcu_read_unlock(); Example 2: A simplified implementation of a SoC cpufreq_driver->target: soc_cpufreq_target(..) @@ -188,7 +188,7 @@ opp_find_freq_ceil - Search for an available OPP which is *at least* the /* Do stuff like policy checks etc. */ /* Find the best frequency match for the req */ rcu_read_lock(); - opp = opp_find_freq_ceil(dev, &freq); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); rcu_read_unlock(); if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); @@ -208,34 +208,34 @@ as thermal considerations (e.g. don't use OPPx until the temperature drops). WARNING: Do not use these functions in interrupt context. -opp_enable - Make a OPP available for operation. +dev_pm_opp_enable - Make a OPP available for operation. Example: Lets say that 1GHz OPP is to be made available only if the SoC temperature is lower than a certain threshold. The SoC framework implementation might choose to do something as follows: if (cur_temp < temp_low_thresh) { /* Enable 1GHz if it was disabled */ rcu_read_lock(); - opp = opp_find_freq_exact(dev, 1000000000, false); + opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); rcu_read_unlock(); /* just error check */ if (!IS_ERR(opp)) - ret = opp_enable(dev, 1000000000); + ret = dev_pm_opp_enable(dev, 1000000000); else goto try_something_else; } -opp_disable - Make an OPP to be not available for operation +dev_pm_opp_disable - Make an OPP to be not available for operation Example: Lets say that 1GHz OPP is to be disabled if the temperature exceeds a threshold value. The SoC framework implementation might choose to do something as follows: if (cur_temp > temp_high_thresh) { /* Disable 1GHz if it was enabled */ rcu_read_lock(); - opp = opp_find_freq_exact(dev, 1000000000, true); + opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); rcu_read_unlock(); /* just error check */ if (!IS_ERR(opp)) - ret = opp_disable(dev, 1000000000); + ret = dev_pm_opp_disable(dev, 1000000000); else goto try_something_else; } @@ -247,7 +247,7 @@ information from the OPP structure is necessary. Once an OPP pointer is retrieved using the search functions, the following functions can be used by SoC framework to retrieve the information represented inside the OPP layer. -opp_get_voltage - Retrieve the voltage represented by the opp pointer. +dev_pm_opp_get_voltage - Retrieve the voltage represented by the opp pointer. Example: At a cpufreq transition to a different frequency, SoC framework requires to set the voltage represented by the OPP using the regulator framework to the Power Management chip providing the @@ -256,15 +256,15 @@ opp_get_voltage - Retrieve the voltage represented by the opp pointer. { /* do things */ rcu_read_lock(); - opp = opp_find_freq_ceil(dev, &freq); - v = opp_get_voltage(opp); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + v = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); if (v) regulator_set_voltage(.., v); /* do other things */ } -opp_get_freq - Retrieve the freq represented by the opp pointer. +dev_pm_opp_get_freq - Retrieve the freq represented by the opp pointer. Example: Lets say the SoC framework uses a couple of helper functions we could pass opp pointers instead of doing additional parameters to handle quiet a bit of data parameters. @@ -273,8 +273,8 @@ opp_get_freq - Retrieve the freq represented by the opp pointer. /* do things.. */ max_freq = ULONG_MAX; rcu_read_lock(); - max_opp = opp_find_freq_floor(dev,&max_freq); - requested_opp = opp_find_freq_ceil(dev,&freq); + max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); + requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) r = soc_test_validity(max_opp, requested_opp); rcu_read_unlock(); @@ -282,25 +282,25 @@ opp_get_freq - Retrieve the freq represented by the opp pointer. } soc_test_validity(..) { - if(opp_get_voltage(max_opp) < opp_get_voltage(requested_opp)) + if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp)) return -EINVAL; - if(opp_get_freq(max_opp) < opp_get_freq(requested_opp)) + if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp)) return -EINVAL; /* do things.. */ } -opp_get_opp_count - Retrieve the number of available opps for a device +dev_pm_opp_get_opp_count - Retrieve the number of available opps for a device Example: Lets say a co-processor in the SoC needs to know the available frequencies in a table, the main processor can notify as following: soc_notify_coproc_available_frequencies() { /* Do things */ rcu_read_lock(); - num_available = opp_get_opp_count(dev); + num_available = dev_pm_opp_get_opp_count(dev); speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL); /* populate the table in increasing order */ freq = 0; - while (!IS_ERR(opp = opp_find_freq_ceil(dev, &freq))) { + while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) { speeds[i] = freq; freq++; i++; @@ -313,7 +313,7 @@ opp_get_opp_count - Retrieve the number of available opps for a device 6. Cpufreq Table Generation =========================== -opp_init_cpufreq_table - cpufreq framework typically is initialized with +dev_pm_opp_init_cpufreq_table - cpufreq framework typically is initialized with cpufreq_frequency_table_cpuinfo which is provided with the list of frequencies that are available for operation. This function provides a ready to use conversion routine to translate the OPP layer's internal @@ -326,7 +326,7 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with soc_pm_init() { /* Do things */ - r = opp_init_cpufreq_table(dev, &freq_table); + r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); if (!r) cpufreq_frequency_table_cpuinfo(policy, freq_table); /* Do other things */ @@ -336,7 +336,7 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with addition to CONFIG_PM as power management feature is required to dynamically scale voltage and frequency in a system. -opp_free_cpufreq_table - Free up the table allocated by opp_init_cpufreq_table +dev_pm_opp_free_cpufreq_table - Free up the table allocated by dev_pm_opp_init_cpufreq_table 7. Data Structures ================== @@ -366,8 +366,8 @@ struct opp - The internal data structure of OPP library which is used to identifier for OPP in the interactions with OPP layer. WARNING: The struct opp pointer should not be parsed or modified by the - users. The defaults of for an instance is populated by opp_add, but the - availability of the OPP can be modified by opp_enable/disable functions. + users. The defaults of for an instance is populated by dev_pm_opp_add, but the + availability of the OPP can be modified by dev_pm_opp_enable/disable functions. struct device - This is used to identify a domain to the OPP layer. The nature of the device and it's implementation is left to the user of @@ -377,19 +377,19 @@ Overall, in a simplistic view, the data structure operations is represented as following: Initialization / modification: - +-----+ /- opp_enable -opp_add --> | opp | <------- - | +-----+ \- opp_disable + +-----+ /- dev_pm_opp_enable +dev_pm_opp_add --> | opp | <------- + | +-----+ \- dev_pm_opp_disable \-------> domain_info(device) Search functions: - /-- opp_find_freq_ceil ---\ +-----+ -domain_info<---- opp_find_freq_exact -----> | opp | - \-- opp_find_freq_floor ---/ +-----+ + /-- dev_pm_opp_find_freq_ceil ---\ +-----+ +domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | + \-- dev_pm_opp_find_freq_floor ---/ +-----+ Retrieval functions: -+-----+ /- opp_get_voltage ++-----+ /- dev_pm_opp_get_voltage | opp | <--- -+-----+ \- opp_get_freq ++-----+ \- dev_pm_opp_get_freq -domain_info <- opp_get_opp_count +domain_info <- dev_pm_opp_get_opp_count diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 90372a21087f..d7ecc90e6bba 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -226,7 +226,7 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev) val = readl_relaxed(base + OCOTP_CFG3); val >>= OCOTP_CFG3_SPEED_SHIFT; if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) - if (opp_disable(cpu_dev, 1200000000)) + if (dev_pm_opp_disable(cpu_dev, 1200000000)) pr_warn("failed to disable 1.2 GHz OPP\n"); put_node: diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index f26918467efc..33969e5a149f 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -522,11 +522,11 @@ static int __init beagle_opp_init(void) return -ENODEV; } /* Enable MPU 1GHz and lower opps */ - r = opp_enable(mpu_dev, 800000000); + r = dev_pm_opp_enable(mpu_dev, 800000000); /* TODO: MPU 1GHz needs SR and ABB */ /* Enable IVA 800MHz and lower opps */ - r |= opp_enable(iva_dev, 660000000); + r |= dev_pm_opp_enable(iva_dev, 660000000); /* TODO: DSP 800MHz needs SR and ABB */ if (r) { pr_err("%s: failed to enable higher opp %d\n", @@ -535,8 +535,8 @@ static int __init beagle_opp_init(void) * Cleanup - disable the higher freqs - we dont care * about the results */ - opp_disable(mpu_dev, 800000000); - opp_disable(iva_dev, 660000000); + dev_pm_opp_disable(mpu_dev, 800000000); + dev_pm_opp_disable(iva_dev, 660000000); } } return 0; diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index bd41d59a7cab..7b04637b13cb 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -81,14 +81,14 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, dev = &oh->od->pdev->dev; } - r = opp_add(dev, opp_def->freq, opp_def->u_volt); + r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt); if (r) { dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", __func__, opp_def->freq, opp_def->hwmod_name, i, r); } else { if (!opp_def->default_available) - r = opp_disable(dev, opp_def->freq); + r = dev_pm_opp_disable(dev, opp_def->freq); if (r) dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", __func__, opp_def->freq, diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index e742118fcfd2..937744c3679d 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -172,7 +172,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, clk_put(clk); rcu_read_lock(); - opp = opp_find_freq_ceil(dev, &freq); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); if (IS_ERR(opp)) { rcu_read_unlock(); pr_err("%s: unable to find boot up OPP for vdd_%s\n", @@ -180,7 +180,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, goto exit; } - bootup_volt = opp_get_voltage(opp); + bootup_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); if (!bootup_volt) { pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n", diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index ef89897c6043..00c6a449cdeb 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -136,7 +136,7 @@ static struct device_opp *find_device_opp(struct device *dev) } /** - * opp_get_voltage() - Gets the voltage corresponding to an available opp + * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an available opp * @opp: opp for which voltage has to be returned for * * Return voltage in micro volt corresponding to the opp, else @@ -150,7 +150,7 @@ static struct device_opp *find_device_opp(struct device *dev) * prior to unlocking with rcu_read_unlock() to maintain the integrity of the * pointer. */ -unsigned long opp_get_voltage(struct opp *opp) +unsigned long dev_pm_opp_get_voltage(struct opp *opp) { struct opp *tmp_opp; unsigned long v = 0; @@ -163,10 +163,10 @@ unsigned long opp_get_voltage(struct opp *opp) return v; } -EXPORT_SYMBOL_GPL(opp_get_voltage); +EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage); /** - * opp_get_freq() - Gets the frequency corresponding to an available opp + * dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp * @opp: opp for which frequency has to be returned for * * Return frequency in hertz corresponding to the opp, else @@ -180,7 +180,7 @@ EXPORT_SYMBOL_GPL(opp_get_voltage); * prior to unlocking with rcu_read_unlock() to maintain the integrity of the * pointer. */ -unsigned long opp_get_freq(struct opp *opp) +unsigned long dev_pm_opp_get_freq(struct opp *opp) { struct opp *tmp_opp; unsigned long f = 0; @@ -193,10 +193,10 @@ unsigned long opp_get_freq(struct opp *opp) return f; } -EXPORT_SYMBOL_GPL(opp_get_freq); +EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); /** - * opp_get_opp_count() - Get number of opps available in the opp list + * dev_pm_opp_get_opp_count() - Get number of opps available in the opp list * @dev: device for which we do this operation * * This function returns the number of available opps if there are any, @@ -206,7 +206,7 @@ EXPORT_SYMBOL_GPL(opp_get_freq); * internally references two RCU protected structures: device_opp and opp which * are safe as long as we are under a common RCU locked section. */ -int opp_get_opp_count(struct device *dev) +int dev_pm_opp_get_opp_count(struct device *dev) { struct device_opp *dev_opp; struct opp *temp_opp; @@ -226,10 +226,10 @@ int opp_get_opp_count(struct device *dev) return count; } -EXPORT_SYMBOL_GPL(opp_get_opp_count); +EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); /** - * opp_find_freq_exact() - search for an exact frequency + * dev_pm_opp_find_freq_exact() - search for an exact frequency * @dev: device for which we do this operation * @freq: frequency to search for * @available: true/false - match for available opp @@ -254,7 +254,7 @@ EXPORT_SYMBOL_GPL(opp_get_opp_count); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, +struct opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { struct device_opp *dev_opp; @@ -277,10 +277,10 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, return opp; } -EXPORT_SYMBOL_GPL(opp_find_freq_exact); +EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); /** - * opp_find_freq_ceil() - Search for an rounded ceil freq + * dev_pm_opp_find_freq_ceil() - Search for an rounded ceil freq * @dev: device for which we do this operation * @freq: Start frequency * @@ -300,7 +300,7 @@ EXPORT_SYMBOL_GPL(opp_find_freq_exact); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) +struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { struct device_opp *dev_opp; struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); @@ -324,10 +324,10 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) return opp; } -EXPORT_SYMBOL_GPL(opp_find_freq_ceil); +EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); /** - * opp_find_freq_floor() - Search for a rounded floor freq + * dev_pm_opp_find_freq_floor() - Search for a rounded floor freq * @dev: device for which we do this operation * @freq: Start frequency * @@ -347,7 +347,7 @@ EXPORT_SYMBOL_GPL(opp_find_freq_ceil); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) +struct opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { struct device_opp *dev_opp; struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); @@ -375,17 +375,17 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) return opp; } -EXPORT_SYMBOL_GPL(opp_find_freq_floor); +EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); /** - * opp_add() - Add an OPP table from a table definitions + * dev_pm_opp_add() - Add an OPP table from a table definitions * @dev: device for which we do this operation * @freq: Frequency in Hz for this OPP * @u_volt: Voltage in uVolts for this OPP * * This function adds an opp definition to the opp list and returns status. * The opp is made available by default and it can be controlled using - * opp_enable/disable functions. + * dev_pm_opp_enable/disable functions. * * Locking: The internal device_opp and opp structures are RCU protected. * Hence this function internally uses RCU updater strategy with mutex locks @@ -393,7 +393,7 @@ EXPORT_SYMBOL_GPL(opp_find_freq_floor); * that this function is *NOT* called under RCU protection or in contexts where * mutex cannot be locked. */ -int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) +int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) { struct device_opp *dev_opp = NULL; struct opp *opp, *new_opp; @@ -460,7 +460,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp); return 0; } -EXPORT_SYMBOL_GPL(opp_add); +EXPORT_SYMBOL_GPL(dev_pm_opp_add); /** * opp_set_availability() - helper to set the availability of an opp @@ -552,13 +552,13 @@ unlock: } /** - * opp_enable() - Enable a specific OPP + * dev_pm_opp_enable() - Enable a specific OPP * @dev: device for which we do this operation * @freq: OPP frequency to enable * * Enables a provided opp. If the operation is valid, this returns 0, else the * corresponding error value. It is meant to be used for users an OPP available - * after being temporarily made unavailable with opp_disable. + * after being temporarily made unavailable with dev_pm_opp_disable. * * Locking: The internal device_opp and opp structures are RCU protected. * Hence this function indirectly uses RCU and mutex locks to keep the @@ -566,21 +566,21 @@ unlock: * this function is *NOT* called under RCU protection or in contexts where * mutex locking or synchronize_rcu() blocking calls cannot be used. */ -int opp_enable(struct device *dev, unsigned long freq) +int dev_pm_opp_enable(struct device *dev, unsigned long freq) { return opp_set_availability(dev, freq, true); } -EXPORT_SYMBOL_GPL(opp_enable); +EXPORT_SYMBOL_GPL(dev_pm_opp_enable); /** - * opp_disable() - Disable a specific OPP + * dev_pm_opp_disable() - Disable a specific OPP * @dev: device for which we do this operation * @freq: OPP frequency to disable * * Disables a provided opp. If the operation is valid, this returns * 0, else the corresponding error value. It is meant to be a temporary * control by users to make this OPP not available until the circumstances are - * right to make it available again (with a call to opp_enable). + * right to make it available again (with a call to dev_pm_opp_enable). * * Locking: The internal device_opp and opp structures are RCU protected. * Hence this function indirectly uses RCU and mutex locks to keep the @@ -588,15 +588,15 @@ EXPORT_SYMBOL_GPL(opp_enable); * this function is *NOT* called under RCU protection or in contexts where * mutex locking or synchronize_rcu() blocking calls cannot be used. */ -int opp_disable(struct device *dev, unsigned long freq) +int dev_pm_opp_disable(struct device *dev, unsigned long freq) { return opp_set_availability(dev, freq, false); } -EXPORT_SYMBOL_GPL(opp_disable); +EXPORT_SYMBOL_GPL(dev_pm_opp_disable); #ifdef CONFIG_CPU_FREQ /** - * opp_init_cpufreq_table() - create a cpufreq table for a device + * dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device * @dev: device for which we do this operation * @table: Cpufreq table returned back to caller * @@ -619,7 +619,7 @@ EXPORT_SYMBOL_GPL(opp_disable); * Callers should ensure that this function is *NOT* called under RCU protection * or in contexts where mutex locking cannot be used. */ -int opp_init_cpufreq_table(struct device *dev, +int dev_pm_opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { struct device_opp *dev_opp; @@ -639,7 +639,7 @@ int opp_init_cpufreq_table(struct device *dev, } freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * - (opp_get_opp_count(dev) + 1), GFP_KERNEL); + (dev_pm_opp_get_opp_count(dev) + 1), GFP_KERNEL); if (!freq_table) { mutex_unlock(&dev_opp_list_lock); dev_warn(dev, "%s: Unable to allocate frequency table\n", @@ -663,16 +663,16 @@ int opp_init_cpufreq_table(struct device *dev, return 0; } -EXPORT_SYMBOL_GPL(opp_init_cpufreq_table); +EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); /** - * opp_free_cpufreq_table() - free the cpufreq table + * dev_pm_opp_free_cpufreq_table() - free the cpufreq table * @dev: device for which we do this operation * @table: table to free * - * Free up the table allocated by opp_init_cpufreq_table + * Free up the table allocated by dev_pm_opp_init_cpufreq_table */ -void opp_free_cpufreq_table(struct device *dev, +void dev_pm_opp_free_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { if (!table) @@ -681,14 +681,14 @@ void opp_free_cpufreq_table(struct device *dev, kfree(*table); *table = NULL; } -EXPORT_SYMBOL_GPL(opp_free_cpufreq_table); +EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table); #endif /* CONFIG_CPU_FREQ */ /** - * opp_get_notifier() - find notifier_head of the device with opp + * dev_pm_opp_get_notifier() - find notifier_head of the device with opp * @dev: device pointer used to lookup device OPPs. */ -struct srcu_notifier_head *opp_get_notifier(struct device *dev) +struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev) { struct device_opp *dev_opp = find_device_opp(dev); @@ -732,7 +732,7 @@ int of_init_opp_table(struct device *dev) unsigned long freq = be32_to_cpup(val++) * 1000; unsigned long volt = be32_to_cpup(val++); - if (opp_add(dev, freq, volt)) { + if (dev_pm_opp_add(dev, freq, volt)) { dev_warn(dev, "%s: Failed to add OPP %ld\n", __func__, freq); continue; diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 3549f0784af1..9e82a9d5df77 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -98,7 +98,7 @@ static void put_cluster_clk_and_freq_table(struct device *cpu_dev) if (!atomic_dec_return(&cluster_usage[cluster])) { clk_put(clk[cluster]); - opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); dev_dbg(cpu_dev, "%s: cluster: %d\n", __func__, cluster); } } @@ -119,7 +119,7 @@ static int get_cluster_clk_and_freq_table(struct device *cpu_dev) goto atomic_dec; } - ret = opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]); + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]); if (ret) { dev_err(cpu_dev, "%s: failed to init cpufreq table, cpu: %d, err: %d\n", __func__, cpu_dev->id, ret); @@ -138,7 +138,7 @@ static int get_cluster_clk_and_freq_table(struct device *cpu_dev) dev_err(cpu_dev, "%s: Failed to get clk for cpu: %d, cluster: %d\n", __func__, cpu_dev->id, cluster); ret = PTR_ERR(clk[cluster]); - opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); atomic_dec: atomic_dec(&cluster_usage[cluster]); diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index c522a95c0e16..af951a9cea78 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -72,7 +72,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, if (!IS_ERR(cpu_reg)) { rcu_read_lock(); - opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); if (IS_ERR(opp)) { rcu_read_unlock(); pr_err("failed to find OPP for %ld\n", freq_Hz); @@ -80,7 +80,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, ret = PTR_ERR(opp); goto post_notify; } - volt = opp_get_voltage(opp); + volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); tol = volt * voltage_tolerance / 100; volt_old = regulator_get_voltage(cpu_reg); @@ -218,7 +218,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) goto out_put_node; } - ret = opp_init_cpufreq_table(cpu_dev, &freq_table); + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); if (ret) { pr_err("failed to init cpufreq table: %d\n", ret); goto out_put_node; @@ -242,12 +242,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) ; rcu_read_lock(); - opp = opp_find_freq_exact(cpu_dev, + opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[0].frequency * 1000, true); - min_uV = opp_get_voltage(opp); - opp = opp_find_freq_exact(cpu_dev, + min_uV = dev_pm_opp_get_voltage(opp); + opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[i-1].frequency * 1000, true); - max_uV = opp_get_voltage(opp); + max_uV = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); if (ret > 0) @@ -264,7 +264,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) return 0; out_free_table: - opp_free_cpufreq_table(cpu_dev, &freq_table); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); out_put_node: of_node_put(np); return ret; @@ -273,7 +273,7 @@ out_put_node: static int cpu0_cpufreq_remove(struct platform_device *pdev) { cpufreq_unregister_driver(&cpu0_cpufreq_driver); - opp_free_cpufreq_table(cpu_dev, &freq_table); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); return 0; } diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index be5380ecdcd4..444eca74d3c2 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -123,7 +123,7 @@ static int init_div_table(void) rcu_read_lock(); for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { - opp = opp_find_freq_exact(dvfs_info->dev, + opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, freq_tbl[i].frequency * 1000, true); if (IS_ERR(opp)) { rcu_read_unlock(); @@ -142,7 +142,7 @@ static int init_div_table(void) << P0_7_CSCLKDEV_SHIFT; /* Calculate EMA */ - volt_id = opp_get_voltage(opp); + volt_id = dev_pm_opp_get_voltage(opp); volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; if (volt_id < PMIC_HIGH_VOLT) { ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | @@ -399,13 +399,14 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) goto err_put_node; } - ret = opp_init_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); + ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, + &dvfs_info->freq_table); if (ret) { dev_err(dvfs_info->dev, "failed to init cpufreq table: %d\n", ret); goto err_put_node; } - dvfs_info->freq_count = opp_get_opp_count(dvfs_info->dev); + dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); exynos_sort_descend_freq_table(); if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) @@ -454,7 +455,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) return 0; err_free_table: - opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); + dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); err_put_node: of_node_put(np); dev_err(&pdev->dev, "%s: failed initialization\n", __func__); @@ -464,7 +465,7 @@ err_put_node: static int exynos_cpufreq_remove(struct platform_device *pdev) { cpufreq_unregister_driver(&exynos_driver); - opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); + dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); return 0; } diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index c3fd2a101ca0..b360549e7715 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -70,14 +70,14 @@ static int imx6q_set_target(struct cpufreq_policy *policy, return 0; rcu_read_lock(); - opp = opp_find_freq_ceil(cpu_dev, &freq_hz); + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); if (IS_ERR(opp)) { rcu_read_unlock(); dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz); return PTR_ERR(opp); } - volt = opp_get_voltage(opp); + volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); volt_old = regulator_get_voltage(arm_reg); @@ -237,14 +237,14 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) } /* We expect an OPP table supplied by platform */ - num = opp_get_opp_count(cpu_dev); + num = dev_pm_opp_get_opp_count(cpu_dev); if (num < 0) { ret = num; dev_err(cpu_dev, "no OPP table is found: %d\n", ret); goto put_node; } - ret = opp_init_cpufreq_table(cpu_dev, &freq_table); + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); if (ret) { dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); goto put_node; @@ -259,12 +259,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) * same order. */ rcu_read_lock(); - opp = opp_find_freq_exact(cpu_dev, + opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[0].frequency * 1000, true); - min_volt = opp_get_voltage(opp); - opp = opp_find_freq_exact(cpu_dev, + min_volt = dev_pm_opp_get_voltage(opp); + opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[--num].frequency * 1000, true); - max_volt = opp_get_voltage(opp); + max_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt); if (ret > 0) @@ -292,7 +292,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) return 0; free_freq_table: - opp_free_cpufreq_table(cpu_dev, &freq_table); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); put_node: of_node_put(np); return ret; @@ -301,7 +301,7 @@ put_node: static int imx6q_cpufreq_remove(struct platform_device *pdev) { cpufreq_unregister_driver(&imx6q_cpufreq_driver); - opp_free_cpufreq_table(cpu_dev, &freq_table); + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); return 0; } diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index f31fcfcad514..c5e31d296607 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -105,14 +105,14 @@ static int omap_target(struct cpufreq_policy *policy, if (mpu_reg) { rcu_read_lock(); - opp = opp_find_freq_ceil(mpu_dev, &freq); + opp = dev_pm_opp_find_freq_ceil(mpu_dev, &freq); if (IS_ERR(opp)) { rcu_read_unlock(); dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", __func__, freqs.new); return -EINVAL; } - volt = opp_get_voltage(opp); + volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); tol = volt * OPP_TOLERANCE / 100; volt_old = regulator_get_voltage(mpu_reg); @@ -162,7 +162,7 @@ done: static inline void freq_table_free(void) { if (atomic_dec_and_test(&freq_table_users)) - opp_free_cpufreq_table(mpu_dev, &freq_table); + dev_pm_opp_free_cpufreq_table(mpu_dev, &freq_table); } static int omap_cpu_init(struct cpufreq_policy *policy) @@ -181,7 +181,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy) policy->cur = omap_getspeed(policy->cpu); if (!freq_table) - result = opp_init_cpufreq_table(mpu_dev, &freq_table); + result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); if (result) { dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index c99c00d35d34..f798edcb910d 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -908,7 +908,7 @@ static ssize_t available_frequencies_show(struct device *d, rcu_read_lock(); do { - opp = opp_find_freq_ceil(dev, &freq); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); if (IS_ERR(opp)) break; @@ -1036,18 +1036,18 @@ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { /* The freq is an upper bound. opp should be lower */ - opp = opp_find_freq_floor(dev, freq); + opp = dev_pm_opp_find_freq_floor(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ERANGE)) - opp = opp_find_freq_ceil(dev, freq); + opp = dev_pm_opp_find_freq_ceil(dev, freq); } else { /* The freq is an lower bound. opp should be higher */ - opp = opp_find_freq_ceil(dev, freq); + opp = dev_pm_opp_find_freq_ceil(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ERANGE)) - opp = opp_find_freq_floor(dev, freq); + opp = dev_pm_opp_find_freq_floor(dev, freq); } return opp; @@ -1066,7 +1066,7 @@ int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) int ret = 0; rcu_read_lock(); - nh = opp_get_notifier(dev); + nh = dev_pm_opp_get_notifier(dev); if (IS_ERR(nh)) ret = PTR_ERR(nh); rcu_read_unlock(); @@ -1092,7 +1092,7 @@ int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) int ret = 0; rcu_read_lock(); - nh = opp_get_notifier(dev); + nh = dev_pm_opp_get_notifier(dev); if (IS_ERR(nh)) ret = PTR_ERR(nh); rcu_read_unlock(); diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index c5f86d8caca3..33c0e05a5ff1 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -650,8 +650,8 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq, rcu_read_unlock(); return PTR_ERR(opp); } - new_oppinfo.rate = opp_get_freq(opp); - new_oppinfo.volt = opp_get_voltage(opp); + new_oppinfo.rate = dev_pm_opp_get_freq(opp); + new_oppinfo.volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); freq = new_oppinfo.rate; @@ -873,7 +873,7 @@ static int exynos4210_init_tables(struct busfreq_data *data) exynos4210_busclk_table[i].volt = exynos4210_asv_volt[mgrp][i]; for (i = LV_0; i < EX4210_LV_NUM; i++) { - err = opp_add(data->dev, exynos4210_busclk_table[i].clk, + err = dev_pm_opp_add(data->dev, exynos4210_busclk_table[i].clk, exynos4210_busclk_table[i].volt); if (err) { dev_err(data->dev, "Cannot add opp entries.\n"); @@ -940,7 +940,7 @@ static int exynos4x12_init_tables(struct busfreq_data *data) } for (i = 0; i < EX4x12_LV_NUM; i++) { - ret = opp_add(data->dev, exynos4x12_mifclk_table[i].clk, + ret = dev_pm_opp_add(data->dev, exynos4x12_mifclk_table[i].clk, exynos4x12_mifclk_table[i].volt); if (ret) { dev_err(data->dev, "Fail to add opp entries.\n"); @@ -969,7 +969,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, data->disabled = true; rcu_read_lock(); - opp = opp_find_freq_floor(data->dev, &maxfreq); + opp = dev_pm_opp_find_freq_floor(data->dev, &maxfreq); if (IS_ERR(opp)) { rcu_read_unlock(); dev_err(data->dev, "%s: unable to find a min freq\n", @@ -977,8 +977,8 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, mutex_unlock(&data->lock); return PTR_ERR(opp); } - new_oppinfo.rate = opp_get_freq(opp); - new_oppinfo.volt = opp_get_voltage(opp); + new_oppinfo.rate = dev_pm_opp_get_freq(opp); + new_oppinfo.volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); err = exynos4_bus_setvolt(data, &new_oppinfo, @@ -1065,15 +1065,16 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) } rcu_read_lock(); - opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq); + opp = dev_pm_opp_find_freq_floor(dev, + &exynos4_devfreq_profile.initial_freq); if (IS_ERR(opp)) { rcu_read_unlock(); dev_err(dev, "Invalid initial frequency %lu kHz.\n", exynos4_devfreq_profile.initial_freq); return PTR_ERR(opp); } - data->curr_oppinfo.rate = opp_get_freq(opp); - data->curr_oppinfo.volt = opp_get_voltage(opp); + data->curr_oppinfo.rate = dev_pm_opp_get_freq(opp); + data->curr_oppinfo.volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); platform_set_drvdata(pdev, data); diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index 574b16b59be5..b0e45925505b 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c @@ -144,8 +144,8 @@ static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq, return PTR_ERR(opp); } - freq = opp_get_freq(opp); - volt = opp_get_voltage(opp); + freq = dev_pm_opp_get_freq(opp); + volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); old_freq = data->curr_freq; @@ -246,7 +246,7 @@ static int exynos5250_init_int_tables(struct busfreq_data_int *data) int i, err = 0; for (i = LV_0; i < _LV_END; i++) { - err = opp_add(data->dev, exynos5_int_opp_table[i].clk, + err = dev_pm_opp_add(data->dev, exynos5_int_opp_table[i].clk, exynos5_int_opp_table[i].volt); if (err) { dev_err(data->dev, "Cannot add opp entries.\n"); @@ -276,14 +276,14 @@ static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this, data->disabled = true; rcu_read_lock(); - opp = opp_find_freq_floor(data->dev, &maxfreq); + opp = dev_pm_opp_find_freq_floor(data->dev, &maxfreq); if (IS_ERR(opp)) { rcu_read_unlock(); err = PTR_ERR(opp); goto unlock; } - freq = opp_get_freq(opp); - volt = opp_get_voltage(opp); + freq = dev_pm_opp_get_freq(opp); + volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); err = exynos5_int_setvolt(data, volt); @@ -368,7 +368,7 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) } rcu_read_lock(); - opp = opp_find_freq_floor(dev, + opp = dev_pm_opp_find_freq_floor(dev, &exynos5_devfreq_int_profile.initial_freq); if (IS_ERR(opp)) { rcu_read_unlock(); @@ -377,8 +377,8 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) err = PTR_ERR(opp); goto err_opp_add; } - initial_freq = opp_get_freq(opp); - initial_volt = opp_get_voltage(opp); + initial_freq = dev_pm_opp_get_freq(opp); + initial_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); data->curr_freq = initial_freq; diff --git a/include/linux/opp.h b/include/linux/opp.h index 3aca2b8def33..2066ae5880c6 100644 --- a/include/linux/opp.h +++ b/include/linux/opp.h @@ -27,77 +27,79 @@ enum opp_event { #if defined(CONFIG_PM_OPP) -unsigned long opp_get_voltage(struct opp *opp); +unsigned long dev_pm_opp_get_voltage(struct opp *opp); -unsigned long opp_get_freq(struct opp *opp); +unsigned long dev_pm_opp_get_freq(struct opp *opp); -int opp_get_opp_count(struct device *dev); +int dev_pm_opp_get_opp_count(struct device *dev); -struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, +struct opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available); -struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq); +struct opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq); -struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq); +struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq); -int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt); +int dev_pm_opp_add(struct device *dev, unsigned long freq, + unsigned long u_volt); -int opp_enable(struct device *dev, unsigned long freq); +int dev_pm_opp_enable(struct device *dev, unsigned long freq); -int opp_disable(struct device *dev, unsigned long freq); +int dev_pm_opp_disable(struct device *dev, unsigned long freq); -struct srcu_notifier_head *opp_get_notifier(struct device *dev); +struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); #else -static inline unsigned long opp_get_voltage(struct opp *opp) +static inline unsigned long dev_pm_opp_get_voltage(struct opp *opp) { return 0; } -static inline unsigned long opp_get_freq(struct opp *opp) +static inline unsigned long dev_pm_opp_get_freq(struct opp *opp) { return 0; } -static inline int opp_get_opp_count(struct device *dev) +static inline int dev_pm_opp_get_opp_count(struct device *dev) { return 0; } -static inline struct opp *opp_find_freq_exact(struct device *dev, +static inline struct opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { return ERR_PTR(-EINVAL); } -static inline struct opp *opp_find_freq_floor(struct device *dev, +static inline struct opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { return ERR_PTR(-EINVAL); } -static inline struct opp *opp_find_freq_ceil(struct device *dev, +static inline struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { return ERR_PTR(-EINVAL); } -static inline int opp_add(struct device *dev, unsigned long freq, +static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) { return -EINVAL; } -static inline int opp_enable(struct device *dev, unsigned long freq) +static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) { return 0; } -static inline int opp_disable(struct device *dev, unsigned long freq) +static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) { return 0; } -static inline struct srcu_notifier_head *opp_get_notifier(struct device *dev) +static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( + struct device *dev) { return ERR_PTR(-EINVAL); } @@ -113,19 +115,19 @@ static inline int of_init_opp_table(struct device *dev) #endif #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) -int opp_init_cpufreq_table(struct device *dev, +int dev_pm_opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table); -void opp_free_cpufreq_table(struct device *dev, +void dev_pm_opp_free_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table); #else -static inline int opp_init_cpufreq_table(struct device *dev, +static inline int dev_pm_opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { return -EINVAL; } static inline -void opp_free_cpufreq_table(struct device *dev, +void dev_pm_opp_free_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { } -- cgit v1.2.3 From 47d43ba73eb98d8ba731208735c899129d9849e1 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 19 Sep 2013 16:03:51 -0500 Subject: PM / OPP: rename data structures to dev_pm equivalents Since Operating Performance Points (OPP) data structures are specific to device specific power management, be specific and rename opp_* data structures in OPP library with dev_pm_opp_* equivalent. Affected structures are: struct opp enum opp_event Minor checkpatch warning resulting of this change was fixed as well. Reported-by: Randy Dunlap Signed-off-by: Nishanth Menon Signed-off-by: Rafael J. Wysocki --- Documentation/power/opp.txt | 4 ++-- arch/arm/mach-omap2/pm.c | 2 +- drivers/base/power/opp.c | 41 +++++++++++++++++++----------------- drivers/cpufreq/cpufreq-cpu0.c | 4 ++-- drivers/cpufreq/exynos5440-cpufreq.c | 2 +- drivers/cpufreq/imx6q-cpufreq.c | 4 ++-- drivers/cpufreq/omap-cpufreq.c | 2 +- drivers/devfreq/devfreq.c | 9 ++++---- drivers/devfreq/exynos/exynos4_bus.c | 6 +++--- drivers/devfreq/exynos/exynos5_bus.c | 6 +++--- include/linux/devfreq.h | 4 ++-- include/linux/opp.h | 29 +++++++++++++------------ 12 files changed, 60 insertions(+), 53 deletions(-) (limited to 'include/linux') diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index 185367b1848f..7f67e3d2c530 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt @@ -358,14 +358,14 @@ accessed by various functions as described above. However, the structures representing the actual OPPs and domains are internal to the OPP library itself to allow for suitable abstraction reusable across systems. -struct opp - The internal data structure of OPP library which is used to +struct dev_pm_opp - The internal data structure of OPP library which is used to represent an OPP. In addition to the freq, voltage, availability information, it also contains internal book keeping information required for the OPP library to operate on. Pointer to this structure is provided back to the users such as SoC framework to be used as a identifier for OPP in the interactions with OPP layer. - WARNING: The struct opp pointer should not be parsed or modified by the + WARNING: The struct dev_pm_opp pointer should not be parsed or modified by the users. The defaults of for an instance is populated by dev_pm_opp_add, but the availability of the OPP can be modified by dev_pm_opp_enable/disable functions. diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 937744c3679d..92901bd41490 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -131,7 +131,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, { struct voltagedomain *voltdm; struct clk *clk; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long freq, bootup_volt; struct device *dev; diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 00c6a449cdeb..693e14a24914 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -42,7 +42,7 @@ */ /** - * struct opp - Generic OPP description structure + * struct dev_pm_opp - Generic OPP description structure * @node: opp list node. The nodes are maintained throughout the lifetime * of boot. It is expected only an optimal set of OPPs are * added to the library by the SoC framework. @@ -59,7 +59,7 @@ * * This structure stores the OPP information for a given device. */ -struct opp { +struct dev_pm_opp { struct list_head node; bool available; @@ -150,9 +150,9 @@ static struct device_opp *find_device_opp(struct device *dev) * prior to unlocking with rcu_read_unlock() to maintain the integrity of the * pointer. */ -unsigned long dev_pm_opp_get_voltage(struct opp *opp) +unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) { - struct opp *tmp_opp; + struct dev_pm_opp *tmp_opp; unsigned long v = 0; tmp_opp = rcu_dereference(opp); @@ -180,9 +180,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage); * prior to unlocking with rcu_read_unlock() to maintain the integrity of the * pointer. */ -unsigned long dev_pm_opp_get_freq(struct opp *opp) +unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) { - struct opp *tmp_opp; + struct dev_pm_opp *tmp_opp; unsigned long f = 0; tmp_opp = rcu_dereference(opp); @@ -209,7 +209,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); int dev_pm_opp_get_opp_count(struct device *dev) { struct device_opp *dev_opp; - struct opp *temp_opp; + struct dev_pm_opp *temp_opp; int count = 0; dev_opp = find_device_opp(dev); @@ -254,11 +254,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, - bool available) +struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, + unsigned long freq, + bool available) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); + struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { @@ -300,10 +301,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) +struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, + unsigned long *freq) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); + struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); @@ -347,10 +349,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) +struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, + unsigned long *freq) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); + struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); @@ -396,11 +399,11 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) { struct device_opp *dev_opp = NULL; - struct opp *opp, *new_opp; + struct dev_pm_opp *opp, *new_opp; struct list_head *head; /* allocate new OPP node */ - new_opp = kzalloc(sizeof(struct opp), GFP_KERNEL); + new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); if (!new_opp) { dev_warn(dev, "%s: Unable to create new OPP node\n", __func__); return -ENOMEM; @@ -485,11 +488,11 @@ static int opp_set_availability(struct device *dev, unsigned long freq, bool availability_req) { struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); - struct opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); + struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); int r = 0; /* keep the node allocated */ - new_opp = kmalloc(sizeof(struct opp), GFP_KERNEL); + new_opp = kmalloc(sizeof(*new_opp), GFP_KERNEL); if (!new_opp) { dev_warn(dev, "%s: Unable to create OPP\n", __func__); return -ENOMEM; @@ -623,7 +626,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { struct device_opp *dev_opp; - struct opp *opp; + struct dev_pm_opp *opp; struct cpufreq_frequency_table *freq_table; int i = 0; diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index af951a9cea78..d73107894fee 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { struct cpufreq_freqs freqs; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long volt = 0, volt_old = 0, tol = 0; long freq_Hz, freq_exact; unsigned int index; @@ -230,7 +230,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) transition_latency = CPUFREQ_ETERNAL; if (!IS_ERR(cpu_reg)) { - struct opp *opp; + struct dev_pm_opp *opp; unsigned long min_uV, max_uV; int i; diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 444eca74d3c2..c8b3d3950f9e 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -118,7 +118,7 @@ static int init_div_table(void) struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; unsigned int tmp, clk_div, ema_div, freq, volt_id; int i = 0; - struct opp *opp; + struct dev_pm_opp *opp; rcu_read_lock(); for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index b360549e7715..84e993dfb305 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -49,7 +49,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { struct cpufreq_freqs freqs; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long freq_hz, volt, volt_old; unsigned int index; int ret; @@ -199,7 +199,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { static int imx6q_cpufreq_probe(struct platform_device *pdev) { struct device_node *np; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long min_volt, max_volt; int num, ret; diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index c5e31d296607..f057d423020c 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -65,7 +65,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int i; int r, ret = 0; struct cpufreq_freqs freqs; - struct opp *opp; + struct dev_pm_opp *opp; unsigned long freq, volt = 0, volt_old = 0, tol = 0; if (!freq_table) { diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index f798edcb910d..03530a0a8042 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -902,7 +902,7 @@ static ssize_t available_frequencies_show(struct device *d, { struct devfreq *df = to_devfreq(d); struct device *dev = df->dev.parent; - struct opp *opp; + struct dev_pm_opp *opp; ssize_t count = 0; unsigned long freq = 0; @@ -1029,10 +1029,11 @@ module_exit(devfreq_exit); * under the locked area. The pointer returned must be used prior to unlocking * with rcu_read_unlock() to maintain the integrity of the pointer. */ -struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, - u32 flags) +struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, + unsigned long *freq, + u32 flags) { - struct opp *opp; + struct dev_pm_opp *opp; if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { /* The freq is an upper bound. opp should be lower */ diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 33c0e05a5ff1..891becd46513 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -639,7 +639,7 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq, struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct busfreq_data *data = platform_get_drvdata(pdev); - struct opp *opp; + struct dev_pm_opp *opp; unsigned long freq; unsigned long old_freq = data->curr_oppinfo.rate; struct busfreq_opp_info new_oppinfo; @@ -956,7 +956,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, { struct busfreq_data *data = container_of(this, struct busfreq_data, pm_notifier); - struct opp *opp; + struct dev_pm_opp *opp; struct busfreq_opp_info new_oppinfo; unsigned long maxfreq = ULONG_MAX; int err = 0; @@ -1020,7 +1020,7 @@ unlock: static int exynos4_busfreq_probe(struct platform_device *pdev) { struct busfreq_data *data; - struct opp *opp; + struct dev_pm_opp *opp; struct device *dev = &pdev->dev; int err = 0; diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index b0e45925505b..d06232aa0738 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c @@ -132,7 +132,7 @@ static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq, struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct busfreq_data_int *data = platform_get_drvdata(pdev); - struct opp *opp; + struct dev_pm_opp *opp; unsigned long old_freq, freq; unsigned long volt; @@ -262,7 +262,7 @@ static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this, { struct busfreq_data_int *data = container_of(this, struct busfreq_data_int, pm_notifier); - struct opp *opp; + struct dev_pm_opp *opp; unsigned long maxfreq = ULONG_MAX; unsigned long freq; unsigned long volt; @@ -316,7 +316,7 @@ unlock: static int exynos5_busfreq_int_probe(struct platform_device *pdev) { struct busfreq_data_int *data; - struct opp *opp; + struct dev_pm_opp *opp; struct device *dev = &pdev->dev; struct device_node *np; unsigned long initial_freq; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 5f1ab92107e6..c8c995325ca8 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -187,7 +187,7 @@ extern int devfreq_suspend_device(struct devfreq *devfreq); extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ -extern struct opp *devfreq_recommended_opp(struct device *dev, +extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags); extern int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq); @@ -238,7 +238,7 @@ static inline int devfreq_resume_device(struct devfreq *devfreq) return 0; } -static inline struct opp *devfreq_recommended_opp(struct device *dev, +static inline struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { return ERR_PTR(-EINVAL); diff --git a/include/linux/opp.h b/include/linux/opp.h index 2066ae5880c6..5151b0059585 100644 --- a/include/linux/opp.h +++ b/include/linux/opp.h @@ -18,27 +18,30 @@ #include #include -struct opp; +struct dev_pm_opp; struct device; -enum opp_event { +enum dev_pm_opp_event { OPP_EVENT_ADD, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, }; #if defined(CONFIG_PM_OPP) -unsigned long dev_pm_opp_get_voltage(struct opp *opp); +unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); -unsigned long dev_pm_opp_get_freq(struct opp *opp); +unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp); int dev_pm_opp_get_opp_count(struct device *dev); -struct opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, - bool available); +struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, + unsigned long freq, + bool available); -struct opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq); +struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, + unsigned long *freq); -struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq); +struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, + unsigned long *freq); int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt); @@ -49,12 +52,12 @@ int dev_pm_opp_disable(struct device *dev, unsigned long freq); struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); #else -static inline unsigned long dev_pm_opp_get_voltage(struct opp *opp) +static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) { return 0; } -static inline unsigned long dev_pm_opp_get_freq(struct opp *opp) +static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) { return 0; } @@ -64,19 +67,19 @@ static inline int dev_pm_opp_get_opp_count(struct device *dev) return 0; } -static inline struct opp *dev_pm_opp_find_freq_exact(struct device *dev, +static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { return ERR_PTR(-EINVAL); } -static inline struct opp *dev_pm_opp_find_freq_floor(struct device *dev, +static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { return ERR_PTR(-EINVAL); } -static inline struct opp *dev_pm_opp_find_freq_ceil(struct device *dev, +static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { return ERR_PTR(-EINVAL); -- cgit v1.2.3 From e4db1c7439b31993a4886b273bb9235a8eea82bf Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 19 Sep 2013 16:03:52 -0500 Subject: PM / OPP: rename header to linux/pm_opp.h Since Operating Performance Points (OPP) functions are specific to device specific power management, be specific and rename opp.h to pm_opp.h Reported-by: Randy Dunlap Signed-off-by: Nishanth Menon Signed-off-by: Rafael J. Wysocki --- Documentation/power/opp.txt | 2 +- arch/arm/mach-imx/mach-imx6q.c | 2 +- arch/arm/mach-omap2/board-omap3beagle.c | 2 +- arch/arm/mach-omap2/omap-pm.h | 2 +- arch/arm/mach-omap2/opp.c | 2 +- arch/arm/mach-omap2/pm.c | 2 +- drivers/base/power/opp.c | 2 +- drivers/cpufreq/arm_big_little.c | 2 +- drivers/cpufreq/arm_big_little_dt.c | 2 +- drivers/cpufreq/cpufreq-cpu0.c | 2 +- drivers/cpufreq/exynos5440-cpufreq.c | 2 +- drivers/cpufreq/imx6q-cpufreq.c | 2 +- drivers/cpufreq/omap-cpufreq.c | 2 +- drivers/devfreq/devfreq.c | 2 +- drivers/devfreq/exynos/exynos4_bus.c | 2 +- drivers/devfreq/exynos/exynos5_bus.c | 4 +- include/linux/devfreq.h | 2 +- include/linux/opp.h | 139 -------------------------------- include/linux/pm_opp.h | 139 ++++++++++++++++++++++++++++++++ 19 files changed, 157 insertions(+), 157 deletions(-) delete mode 100644 include/linux/opp.h create mode 100644 include/linux/pm_opp.h (limited to 'include/linux') diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index 7f67e3d2c530..b8a907dc0169 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt @@ -42,7 +42,7 @@ We can represent these as three OPPs as the following {Hz, uV} tuples: OPP library provides a set of helper functions to organize and query the OPP information. The library is located in drivers/base/power/opp.c and the header -is located in include/linux/opp.h. OPP library can be enabled by enabling +is located in include/linux/pm_opp.h. OPP library can be enabled by enabling CONFIG_PM_OPP from power management menuconfig menu. OPP library depends on CONFIG_PM as certain SoCs such as Texas Instrument's OMAP framework allows to optionally boot at a certain OPP without needing cpufreq. diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index d7ecc90e6bba..699aabe296e1 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 33969e5a149f..6432ab8d9207 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h index 67faa7b8fe92..1d777e63e05c 100644 --- a/arch/arm/mach-omap2/omap-pm.h +++ b/arch/arm/mach-omap2/omap-pm.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include /* * agent_id values for use with omap_pm_set_min_bus_tput(): diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index 7b04637b13cb..ec21e6eb03e1 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -17,7 +17,7 @@ * GNU General Public License for more details. */ #include -#include +#include #include #include "omap_device.h" diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 92901bd41490..2f569b3c3092 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 693e14a24914..fa4187418440 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 9e82a9d5df77..e010fb722c6b 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 480c0bd0468d..8d9d59108906 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index d73107894fee..242d4900de47 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index c8b3d3950f9e..d41e77769d1a 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 84e993dfb305..e4c914066601 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index f057d423020c..20190f56594f 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 03530a0a8042..2e23b12c350b 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 891becd46513..cede6f71cd63 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index d06232aa0738..52835f12ac98 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c @@ -15,10 +15,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index c8c995325ca8..7a7cc74d7f27 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -15,7 +15,7 @@ #include #include -#include +#include #define DEVFREQ_NAME_LEN 16 diff --git a/include/linux/opp.h b/include/linux/opp.h deleted file mode 100644 index 5151b0059585..000000000000 --- a/include/linux/opp.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Generic OPP Interface - * - * Copyright (C) 2009-2010 Texas Instruments Incorporated. - * Nishanth Menon - * Romit Dasgupta - * Kevin Hilman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __LINUX_OPP_H__ -#define __LINUX_OPP_H__ - -#include -#include -#include - -struct dev_pm_opp; -struct device; - -enum dev_pm_opp_event { - OPP_EVENT_ADD, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, -}; - -#if defined(CONFIG_PM_OPP) - -unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); - -unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp); - -int dev_pm_opp_get_opp_count(struct device *dev); - -struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, - unsigned long freq, - bool available); - -struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, - unsigned long *freq); - -struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, - unsigned long *freq); - -int dev_pm_opp_add(struct device *dev, unsigned long freq, - unsigned long u_volt); - -int dev_pm_opp_enable(struct device *dev, unsigned long freq); - -int dev_pm_opp_disable(struct device *dev, unsigned long freq); - -struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); -#else -static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) -{ - return 0; -} - -static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) -{ - return 0; -} - -static inline int dev_pm_opp_get_opp_count(struct device *dev) -{ - return 0; -} - -static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, - unsigned long freq, bool available) -{ - return ERR_PTR(-EINVAL); -} - -static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, - unsigned long *freq) -{ - return ERR_PTR(-EINVAL); -} - -static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, - unsigned long *freq) -{ - return ERR_PTR(-EINVAL); -} - -static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, - unsigned long u_volt) -{ - return -EINVAL; -} - -static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) -{ - return 0; -} - -static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) -{ - return 0; -} - -static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( - struct device *dev) -{ - return ERR_PTR(-EINVAL); -} -#endif /* CONFIG_PM_OPP */ - -#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) -int of_init_opp_table(struct device *dev); -#else -static inline int of_init_opp_table(struct device *dev) -{ - return -EINVAL; -} -#endif - -#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) -int dev_pm_opp_init_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table); -void dev_pm_opp_free_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table); -#else -static inline int dev_pm_opp_init_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table) -{ - return -EINVAL; -} - -static inline -void dev_pm_opp_free_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table) -{ -} -#endif /* CONFIG_CPU_FREQ */ - -#endif /* __LINUX_OPP_H__ */ diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h new file mode 100644 index 000000000000..5151b0059585 --- /dev/null +++ b/include/linux/pm_opp.h @@ -0,0 +1,139 @@ +/* + * Generic OPP Interface + * + * Copyright (C) 2009-2010 Texas Instruments Incorporated. + * Nishanth Menon + * Romit Dasgupta + * Kevin Hilman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_OPP_H__ +#define __LINUX_OPP_H__ + +#include +#include +#include + +struct dev_pm_opp; +struct device; + +enum dev_pm_opp_event { + OPP_EVENT_ADD, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, +}; + +#if defined(CONFIG_PM_OPP) + +unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); + +unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp); + +int dev_pm_opp_get_opp_count(struct device *dev); + +struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, + unsigned long freq, + bool available); + +struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, + unsigned long *freq); + +struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, + unsigned long *freq); + +int dev_pm_opp_add(struct device *dev, unsigned long freq, + unsigned long u_volt); + +int dev_pm_opp_enable(struct device *dev, unsigned long freq); + +int dev_pm_opp_disable(struct device *dev, unsigned long freq); + +struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); +#else +static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) +{ + return 0; +} + +static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) +{ + return 0; +} + +static inline int dev_pm_opp_get_opp_count(struct device *dev) +{ + return 0; +} + +static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, + unsigned long freq, bool available) +{ + return ERR_PTR(-EINVAL); +} + +static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, + unsigned long *freq) +{ + return ERR_PTR(-EINVAL); +} + +static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, + unsigned long *freq) +{ + return ERR_PTR(-EINVAL); +} + +static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, + unsigned long u_volt) +{ + return -EINVAL; +} + +static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq) +{ + return 0; +} + +static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq) +{ + return 0; +} + +static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( + struct device *dev) +{ + return ERR_PTR(-EINVAL); +} +#endif /* CONFIG_PM_OPP */ + +#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) +int of_init_opp_table(struct device *dev); +#else +static inline int of_init_opp_table(struct device *dev) +{ + return -EINVAL; +} +#endif + +#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) +int dev_pm_opp_init_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table); +void dev_pm_opp_free_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table); +#else +static inline int dev_pm_opp_init_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table) +{ + return -EINVAL; +} + +static inline +void dev_pm_opp_free_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table) +{ +} +#endif /* CONFIG_CPU_FREQ */ + +#endif /* __LINUX_OPP_H__ */ -- cgit v1.2.3 From 9c0ebcf78fde0ffa348a95a544c6d3f2dac5af65 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 25 Oct 2013 19:45:48 +0530 Subject: cpufreq: Implement light weight ->target_index() routine Currently, the prototype of cpufreq_drivers target routines is: int target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); And most of the drivers call cpufreq_frequency_table_target() to get a valid index of their frequency table which is closest to the target_freq. And they don't use target_freq and relation after that. So, it makes sense to just do this work in cpufreq core before calling cpufreq_frequency_table_target() and simply pass index instead. But this can be done only with drivers which expose their frequency table with cpufreq core. For others we need to stick with the old prototype of target() until those drivers are converted to expose frequency tables. This patch implements the new light weight prototype for target_index() routine. It looks like this: int target_index(struct cpufreq_policy *policy, unsigned int index); CPUFreq core will call cpufreq_frequency_table_target() before calling this routine and pass index to it. Because CPUFreq core now requires to call routines present in freq_table.c CONFIG_CPU_FREQ_TABLE must be enabled all the time. This also marks target() interface as deprecated. So, that new drivers avoid using it. And Documentation is updated accordingly. It also converts existing .target() to newly defined light weight .target_index() routine for many driver. Acked-by: Hans-Christian Egtvedt Acked-by: Jesper Nilsson Acked-by: Linus Walleij Acked-by: Russell King Acked-by: David S. Miller Tested-by: Andrew Lunn Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/cpu-drivers.txt | 27 ++++++++++------ Documentation/cpu-freq/governors.txt | 4 +-- arch/arm/mach-sa1100/generic.c | 20 ------------ arch/arm/mach-sa1100/generic.h | 2 -- drivers/cpufreq/acpi-cpufreq.c | 21 ++++--------- drivers/cpufreq/arm_big_little.c | 17 +++------- drivers/cpufreq/at32ap-cpufreq.c | 23 +++----------- drivers/cpufreq/blackfin-cpufreq.c | 17 +++------- drivers/cpufreq/cpufreq-cpu0.c | 17 ++-------- drivers/cpufreq/cpufreq.c | 57 +++++++++++++++++++++++++++------- drivers/cpufreq/cris-artpec3-cpufreq.c | 18 ++--------- drivers/cpufreq/cris-etraxfs-cpufreq.c | 17 ++-------- drivers/cpufreq/davinci-cpufreq.c | 16 ++-------- drivers/cpufreq/dbx500-cpufreq.c | 16 ++-------- drivers/cpufreq/e_powersaver.c | 17 ++-------- drivers/cpufreq/elanfreq.c | 34 ++------------------ drivers/cpufreq/exynos-cpufreq.c | 21 ++----------- drivers/cpufreq/exynos5440-cpufreq.c | 21 +++---------- drivers/cpufreq/ia64-acpi-cpufreq.c | 21 ++----------- drivers/cpufreq/imx6q-cpufreq.c | 17 ++-------- drivers/cpufreq/kirkwood-cpufreq.c | 19 ++---------- drivers/cpufreq/longhaul.c | 13 ++------ drivers/cpufreq/loongson2_cpufreq.c | 21 +++---------- drivers/cpufreq/maple-cpufreq.c | 16 +++------- drivers/cpufreq/omap-cpufreq.c | 31 ++---------------- drivers/cpufreq/p4-clockmod.c | 18 +++-------- drivers/cpufreq/pasemi-cpufreq.c | 12 ++----- drivers/cpufreq/pmac32-cpufreq.c | 12 ++----- drivers/cpufreq/pmac64-cpufreq.c | 17 +++------- drivers/cpufreq/powernow-k6.c | 35 +++------------------ drivers/cpufreq/powernow-k7.c | 22 +++---------- drivers/cpufreq/powernow-k8.c | 24 +++++--------- drivers/cpufreq/ppc-corenet-cpufreq.c | 15 +++------ drivers/cpufreq/ppc_cbe_cpufreq.c | 12 ++----- drivers/cpufreq/pxa2xx-cpufreq.c | 13 ++------ drivers/cpufreq/pxa3xx-cpufreq.c | 17 ++-------- drivers/cpufreq/s3c2416-cpufreq.c | 17 +++------- drivers/cpufreq/s3c64xx-cpufreq.c | 18 +++-------- drivers/cpufreq/s5pv210-cpufreq.c | 54 +++++++++----------------------- drivers/cpufreq/sa1100-cpufreq.c | 24 +++----------- drivers/cpufreq/sa1110-cpufreq.c | 26 +++------------- drivers/cpufreq/sc520_freq.c | 19 ++---------- drivers/cpufreq/sparc-us2e-cpufreq.c | 21 ++----------- drivers/cpufreq/sparc-us3-cpufreq.c | 23 ++------------ drivers/cpufreq/spear-cpufreq.c | 12 +++---- drivers/cpufreq/speedstep-centrino.c | 27 +++++----------- drivers/cpufreq/speedstep-ich.c | 24 ++++---------- drivers/cpufreq/speedstep-smi.c | 20 +++--------- drivers/cpufreq/tegra-cpufreq.c | 12 ++----- include/linux/cpufreq.h | 4 ++- 50 files changed, 242 insertions(+), 759 deletions(-) (limited to 'include/linux') diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 40282e617913..8b1a4451422e 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -23,8 +23,8 @@ Contents: 1.1 Initialization 1.2 Per-CPU Initialization 1.3 verify -1.4 target or setpolicy? -1.5 target +1.4 target/target_index or setpolicy? +1.5 target/target_index 1.6 setpolicy 2. Frequency Table Helpers @@ -56,7 +56,8 @@ cpufreq_driver.init - A pointer to the per-CPU initialization cpufreq_driver.verify - A pointer to a "verification" function. cpufreq_driver.setpolicy _or_ -cpufreq_driver.target - See below on the differences. +cpufreq_driver.target/ +target_index - See below on the differences. And optionally @@ -66,7 +67,7 @@ cpufreq_driver.resume - A pointer to a per-CPU resume function which is called with interrupts disabled and _before_ the pre-suspend frequency and/or policy is restored by a call to - ->target or ->setpolicy. + ->target/target_index or ->setpolicy. cpufreq_driver.attr - A pointer to a NULL-terminated list of "struct freq_attr" which allow to @@ -103,8 +104,8 @@ policy->governor must contain the "default policy" for this CPU. A few moments later, cpufreq_driver.verify and either cpufreq_driver.setpolicy or - cpufreq_driver.target is called with - these values. + cpufreq_driver.target/target_index is called + with these values. For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the frequency table helpers might be helpful. See the section 2 for more information @@ -133,20 +134,28 @@ range) is within policy->min and policy->max. If necessary, increase policy->max first, and only if this is no solution, decrease policy->min. -1.4 target or setpolicy? +1.4 target/target_index or setpolicy? ---------------------------- Most cpufreq drivers or even most cpu frequency scaling algorithms only allow the CPU to be set to one frequency. For these, you use the -->target call. +->target/target_index call. Some cpufreq-capable processors switch the frequency between certain limits on their own. These shall use the ->setpolicy call -1.4. target +1.4. target/target_index ------------- +The target_index call has two arguments: struct cpufreq_policy *policy, +and unsigned int index (into the exposed frequency table). + +The CPUfreq driver must set the new frequency when called here. The +actual frequency must be determined by freq_table[index].frequency. + +Deprecated: +---------- The target call has three arguments: struct cpufreq_policy *policy, unsigned int target_frequency, unsigned int relation. diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index 219970ba54b7..77ec21574fb1 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt @@ -40,7 +40,7 @@ Most cpufreq drivers (in fact, all except one, longrun) or even most cpu frequency scaling algorithms only offer the CPU to be set to one frequency. In order to offer dynamic frequency scaling, the cpufreq core must be able to tell these drivers of a "target frequency". So -these specific drivers will be transformed to offer a "->target" +these specific drivers will be transformed to offer a "->target/target_index" call instead of the existing "->setpolicy" call. For "longrun", all stays the same, though. @@ -71,7 +71,7 @@ CPU can be set to switch independently | CPU can only be set / the limits of policy->{min,max} / \ / \ - Using the ->setpolicy call, Using the ->target call, + Using the ->setpolicy call, Using the ->target/target_index call, the limits and the the frequency closest "policy" is set. to target_freq is set. It is assured that it diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index cb4b2ca3cf6b..d4ea142c4edd 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -62,26 +62,6 @@ struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = { { .frequency = CPUFREQ_TABLE_END, }, }; -/* rounds up(!) */ -unsigned int sa11x0_freq_to_ppcr(unsigned int khz) -{ - int i; - - for (i = 0; i < NR_FREQS; i++) - if (sa11x0_freq_table[i].frequency >= khz) - break; - - return i; -} - -unsigned int sa11x0_ppcr_to_freq(unsigned int idx) -{ - unsigned int freq = 0; - if (idx < NR_FREQS) - freq = sa11x0_freq_table[idx].frequency; - return freq; -} - unsigned int sa11x0_getspeed(unsigned int cpu) { if (cpu) diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index cbdfae744dc5..0d92e119b36b 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h @@ -21,9 +21,7 @@ extern void sa1110_mb_enable(void); extern void sa1110_mb_disable(void); extern struct cpufreq_frequency_table sa11x0_freq_table[]; -extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); extern unsigned int sa11x0_getspeed(unsigned int cpu); -extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx); struct flash_platform_data; struct resource; diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index a1717d7367c1..889cec0a9022 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -424,17 +424,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, } static int acpi_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int index) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); struct acpi_processor_performance *perf; struct cpufreq_freqs freqs; struct drv_cmd cmd; - unsigned int next_state = 0; /* Index into freq_table */ unsigned int next_perf_state = 0; /* Index into perf table */ int result = 0; - pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); + pr_debug("acpi_cpufreq_target %d (%d)\n", + data->freq_table[index].frequency, policy->cpu); if (unlikely(data == NULL || data->acpi_data == NULL || data->freq_table == NULL)) { @@ -442,16 +442,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, } perf = data->acpi_data; - result = cpufreq_frequency_table_target(policy, - data->freq_table, - target_freq, - relation, &next_state); - if (unlikely(result)) { - result = -ENODEV; - goto out; - } - - next_perf_state = data->freq_table[next_state].driver_data; + next_perf_state = data->freq_table[index].driver_data; if (perf->state == next_perf_state) { if (unlikely(data->resume)) { pr_debug("Called after resume, resetting to P%d\n", @@ -493,7 +484,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, cmd.mask = cpumask_of(policy->cpu); freqs.old = perf->states[perf->state].core_frequency * 1000; - freqs.new = data->freq_table[next_state].frequency; + freqs.new = data->freq_table[index].frequency; cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); drv_write(&cmd); @@ -923,7 +914,7 @@ static struct freq_attr *acpi_cpufreq_attr[] = { static struct cpufreq_driver acpi_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = acpi_cpufreq_target, + .target_index = acpi_cpufreq_target, .bios_limit = acpi_processor_get_bios_limit, .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 086f7c17ff58..163e3378fe17 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -49,28 +49,21 @@ static unsigned int bL_cpufreq_get(unsigned int cpu) /* Set clock frequency */ static int bL_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int index) { struct cpufreq_freqs freqs; - u32 cpu = policy->cpu, freq_tab_idx, cur_cluster; + u32 cpu = policy->cpu, cur_cluster; int ret = 0; cur_cluster = cpu_to_cluster(policy->cpu); freqs.old = bL_cpufreq_get(policy->cpu); - - /* Determine valid target frequency using freq_table */ - cpufreq_frequency_table_target(policy, freq_table[cur_cluster], - target_freq, relation, &freq_tab_idx); - freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency; + freqs.new = freq_table[cur_cluster][index].frequency; pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n", - __func__, cpu, cur_cluster, freqs.old, target_freq, + __func__, cpu, cur_cluster, freqs.old, freqs.new, freqs.new); - if (freqs.old == freqs.new) - return 0; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000); @@ -200,7 +193,7 @@ static struct cpufreq_driver bL_cpufreq_driver = { .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY, .verify = cpufreq_generic_frequency_table_verify, - .target = bL_cpufreq_set_target, + .target_index = bL_cpufreq_set_target, .get = bL_cpufreq_get, .init = bL_cpufreq_init, .exit = bL_cpufreq_exit, diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 7439deddd5cf..81d07527bde6 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c @@ -35,25 +35,12 @@ static unsigned int at32_get_speed(unsigned int cpu) static unsigned int ref_freq; static unsigned long loops_per_jiffy_ref; -static int at32_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) { struct cpufreq_freqs freqs; - long freq; - - /* Convert target_freq from kHz to Hz */ - freq = clk_round_rate(cpuclk, target_freq * 1000); - - /* Check if policy->min <= new_freq <= policy->max */ - if(freq < (policy->min * 1000) || freq > (policy->max * 1000)) - return -EINVAL; - - pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); freqs.old = at32_get_speed(0); - freqs.new = (freq + 500) / 1000; - freqs.flags = 0; + freqs.new = freq_table[index].frequency; if (!ref_freq) { ref_freq = freqs.old; @@ -64,13 +51,13 @@ static int at32_set_target(struct cpufreq_policy *policy, if (freqs.old < freqs.new) boot_cpu_data.loops_per_jiffy = cpufreq_scale( loops_per_jiffy_ref, ref_freq, freqs.new); - clk_set_rate(cpuclk, freq); + clk_set_rate(cpuclk, freqs.new * 1000); if (freqs.new < freqs.old) boot_cpu_data.loops_per_jiffy = cpufreq_scale( loops_per_jiffy_ref, ref_freq, freqs.new); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - pr_debug("cpufreq: set frequency %lu Hz\n", freq); + pr_debug("cpufreq: set frequency %u Hz\n", freqs.new * 1000); return 0; } @@ -139,7 +126,7 @@ static struct cpufreq_driver at32_driver = { .name = "at32ap", .init = at32_cpufreq_driver_init, .verify = cpufreq_generic_frequency_table_verify, - .target = at32_set_target, + .target_index = at32_set_target, .get = at32_get_speed, .flags = CPUFREQ_STICKY, }; diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c index 0bc9e8c2c79b..12528b28d45d 100644 --- a/drivers/cpufreq/blackfin-cpufreq.c +++ b/drivers/cpufreq/blackfin-cpufreq.c @@ -127,14 +127,11 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new) } #endif -static int bfin_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int bfin_target(struct cpufreq_policy *policy, unsigned int index) { #ifndef CONFIG_BF60x unsigned int plldiv; #endif - unsigned int index; - unsigned long cclk_hz; struct cpufreq_freqs freqs; static unsigned long lpj_ref; static unsigned int lpj_ref_freq; @@ -144,17 +141,11 @@ static int bfin_target(struct cpufreq_policy *policy, cycles_t cycles; #endif - if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq, - relation, &index)) - return -EINVAL; - - cclk_hz = bfin_freq_table[index].frequency; - freqs.old = bfin_getfreq_khz(0); - freqs.new = cclk_hz; + freqs.new = bfin_freq_table[index].frequency; pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", - cclk_hz, target_freq, freqs.old); + freqs.new, freqs.new, freqs.old); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); #ifndef CONFIG_BF60x @@ -209,7 +200,7 @@ static int __bfin_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver bfin_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = bfin_target, + .target_index = bfin_target, .get = bfin_getfreq_khz, .init = __bfin_cpu_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 33ab6504c447..4dbe7efd86e5 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -35,24 +35,14 @@ static unsigned int cpu0_get_speed(unsigned int cpu) return clk_get_rate(cpu_clk) / 1000; } -static int cpu0_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) { struct cpufreq_freqs freqs; struct dev_pm_opp *opp; unsigned long volt = 0, volt_old = 0, tol = 0; long freq_Hz, freq_exact; - unsigned int index; int ret; - ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &index); - if (ret) { - pr_err("failed to match target freqency %d: %d\n", - target_freq, ret); - return ret; - } - freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); if (freq_Hz < 0) freq_Hz = freq_table[index].frequency * 1000; @@ -60,9 +50,6 @@ static int cpu0_set_target(struct cpufreq_policy *policy, freqs.new = freq_Hz / 1000; freqs.old = clk_get_rate(cpu_clk) / 1000; - if (freqs.old == freqs.new) - return 0; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); if (!IS_ERR(cpu_reg)) { @@ -128,7 +115,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy) static struct cpufreq_driver cpu0_cpufreq_driver = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = cpu0_set_target, + .target_index = cpu0_set_target, .get = cpu0_get_speed, .init = cpu0_cpufreq_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index ec391d7f010b..87ed83a6c894 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list); static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); #endif +static inline bool has_target(void) +{ + return cpufreq_driver->target_index || cpufreq_driver->target; +} + /* * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure * all cpufreq/hotplug/workqueue/etc related lock issues. @@ -392,7 +397,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, *policy = CPUFREQ_POLICY_POWERSAVE; err = 0; } - } else if (cpufreq_driver->target) { + } else if (has_target()) { struct cpufreq_governor *t; mutex_lock(&cpufreq_governor_mutex); @@ -550,7 +555,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, ssize_t i = 0; struct cpufreq_governor *t; - if (!cpufreq_driver->target) { + if (!has_target()) { i += sprintf(buf, "performance powersave"); goto out; } @@ -835,7 +840,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, if (ret) goto err_out_kobj_put; } - if (cpufreq_driver->target) { + if (has_target()) { ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); if (ret) goto err_out_kobj_put; @@ -884,10 +889,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu, struct device *dev, bool frozen) { - int ret = 0, has_target = !!cpufreq_driver->target; + int ret = 0; unsigned long flags; - if (has_target) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); @@ -905,7 +910,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unlock_policy_rwsem_write(policy->cpu); - if (has_target) { + if (has_target()) { if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { pr_err("%s: Failed to start governor\n", __func__); @@ -1215,7 +1220,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, return -EINVAL; } - if (cpufreq_driver->target) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); @@ -1280,7 +1285,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, /* If cpu is last user of policy, free policy */ if (cpus == 1) { - if (cpufreq_driver->target) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) { @@ -1323,7 +1328,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, if (!frozen) cpufreq_policy_free(policy); } else { - if (cpufreq_driver->target) { + if (has_target()) { if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { pr_err("%s: Failed to start governor\n", @@ -1694,12 +1699,41 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", policy->cpu, target_freq, relation, old_target_freq); + /* + * This might look like a redundant call as we are checking it again + * after finding index. But it is left intentionally for cases where + * exactly same freq is called again and so we can save on few function + * calls. + */ if (target_freq == policy->cur) return 0; if (cpufreq_driver->target) retval = cpufreq_driver->target(policy, target_freq, relation); + else if (cpufreq_driver->target_index) { + struct cpufreq_frequency_table *freq_table; + int index; + freq_table = cpufreq_frequency_get_table(policy->cpu); + if (unlikely(!freq_table)) { + pr_err("%s: Unable to find freq_table\n", __func__); + goto out; + } + + retval = cpufreq_frequency_table_target(policy, freq_table, + target_freq, relation, &index); + if (unlikely(retval)) { + pr_err("%s: Unable to find matching freq\n", __func__); + goto out; + } + + if (freq_table[index].frequency == policy->cur) + retval = 0; + else + retval = cpufreq_driver->target_index(policy, index); + } + +out: return retval; } EXPORT_SYMBOL_GPL(__cpufreq_driver_target); @@ -2025,7 +2059,7 @@ int cpufreq_update_policy(unsigned int cpu) pr_debug("Driver did not initialize current freq"); policy->cur = new_policy.cur; } else { - if (policy->cur != new_policy.cur && cpufreq_driver->target) + if (policy->cur != new_policy.cur && has_target()) cpufreq_out_of_sync(cpu, policy->cur, new_policy.cur); } @@ -2103,7 +2137,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) return -ENODEV; if (!driver_data || !driver_data->verify || !driver_data->init || - ((!driver_data->setpolicy) && (!driver_data->target))) + !(driver_data->setpolicy || driver_data->target_index || + driver_data->target)) return -EINVAL; pr_debug("trying to register driver %s\n", driver_data->name); diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index 05fdc7e40257..841857cf1562 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c @@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) return clk_ctrl.pll ? 200000 : 6000; } -static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, - unsigned int state) +static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state) { struct cpufreq_freqs freqs; reg_clkgen_rw_clk_ctrl clk_ctrl; @@ -52,19 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, local_irq_enable(); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -}; - -static int cris_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, cris_freq_table, - target_freq, relation, &newstate)) - return -EINVAL; - - cris_freq_set_cpu_state(policy, newstate); return 0; } @@ -77,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver cris_freq_driver = { .get = cris_freq_get_cpu_frequency, .verify = cpufreq_generic_frequency_table_verify, - .target = cris_freq_target, + .target_index = cris_freq_target, .init = cris_freq_cpu_init, .exit = cpufreq_generic_exit, .name = "cris_freq", diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index fac2b26932dd..c58811abd961 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c @@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) return clk_ctrl.pll ? 200000 : 6000; } -static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, - unsigned int state) +static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state) { struct cpufreq_freqs freqs; reg_config_rw_clk_ctrl clk_ctrl; @@ -52,18 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, local_irq_enable(); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -}; - -static int cris_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target - (policy, cris_freq_table, target_freq, relation, &newstate)) - return -EINVAL; - - cris_freq_set_cpu_state(policy, newstate); return 0; } @@ -76,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver cris_freq_driver = { .get = cris_freq_get_cpu_frequency, .verify = cpufreq_generic_frequency_table_verify, - .target = cris_freq_target, + .target_index = cris_freq_target, .init = cris_freq_cpu_init, .exit = cpufreq_generic_exit, .name = "cris_freq", diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 972583baf9e8..1f5d8a569c77 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -66,28 +66,18 @@ static unsigned int davinci_getspeed(unsigned int cpu) return clk_get_rate(cpufreq.armclk) / 1000; } -static int davinci_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) { int ret = 0; - unsigned int idx; struct cpufreq_freqs freqs; struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; struct clk *armclk = cpufreq.armclk; freqs.old = davinci_getspeed(0); - freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; - - if (freqs.old == freqs.new) - return ret; + freqs.new = pdata->freq_table[idx].frequency; dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); - ret = cpufreq_frequency_table_target(policy, pdata->freq_table, - freqs.new, relation, &idx); - if (ret) - return -EINVAL; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); /* if moving to higher frequency, up the voltage beforehand */ @@ -148,7 +138,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver davinci_driver = { .flags = CPUFREQ_STICKY, .verify = davinci_verify_speed, - .target = davinci_target, + .target_index = davinci_target, .get = davinci_getspeed, .init = davinci_cpu_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index a60f7693c18e..238b16976be1 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c @@ -20,23 +20,13 @@ static struct cpufreq_frequency_table *freq_table; static struct clk *armss_clk; static int dbx500_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { struct cpufreq_freqs freqs; - unsigned int idx; int ret; - /* Lookup the next frequency */ - if (cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &idx)) - return -EINVAL; - freqs.old = policy->cur; - freqs.new = freq_table[idx].frequency; - - if (freqs.old == freqs.new) - return 0; + freqs.new = freq_table[index].frequency; /* pre-change notification */ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); @@ -80,7 +70,7 @@ static int dbx500_cpufreq_init(struct cpufreq_policy *policy) static struct cpufreq_driver dbx500_cpufreq_driver = { .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, .verify = cpufreq_generic_frequency_table_verify, - .target = dbx500_cpufreq_target, + .target_index = dbx500_cpufreq_target, .get = dbx500_cpufreq_getspeed, .init = dbx500_cpufreq_init, .name = "DBX500", diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 2c11ce3c67bd..b39c4ef60a7a 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -168,12 +168,9 @@ postchange: return err; } -static int eps_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int eps_target(struct cpufreq_policy *policy, unsigned int index) { struct eps_cpu_data *centaur; - unsigned int newstate = 0; unsigned int cpu = policy->cpu; unsigned int dest_state; int ret; @@ -182,16 +179,8 @@ static int eps_target(struct cpufreq_policy *policy, return -ENODEV; centaur = eps_cpu[cpu]; - if (unlikely(cpufreq_frequency_table_target(policy, - &eps_cpu[cpu]->freq_table[0], - target_freq, - relation, - &newstate))) { - return -EINVAL; - } - /* Make frequency transition */ - dest_state = centaur->freq_table[newstate].driver_data & 0xffff; + dest_state = centaur->freq_table[index].driver_data & 0xffff; ret = eps_set_state(centaur, policy, dest_state); if (ret) printk(KERN_ERR "eps: Timeout!\n"); @@ -418,7 +407,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy) static struct cpufreq_driver eps_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = eps_target, + .target_index = eps_target, .init = eps_cpu_init, .exit = eps_cpu_exit, .get = eps_get, diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index d91a645a27ae..4ab41539514f 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -105,20 +105,8 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) } -/** - * elanfreq_set_cpu_frequency: Change the CPU core frequency - * @cpu: cpu number - * @freq: frequency in kHz - * - * This function takes a frequency value and changes the CPU frequency - * according to this. Note that the frequency has to be checked by - * elanfreq_validatespeed() for correctness! - * - * There is no return value. - */ - -static void elanfreq_set_cpu_state(struct cpufreq_policy *policy, - unsigned int state) +static int elanfreq_target(struct cpufreq_policy *policy, + unsigned int state) { struct cpufreq_freqs freqs; @@ -162,25 +150,9 @@ static void elanfreq_set_cpu_state(struct cpufreq_policy *policy, local_irq_enable(); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -}; - - -static int elanfreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], - target_freq, relation, &newstate)) - return -EINVAL; - - elanfreq_set_cpu_state(policy, newstate); return 0; } - - /* * Module init and exit code */ @@ -237,7 +209,7 @@ __setup("elanfreq=", elanfreq_setup); static struct cpufreq_driver elanfreq_driver = { .get = elanfreq_get_cpu_frequency, .verify = cpufreq_generic_frequency_table_verify, - .target = elanfreq_target, + .target_index = elanfreq_target, .init = elanfreq_cpu_init, .exit = cpufreq_generic_exit, .name = "elanfreq", diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 3e4af676f43d..9982fcb82257 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -65,9 +65,6 @@ static int exynos_cpufreq_scale(unsigned int target_freq) freqs.old = policy->cur; freqs.new = target_freq; - if (freqs.new == freqs.old) - goto out; - /* * The policy max have been changed so that we cannot get proper * old_index with cpufreq_frequency_table_target(). Thus, ignore @@ -151,13 +148,9 @@ out: return ret; } -static int exynos_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int exynos_target(struct cpufreq_policy *policy, unsigned int index) { struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; - unsigned int index; - unsigned int new_freq; int ret = 0; mutex_lock(&cpufreq_lock); @@ -165,15 +158,7 @@ static int exynos_target(struct cpufreq_policy *policy, if (frequency_locked) goto out; - if (cpufreq_frequency_table_target(policy, freq_table, - target_freq, relation, &index)) { - ret = -EINVAL; - goto out; - } - - new_freq = freq_table[index].frequency; - - ret = exynos_cpufreq_scale(new_freq); + ret = exynos_cpufreq_scale(freq_table[index].frequency); out: mutex_unlock(&cpufreq_lock); @@ -247,7 +232,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver exynos_driver = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = exynos_target, + .target_index = exynos_target, .get = exynos_getspeed, .init = exynos_cpufreq_cpu_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 8ae5e2925bf1..1bf9b060d522 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -214,27 +214,17 @@ static unsigned int exynos_getspeed(unsigned int cpu) return dvfs_info->cur_frequency; } -static int exynos_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int exynos_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int index, tmp; - int ret = 0, i; + unsigned int tmp; + int i; struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; mutex_lock(&cpufreq_lock); - ret = cpufreq_frequency_table_target(policy, freq_table, - target_freq, relation, &index); - if (ret) - goto out; - freqs.old = dvfs_info->cur_frequency; freqs.new = freq_table[index].frequency; - if (freqs.old == freqs.new) - goto out; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); /* Set the target frequency in all C0_3_PSTATE register */ @@ -245,9 +235,8 @@ static int exynos_target(struct cpufreq_policy *policy, __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); } -out: mutex_unlock(&cpufreq_lock); - return ret; + return 0; } static void exynos_cpufreq_work(struct work_struct *work) @@ -325,7 +314,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver exynos_driver = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = exynos_target, + .target_index = exynos_target, .get = exynos_getspeed, .init = exynos_cpufreq_cpu_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 90c6598415fd..4695fa22406a 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -227,26 +227,11 @@ acpi_cpufreq_get ( static int acpi_cpufreq_target ( struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { - struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; - unsigned int next_state = 0; - unsigned int result = 0; - - pr_debug("acpi_cpufreq_setpolicy\n"); - - result = cpufreq_frequency_table_target(policy, - data->freq_table, target_freq, relation, &next_state); - if (result) - return (result); - - result = processor_set_freq(data, policy, next_state); - - return (result); + return processor_set_freq(acpi_io_data[policy->cpu], policy, index); } - static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -379,7 +364,7 @@ acpi_cpufreq_cpu_exit ( static struct cpufreq_driver acpi_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = acpi_cpufreq_target, + .target_index = acpi_cpufreq_target, .get = acpi_cpufreq_get, .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index be23892282e3..07af3b0de069 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -40,30 +40,17 @@ static unsigned int imx6q_get_speed(unsigned int cpu) return clk_get_rate(arm_clk) / 1000; } -static int imx6q_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) { struct cpufreq_freqs freqs; struct dev_pm_opp *opp; unsigned long freq_hz, volt, volt_old; - unsigned int index; int ret; - ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &index); - if (ret) { - dev_err(cpu_dev, "failed to match target frequency %d: %d\n", - target_freq, ret); - return ret; - } - freqs.new = freq_table[index].frequency; freq_hz = freqs.new * 1000; freqs.old = clk_get_rate(arm_clk) / 1000; - if (freqs.old == freqs.new) - return 0; - rcu_read_lock(); opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); if (IS_ERR(opp)) { @@ -159,7 +146,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy) static struct cpufreq_driver imx6q_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = imx6q_set_target, + .target_index = imx6q_set_target, .get = imx6q_get_speed, .init = imx6q_cpufreq_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index fff8653c8e9b..0ae4dd7e1f2d 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -55,8 +55,8 @@ static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) return kirkwood_freq_table[0].frequency; } -static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy, - unsigned int index) +static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, + unsigned int index) { struct cpufreq_freqs freqs; unsigned int state = kirkwood_freq_table[index].driver_data; @@ -100,19 +100,6 @@ static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy, local_irq_enable(); } cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -}; - -static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int index = 0; - - if (cpufreq_frequency_table_target(policy, kirkwood_freq_table, - target_freq, relation, &index)) - return -EINVAL; - - kirkwood_cpufreq_set_cpu_state(policy, index); return 0; } @@ -126,7 +113,7 @@ static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver kirkwood_cpufreq_driver = { .get = kirkwood_cpufreq_get_cpu_frequency, .verify = cpufreq_generic_frequency_table_verify, - .target = kirkwood_cpufreq_target, + .target_index = kirkwood_cpufreq_target, .init = kirkwood_cpufreq_cpu_init, .exit = cpufreq_generic_exit, .name = "kirkwood-cpufreq", diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 14df4974fb45..45bafddfd8ea 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -626,21 +626,12 @@ static void longhaul_setup_voltagescaling(void) static int longhaul_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int table_index) { - unsigned int table_index = 0; unsigned int i; unsigned int dir = 0; u8 vid, current_vid; - if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, - relation, &table_index)) - return -EINVAL; - - /* Don't set same frequency again */ - if (longhaul_index == table_index) - return 0; - if (!can_scale_voltage) longhaul_setstate(policy, table_index); else { @@ -919,7 +910,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver longhaul_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = longhaul_target, + .target_index = longhaul_target, .get = longhaul_get, .init = longhaul_cpu_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index 2c8ec8e06449..41a8e2cdf940 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c @@ -53,11 +53,9 @@ static unsigned int loongson2_cpufreq_get(unsigned int cpu) * Here we notify other drivers of the proposed change and the final change. */ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { unsigned int cpu = policy->cpu; - unsigned int newstate = 0; cpumask_t cpus_allowed; struct cpufreq_freqs freqs; unsigned int freq; @@ -65,26 +63,17 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, cpus_allowed = current->cpus_allowed; set_cpus_allowed_ptr(current, cpumask_of(cpu)); - if (cpufreq_frequency_table_target - (policy, &loongson2_clockmod_table[0], target_freq, relation, - &newstate)) - return -EINVAL; - freq = ((cpu_clock_freq / 1000) * - loongson2_clockmod_table[newstate].driver_data) / 8; - if (freq < policy->min || freq > policy->max) - return -EINVAL; + loongson2_clockmod_table[index].driver_data) / 8; - pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); + pr_debug("cpufreq: requested frequency %u Hz\n", + loongson2_clockmod_table[index].frequency * 1000); freqs.old = loongson2_cpufreq_get(cpu); freqs.new = freq; freqs.flags = 0; - if (freqs.new == freqs.old) - return 0; - /* notifiers */ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); @@ -145,7 +134,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = { .name = "loongson2", .init = loongson2_cpufreq_cpu_init, .verify = cpufreq_generic_frequency_table_verify, - .target = loongson2_cpufreq_target, + .target_index = loongson2_cpufreq_target, .get = loongson2_cpufreq_get, .exit = loongson2_cpufreq_exit, .attr = cpufreq_generic_attr, diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index eb1e1766baed..4e2da0874bfb 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c @@ -131,26 +131,18 @@ static int maple_scom_query_freq(void) */ static int maple_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int index) { - unsigned int newstate = 0; struct cpufreq_freqs freqs; int rc; - if (cpufreq_frequency_table_target(policy, maple_cpu_freqs, - target_freq, relation, &newstate)) - return -EINVAL; - - if (maple_pmode_cur == newstate) - return 0; - mutex_lock(&maple_switch_mutex); freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency; - freqs.new = maple_cpu_freqs[newstate].frequency; + freqs.new = maple_cpu_freqs[index].frequency; cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - rc = maple_scom_switch_freq(newstate); + rc = maple_scom_switch_freq(index); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); mutex_unlock(&maple_switch_mutex); @@ -173,7 +165,7 @@ static struct cpufreq_driver maple_cpufreq_driver = { .flags = CPUFREQ_CONST_LOOPS, .init = maple_cpufreq_cpu_init, .verify = cpufreq_generic_frequency_table_verify, - .target = maple_cpufreq_target, + .target_index = maple_cpufreq_target, .get = maple_cpufreq_get_speed, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index ac552d090463..b5512712298f 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -51,40 +51,15 @@ static unsigned int omap_getspeed(unsigned int cpu) return rate; } -static int omap_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int omap_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int i; int r, ret = 0; struct cpufreq_freqs freqs; struct dev_pm_opp *opp; unsigned long freq, volt = 0, volt_old = 0, tol = 0; - if (!freq_table) { - dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__, - policy->cpu); - return -EINVAL; - } - - ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &i); - if (ret) { - dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n", - __func__, policy->cpu, target_freq, ret); - return ret; - } - freqs.new = freq_table[i].frequency; - if (!freqs.new) { - dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__, - policy->cpu, target_freq); - return -EINVAL; - } - freqs.old = omap_getspeed(policy->cpu); - - if (freqs.old == freqs.new && policy->cur == freqs.new) - return ret; + freqs.new = freq_table[index].frequency; freq = freqs.new * 1000; ret = clk_round_rate(mpu_clk, freq); @@ -200,7 +175,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy) static struct cpufreq_driver omap_driver = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = omap_target, + .target_index = omap_target, .get = omap_getspeed, .init = omap_cpu_init, .exit = omap_cpu_exit, diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 6164c1cca504..3c23053afdfd 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -105,23 +105,13 @@ static struct cpufreq_frequency_table p4clockmod_table[] = { }; -static int cpufreq_p4_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int cpufreq_p4_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int newstate = DC_RESV; struct cpufreq_freqs freqs; int i; - if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], - target_freq, relation, &newstate)) - return -EINVAL; - freqs.old = cpufreq_p4_get(policy->cpu); - freqs.new = stock_freq * p4clockmod_table[newstate].driver_data / 8; - - if (freqs.new == freqs.old) - return 0; + freqs.new = stock_freq * p4clockmod_table[index].driver_data / 8; /* notifiers */ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); @@ -131,7 +121,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, * Developer's Manual, Volume 3 */ for_each_cpu(i, policy->cpus) - cpufreq_p4_setdc(i, p4clockmod_table[newstate].driver_data); + cpufreq_p4_setdc(i, p4clockmod_table[index].driver_data); /* notifiers */ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); @@ -255,7 +245,7 @@ static unsigned int cpufreq_p4_get(unsigned int cpu) static struct cpufreq_driver p4clockmod_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = cpufreq_p4_target, + .target_index = cpufreq_p4_target, .init = cpufreq_p4_cpu_init, .exit = cpufreq_generic_exit, .get = cpufreq_p4_get, diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 1cca332728c3..17424ddc7f67 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -240,19 +240,11 @@ static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy) } static int pas_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int pas_astate_new) { struct cpufreq_freqs freqs; - int pas_astate_new; int i; - cpufreq_frequency_table_target(policy, - pas_freqs, - target_freq, - relation, - &pas_astate_new); - freqs.old = policy->cur; freqs.new = pas_freqs[pas_astate_new].frequency; @@ -282,7 +274,7 @@ static struct cpufreq_driver pas_cpufreq_driver = { .init = pas_cpufreq_cpu_init, .exit = pas_cpufreq_cpu_exit, .verify = cpufreq_generic_frequency_table_verify, - .target = pas_cpufreq_target, + .target_index = pas_cpufreq_target, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 6eac1e230078..05f705e1b7a2 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -374,17 +374,11 @@ static unsigned int pmac_cpufreq_get_speed(unsigned int cpu) } static int pmac_cpufreq_target( struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { - unsigned int newstate = 0; int rc; - if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, - target_freq, relation, &newstate)) - return -EINVAL; - - rc = do_set_cpu_speed(policy, newstate, 1); + rc = do_set_cpu_speed(policy, index, 1); ppc_proc_freq = cur_freq * 1000ul; return rc; @@ -453,7 +447,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy) static struct cpufreq_driver pmac_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = pmac_cpufreq_target, + .target_index = pmac_cpufreq_target, .get = pmac_cpufreq_get_speed, .init = pmac_cpufreq_cpu_init, .suspend = pmac_cpufreq_suspend, diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 5261b92d768b..234b598ce416 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -312,27 +312,18 @@ static int g5_pfunc_query_freq(void) * Common interface to the cpufreq core */ -static int g5_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int g5_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int newstate = 0; struct cpufreq_freqs freqs; int rc; - if (cpufreq_frequency_table_target(policy, g5_cpu_freqs, - target_freq, relation, &newstate)) - return -EINVAL; - - if (g5_pmode_cur == newstate) - return 0; - mutex_lock(&g5_switch_mutex); freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; - freqs.new = g5_cpu_freqs[newstate].frequency; + freqs.new = g5_cpu_freqs[index].frequency; cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - rc = g5_switch_freq(newstate); + rc = g5_switch_freq(index); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); mutex_unlock(&g5_switch_mutex); @@ -355,7 +346,7 @@ static struct cpufreq_driver g5_cpufreq_driver = { .flags = CPUFREQ_CONST_LOOPS, .init = g5_cpufreq_cpu_init, .verify = cpufreq_generic_frequency_table_verify, - .target = g5_cpufreq_target, + .target_index = g5_cpufreq_target, .get = g5_cpufreq_get_speed, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index eda17024a34a..643e7952cad3 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -63,12 +63,12 @@ static int powernow_k6_get_cpu_multiplier(void) /** - * powernow_k6_set_state - set the PowerNow! multiplier + * powernow_k6_target - set the PowerNow! multiplier * @best_i: clock_ratio[best_i] is the target multiplier * * Tries to change the PowerNow! multiplier */ -static void powernow_k6_set_state(struct cpufreq_policy *policy, +static int powernow_k6_target(struct cpufreq_policy *policy, unsigned int best_i) { unsigned long outvalue = 0, invalue = 0; @@ -77,7 +77,7 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy, if (clock_ratio[best_i].driver_data > max_multiplier) { printk(KERN_ERR PFX "invalid target frequency\n"); - return; + return -EINVAL; } freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); @@ -100,31 +100,6 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy, cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - return; -} - - -/** - * powernow_k6_setpolicy - sets a new CPUFreq policy - * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) - * - * sets a new CPUFreq policy - */ -static int powernow_k6_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, &clock_ratio[0], - target_freq, relation, &newstate)) - return -EINVAL; - - powernow_k6_set_state(policy, newstate); - return 0; } @@ -161,7 +136,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) unsigned int i; for (i = 0; i < 8; i++) { if (i == max_multiplier) - powernow_k6_set_state(policy, i); + powernow_k6_target(policy, i); } cpufreq_frequency_table_put_attr(policy->cpu); return 0; @@ -176,7 +151,7 @@ static unsigned int powernow_k6_get(unsigned int cpu) static struct cpufreq_driver powernow_k6_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = powernow_k6_target, + .target_index = powernow_k6_target, .init = powernow_k6_cpu_init, .exit = powernow_k6_cpu_exit, .get = powernow_k6_get, diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 44d345bad6fb..946708a1d745 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -248,7 +248,7 @@ static void change_VID(int vid) } -static void change_speed(struct cpufreq_policy *policy, unsigned int index) +static int powernow_target(struct cpufreq_policy *policy, unsigned int index) { u8 fid, vid; struct cpufreq_freqs freqs; @@ -291,6 +291,8 @@ static void change_speed(struct cpufreq_policy *policy, unsigned int index) local_irq_enable(); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); + + return 0; } @@ -533,22 +535,6 @@ static int powernow_decode_bios(int maxfid, int startvid) } -static int powernow_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate; - - if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, - relation, &newstate)) - return -EINVAL; - - change_speed(policy, newstate); - - return 0; -} - - /* * We use the fact that the bus frequency is somehow * a multiple of 100000/3 khz, then we compute sgtc according @@ -694,7 +680,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy) static struct cpufreq_driver powernow_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = powernow_target, + .target_index = powernow_target, .get = powernow_get, #ifdef CONFIG_X86_POWERNOW_K7_ACPI .bios_limit = acpi_processor_get_bios_limit, diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 298beb742ebb..62a1ce47d3df 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -977,20 +977,17 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, struct powernowk8_target_arg { struct cpufreq_policy *pol; - unsigned targfreq; - unsigned relation; + unsigned newstate; }; static long powernowk8_target_fn(void *arg) { struct powernowk8_target_arg *pta = arg; struct cpufreq_policy *pol = pta->pol; - unsigned targfreq = pta->targfreq; - unsigned relation = pta->relation; + unsigned newstate = pta->newstate; struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); u32 checkfid; u32 checkvid; - unsigned int newstate; int ret; if (!data) @@ -1004,8 +1001,9 @@ static long powernowk8_target_fn(void *arg) return -EIO; } - pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", - pol->cpu, targfreq, pol->min, pol->max, relation); + pr_debug("targ: cpu %d, %d kHz, min %d, max %d\n", + pol->cpu, data->powernow_table[newstate].frequency, pol->min, + pol->max); if (query_current_values_with_pending_wait(data)) return -EIO; @@ -1021,10 +1019,6 @@ static long powernowk8_target_fn(void *arg) checkvid, data->currvid); } - if (cpufreq_frequency_table_target(pol, data->powernow_table, - targfreq, relation, &newstate)) - return -EIO; - mutex_lock(&fidvid_mutex); powernow_k8_acpi_pst_values(data, newstate); @@ -1044,11 +1038,9 @@ static long powernowk8_target_fn(void *arg) } /* Driver entry point to switch to the target frequency */ -static int powernowk8_target(struct cpufreq_policy *pol, - unsigned targfreq, unsigned relation) +static int powernowk8_target(struct cpufreq_policy *pol, unsigned index) { - struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, - .relation = relation }; + struct powernowk8_target_arg pta = { .pol = pol, .newstate = index }; return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); } @@ -1213,7 +1205,7 @@ out: static struct cpufreq_driver cpufreq_amd64_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = powernowk8_target, + .target_index = powernowk8_target, .bios_limit = acpi_processor_get_bios_limit, .init = powernowk8_cpu_init, .exit = powernowk8_cpu_exit, diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index a0f562ca292d..79d8e9c46b6d 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -251,27 +251,20 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) } static int corenet_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int index) { struct cpufreq_freqs freqs; - unsigned int new; struct clk *parent; int ret; struct cpu_data *data = per_cpu(cpu_data, policy->cpu); - cpufreq_frequency_table_target(policy, data->table, - target_freq, relation, &new); - - if (policy->cur == data->table[new].frequency) - return 0; - freqs.old = policy->cur; - freqs.new = data->table[new].frequency; + freqs.new = data->table[index].frequency; mutex_lock(&cpufreq_lock); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - parent = of_clk_get(data->parent, data->table[new].driver_data); + parent = of_clk_get(data->parent, data->table[index].driver_data); ret = clk_set_parent(data->clk, parent); if (ret) freqs.new = freqs.old; @@ -288,7 +281,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = { .init = corenet_cpufreq_cpu_init, .exit = __exit_p(corenet_cpufreq_cpu_exit), .verify = cpufreq_generic_frequency_table_verify, - .target = corenet_cpufreq_target, + .target_index = corenet_cpufreq_target, .get = corenet_cpufreq_get_speed, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 38540d1f5939..52f707d5f458 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -129,18 +129,10 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) } static int cbe_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int cbe_pmode_new) { int rc; struct cpufreq_freqs freqs; - unsigned int cbe_pmode_new; - - cpufreq_frequency_table_target(policy, - cbe_freqs, - target_freq, - relation, - &cbe_pmode_new); freqs.old = policy->cur; freqs.new = cbe_freqs[cbe_pmode_new].frequency; @@ -164,7 +156,7 @@ static int cbe_cpufreq_target(struct cpufreq_policy *policy, static struct cpufreq_driver cbe_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = cbe_cpufreq_target, + .target_index = cbe_cpufreq_target, .init = cbe_cpufreq_cpu_init, .exit = cpufreq_generic_exit, .name = "cbe-cpufreq", diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 29aca574317b..183bc13f13e5 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -267,14 +267,11 @@ static unsigned int pxa_cpufreq_get(unsigned int cpu) return get_clk_frequency_khz(0); } -static int pxa_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx) { struct cpufreq_frequency_table *pxa_freqs_table; pxa_freqs_t *pxa_freq_settings; struct cpufreq_freqs freqs; - unsigned int idx; unsigned long flags; unsigned int new_freq_cpu, new_freq_mem; unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; @@ -283,12 +280,6 @@ static int pxa_set_target(struct cpufreq_policy *policy, /* Get the current policy */ find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); - /* Lookup the next frequency */ - if (cpufreq_frequency_table_target(policy, pxa_freqs_table, - target_freq, relation, &idx)) { - return -EINVAL; - } - new_freq_cpu = pxa_freq_settings[idx].khz; new_freq_mem = pxa_freq_settings[idx].membus; freqs.old = policy->cur; @@ -448,7 +439,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) static struct cpufreq_driver pxa_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = pxa_set_target, + .target_index = pxa_set_target, .init = pxa_cpufreq_init, .exit = cpufreq_generic_exit, .get = pxa_cpufreq_get, diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 47fbee49d6e5..132e37d578c2 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -155,24 +155,16 @@ static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) return pxa3xx_get_clk_frequency_khz(0); } -static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index) { struct pxa3xx_freq_info *next; struct cpufreq_freqs freqs; unsigned long flags; - int idx; if (policy->cpu != 0) return -EINVAL; - /* Lookup the next frequency */ - if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table, - target_freq, relation, &idx)) - return -EINVAL; - - next = &pxa3xx_freqs[idx]; + next = &pxa3xx_freqs[index]; freqs.old = policy->cur; freqs.new = next->cpufreq_mhz * 1000; @@ -181,9 +173,6 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, freqs.old / 1000, freqs.new / 1000, (freqs.old == freqs.new) ? " (skipped)" : ""); - if (freqs.old == target_freq) - return 0; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); local_irq_save(flags); @@ -225,7 +214,7 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) static struct cpufreq_driver pxa3xx_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = pxa3xx_cpufreq_set, + .target_index = pxa3xx_cpufreq_set, .init = pxa3xx_cpufreq_init, .exit = cpufreq_generic_exit, .get = pxa3xx_cpufreq_get, diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 26a35d137157..4188accd34ab 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c @@ -217,24 +217,15 @@ static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx) } static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; struct cpufreq_freqs freqs; int idx, ret, to_dvs = 0; - unsigned int i; mutex_lock(&cpufreq_lock); - pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation); - - ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table, - target_freq, relation, &i); - if (ret != 0) - goto out; - - idx = s3c_freq->freq_table[i].driver_data; + idx = s3c_freq->freq_table[index].driver_data; if (idx == SOURCE_HCLK) to_dvs = 1; @@ -256,7 +247,7 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, */ freqs.new = (s3c_freq->is_dvs && !to_dvs) ? clk_get_rate(s3c_freq->hclk) / 1000 - : s3c_freq->freq_table[i].frequency; + : s3c_freq->freq_table[index].frequency; pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); @@ -505,7 +496,7 @@ err_hclk: static struct cpufreq_driver s3c2416_cpufreq_driver = { .flags = 0, .verify = cpufreq_generic_frequency_table_verify, - .target = s3c2416_cpufreq_set_target, + .target_index = s3c2416_cpufreq_set_target, .get = s3c2416_cpufreq_get_speed, .init = s3c2416_cpufreq_driver_init, .name = "s3c2416", diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 461617332033..8bdcf32a4418 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c @@ -63,26 +63,16 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) } static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int index) { int ret; - unsigned int i; struct cpufreq_freqs freqs; struct s3c64xx_dvfs *dvfs; - ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table, - target_freq, relation, &i); - if (ret != 0) - return ret; - freqs.old = clk_get_rate(armclk) / 1000; - freqs.new = s3c64xx_freq_table[i].frequency; + freqs.new = s3c64xx_freq_table[index].frequency; freqs.flags = 0; - dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data]; - - if (freqs.old == freqs.new) - return 0; + dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new); @@ -254,7 +244,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) static struct cpufreq_driver s3c64xx_cpufreq_driver = { .flags = 0, .verify = cpufreq_generic_frequency_table_verify, - .target = s3c64xx_cpufreq_set_target, + .target_index = s3c64xx_cpufreq_set_target, .get = s3c64xx_cpufreq_get_speed, .init = s3c64xx_cpufreq_driver_init, .name = "s3c", diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 600b4f472e28..5978b94e0340 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -36,16 +36,7 @@ static DEFINE_MUTEX(set_freq_lock); /* Use 800MHz when entering sleep mode */ #define SLEEP_FREQ (800 * 1000) -/* - * relation has an additional symantics other than the standard of cpufreq - * DISALBE_FURTHER_CPUFREQ: disable further access to target - * ENABLE_FURTUER_CPUFREQ: enable access to target - */ -enum cpufreq_access { - DISABLE_FURTHER_CPUFREQ = 0x10, - ENABLE_FURTHER_CPUFREQ = 0x20, -}; - +/* Tracks if cpu freqency can be updated anymore */ static bool no_cpufreq_access; /* @@ -182,12 +173,10 @@ static unsigned int s5pv210_getspeed(unsigned int cpu) return clk_get_rate(cpu_clk) / 1000; } -static int s5pv210_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) { unsigned long reg; - unsigned int index, priv_index; + unsigned int priv_index; unsigned int pll_changing = 0; unsigned int bus_speed_changing = 0; int arm_volt, int_volt; @@ -195,9 +184,6 @@ static int s5pv210_target(struct cpufreq_policy *policy, mutex_lock(&set_freq_lock); - if (relation & ENABLE_FURTHER_CPUFREQ) - no_cpufreq_access = false; - if (no_cpufreq_access) { #ifdef CONFIG_PM_VERBOSE pr_err("%s:%d denied access to %s as it is disabled" @@ -207,27 +193,13 @@ static int s5pv210_target(struct cpufreq_policy *policy, goto exit; } - if (relation & DISABLE_FURTHER_CPUFREQ) - no_cpufreq_access = true; - - relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ); - freqs.old = s5pv210_getspeed(0); - - if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, - target_freq, relation, &index)) { - ret = -EINVAL; - goto exit; - } - freqs.new = s5pv210_freq_table[index].frequency; - if (freqs.new == freqs.old) - goto exit; - /* Finding current running level index */ if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, - freqs.old, relation, &priv_index)) { + freqs.old, CPUFREQ_RELATION_H, + &priv_index)) { ret = -EINVAL; goto exit; } @@ -559,16 +531,18 @@ static int s5pv210_cpufreq_notifier_event(struct notifier_block *this, switch (event) { case PM_SUSPEND_PREPARE: - ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - DISABLE_FURTHER_CPUFREQ); + ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); if (ret < 0) return NOTIFY_BAD; + /* Disable updation of cpu frequency */ + no_cpufreq_access = true; return NOTIFY_OK; case PM_POST_RESTORE: case PM_POST_SUSPEND: - cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - ENABLE_FURTHER_CPUFREQ); + /* Enable updation of cpu frequency */ + no_cpufreq_access = false; + cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); return NOTIFY_OK; } @@ -581,18 +555,18 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this, { int ret; - ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - DISABLE_FURTHER_CPUFREQ); + ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); if (ret < 0) return NOTIFY_BAD; + no_cpufreq_access = true; return NOTIFY_DONE; } static struct cpufreq_driver s5pv210_driver = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = s5pv210_target, + .target_index = s5pv210_target, .get = s5pv210_getspeed, .init = s5pv210_cpu_init, .name = "s5pv210", diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c index b282cea47e62..b0da1fe40b1d 100644 --- a/drivers/cpufreq/sa1100-cpufreq.c +++ b/drivers/cpufreq/sa1100-cpufreq.c @@ -177,36 +177,20 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) } } -static int sa1100_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int sa1100_target(struct cpufreq_policy *policy, unsigned int ppcr) { unsigned int cur = sa11x0_getspeed(0); - unsigned int new_ppcr; struct cpufreq_freqs freqs; - new_ppcr = sa11x0_freq_to_ppcr(target_freq); - switch (relation) { - case CPUFREQ_RELATION_L: - if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) - new_ppcr--; - break; - case CPUFREQ_RELATION_H: - if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && - (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) - new_ppcr--; - break; - } - freqs.old = cur; - freqs.new = sa11x0_ppcr_to_freq(new_ppcr); + freqs.new = sa11x0_freq_table[ppcr].frequency; cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); if (freqs.new > cur) sa1100_update_dram_timings(cur, freqs.new); - PPCR = new_ppcr; + PPCR = ppcr; if (freqs.new < cur) sa1100_update_dram_timings(cur, freqs.new); @@ -224,7 +208,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver sa1100_driver __refdata = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = sa1100_target, + .target_index = sa1100_target, .get = sa11x0_getspeed, .init = sa1100_cpu_init, .name = "sa1100", diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c index bca04c0b4a73..55b1818c3e49 100644 --- a/drivers/cpufreq/sa1110-cpufreq.c +++ b/drivers/cpufreq/sa1110-cpufreq.c @@ -229,34 +229,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) /* * Ok, set the CPU frequency. */ -static int sa1110_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr) { struct sdram_params *sdram = &sdram_params; struct cpufreq_freqs freqs; struct sdram_info sd; unsigned long flags; - unsigned int ppcr, unused; - - switch (relation) { - case CPUFREQ_RELATION_L: - ppcr = sa11x0_freq_to_ppcr(target_freq); - if (sa11x0_ppcr_to_freq(ppcr) > policy->max) - ppcr--; - break; - case CPUFREQ_RELATION_H: - ppcr = sa11x0_freq_to_ppcr(target_freq); - if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) && - (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min)) - ppcr--; - break; - default: - return -EINVAL; - } + unsigned int unused; freqs.old = sa11x0_getspeed(0); - freqs.new = sa11x0_ppcr_to_freq(ppcr); + freqs.new = sa11x0_freq_table[ppcr].frequency; sdram_calculate_timing(&sd, freqs.new, sdram); @@ -340,7 +322,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver sa1110_driver __refdata = { .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = sa1110_target, + .target_index = sa1110_target, .get = sa11x0_getspeed, .init = sa1110_cpu_init, .name = "sa1110", diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 9047ab1ca014..6c86452e1737 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -53,8 +53,7 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) } } -static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy, - unsigned int state) +static int sc520_freq_target(struct cpufreq_policy *policy, unsigned int state) { struct cpufreq_freqs freqs; @@ -76,24 +75,10 @@ static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy, local_irq_enable(); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -}; - -static int sc520_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, sc520_freq_table, - target_freq, relation, &newstate)) - return -EINVAL; - - sc520_freq_set_cpu_state(policy, newstate); return 0; } - /* * Module init and exit code */ @@ -117,7 +102,7 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver sc520_freq_driver = { .get = sc520_freq_get_cpu_frequency, .verify = cpufreq_generic_frequency_table_verify, - .target = sc520_freq_target, + .target_index = sc520_freq_target, .init = sc520_freq_cpu_init, .exit = cpufreq_generic_exit, .name = "sc520_freq", diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 291688c1da9a..3bf5b8f03661 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -245,8 +245,7 @@ static unsigned int us2e_freq_get(unsigned int cpu) return clock_tick / estar_to_divisor(estar); } -static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy, - unsigned int index) +static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index) { unsigned int cpu = policy->cpu; unsigned long new_bits, new_freq; @@ -277,20 +276,6 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy, cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); set_cpus_allowed_ptr(current, &cpus_allowed); -} - -static int us2e_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int new_index = 0; - - if (cpufreq_frequency_table_target(policy, - &us2e_freq_table[policy->cpu].table[0], - target_freq, relation, &new_index)) - return -EINVAL; - - us2e_set_cpu_divider_index(policy, new_index); return 0; } @@ -325,7 +310,7 @@ static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) { if (cpufreq_us2e_driver) { cpufreq_frequency_table_put_attr(policy->cpu); - us2e_set_cpu_divider_index(policy, 0); + us2e_freq_target(policy, 0); } return 0; @@ -358,7 +343,7 @@ static int __init us2e_freq_init(void) driver->init = us2e_freq_cpu_init; driver->verify = cpufreq_generic_frequency_table_verify; - driver->target = us2e_freq_target; + driver->target_index = us2e_freq_target; driver->get = us2e_freq_get; driver->exit = us2e_freq_cpu_exit; strcpy(driver->name, "UltraSPARC-IIe"); diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 9b3dbd31362e..2e54d55915df 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -93,8 +93,7 @@ static unsigned int us3_freq_get(unsigned int cpu) return ret; } -static void us3_set_cpu_divider_index(struct cpufreq_policy *policy, - unsigned int index) +static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index) { unsigned int cpu = policy->cpu; unsigned long new_bits, new_freq, reg; @@ -136,22 +135,6 @@ static void us3_set_cpu_divider_index(struct cpufreq_policy *policy, cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); set_cpus_allowed_ptr(current, &cpus_allowed); -} - -static int us3_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int new_index = 0; - - if (cpufreq_frequency_table_target(policy, - &us3_freq_table[policy->cpu].table[0], - target_freq, - relation, - &new_index)) - return -EINVAL; - - us3_set_cpu_divider_index(policy, new_index); return 0; } @@ -182,7 +165,7 @@ static int us3_freq_cpu_exit(struct cpufreq_policy *policy) { if (cpufreq_us3_driver) { cpufreq_frequency_table_put_attr(policy->cpu); - us3_set_cpu_divider_index(policy, 0); + us3_freq_target(policy, 0); } return 0; @@ -219,7 +202,7 @@ static int __init us3_freq_init(void) driver->init = us3_freq_cpu_init; driver->verify = cpufreq_generic_frequency_table_verify; - driver->target = us3_freq_target; + driver->target_index = us3_freq_target; driver->get = us3_freq_get; driver->exit = us3_freq_cpu_exit; strcpy(driver->name, "UltraSPARC-III"); diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 8841366a2068..11a65be3fd76 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -105,20 +105,16 @@ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq) } static int spear_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) + unsigned int index) { struct cpufreq_freqs freqs; long newfreq; struct clk *srcclk; - int index, ret, mult = 1; - - if (cpufreq_frequency_table_target(policy, spear_cpufreq.freq_tbl, - target_freq, relation, &index)) - return -EINVAL; + int ret, mult = 1; freqs.old = spear_cpufreq_get(0); - newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000; + if (of_machine_is_compatible("st,spear1340")) { /* * SPEAr1340 is special in the sense that due to the possibility @@ -179,7 +175,7 @@ static struct cpufreq_driver spear_cpufreq_driver = { .name = "cpufreq-spear", .flags = CPUFREQ_STICKY, .verify = cpufreq_generic_frequency_table_verify, - .target = spear_cpufreq_target, + .target_index = spear_cpufreq_target, .get = spear_cpufreq_get, .init = spear_cpufreq_init, .exit = cpufreq_generic_exit, diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 25e45f89acac..c51ec8c0e3a8 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -416,21 +416,17 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) /** * centrino_setpolicy - set a new CPUFreq policy * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) + * @index: index of target frequency * * Sets a new CPUFreq policy. */ -static int centrino_target (struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int centrino_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int newstate = 0; unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; struct cpufreq_freqs freqs; int retval = 0; unsigned int j, first_cpu, tmp; + struct cpufreq_frequency_table *op_points; cpumask_var_t covered_cpus; if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) @@ -441,16 +437,8 @@ static int centrino_target (struct cpufreq_policy *policy, goto out; } - if (unlikely(cpufreq_frequency_table_target(policy, - per_cpu(centrino_model, cpu)->op_points, - target_freq, - relation, - &newstate))) { - retval = -EINVAL; - goto out; - } - first_cpu = 1; + op_points = &per_cpu(centrino_model, cpu)->op_points[index]; for_each_cpu(j, policy->cpus) { int good_cpu; @@ -474,7 +462,7 @@ static int centrino_target (struct cpufreq_policy *policy, break; } - msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data; + msr = op_points->driver_data; if (first_cpu) { rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); @@ -489,7 +477,8 @@ static int centrino_target (struct cpufreq_policy *policy, freqs.new = extract_clock(msr, cpu, 0); pr_debug("target=%dkHz old=%d new=%d msr=%04x\n", - target_freq, freqs.old, freqs.new, msr); + op_points->frequency, freqs.old, freqs.new, + msr); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); @@ -540,7 +529,7 @@ static struct cpufreq_driver centrino_driver = { .init = centrino_cpu_init, .exit = centrino_cpu_exit, .verify = cpufreq_generic_frequency_table_verify, - .target = centrino_target, + .target_index = centrino_target, .get = get_cur_freq, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 1a8b01bd0fec..707721ebb853 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -251,36 +251,24 @@ static unsigned int speedstep_get(unsigned int cpu) /** * speedstep_target - set a new CPUFreq policy * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) + * @index: index of target frequency * * Sets a new CPUFreq policy. */ -static int speedstep_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int speedstep_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int newstate = 0, policy_cpu; + unsigned int policy_cpu; struct cpufreq_freqs freqs; - if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], - target_freq, relation, &newstate)) - return -EINVAL; - policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); freqs.old = speedstep_get(policy_cpu); - freqs.new = speedstep_freqs[newstate].frequency; + freqs.new = speedstep_freqs[index].frequency; pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new); - /* no transition necessary */ - if (freqs.old == freqs.new) - return 0; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate, + smp_call_function_single(policy_cpu, _speedstep_set_state, &index, true); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); @@ -330,7 +318,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver speedstep_driver = { .name = "speedstep-ich", .verify = cpufreq_generic_frequency_table_verify, - .target = speedstep_target, + .target_index = speedstep_target, .init = speedstep_cpu_init, .exit = cpufreq_generic_exit, .get = speedstep_get, diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index a02b649c9647..19446e479ccc 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -235,29 +235,19 @@ static void speedstep_set_state(unsigned int state) /** * speedstep_target - set a new CPUFreq policy * @policy: new policy - * @target_freq: new freq - * @relation: + * @index: index of new freq * * Sets a new CPUFreq policy/freq. */ -static int speedstep_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) +static int speedstep_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int newstate = 0; struct cpufreq_freqs freqs; - if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], - target_freq, relation, &newstate)) - return -EINVAL; - freqs.old = speedstep_freqs[speedstep_get_state()].frequency; - freqs.new = speedstep_freqs[newstate].frequency; - - if (freqs.old == freqs.new) - return 0; + freqs.new = speedstep_freqs[index].frequency; cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - speedstep_set_state(newstate); + speedstep_set_state(index); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); return 0; @@ -327,7 +317,7 @@ static int speedstep_resume(struct cpufreq_policy *policy) static struct cpufreq_driver speedstep_driver = { .name = "speedstep-smi", .verify = cpufreq_generic_frequency_table_verify, - .target = speedstep_target, + .target_index = speedstep_target, .init = speedstep_cpu_init, .exit = cpufreq_generic_exit, .get = speedstep_get, diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index 32483ef63d53..bd7d89c013a5 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c @@ -150,11 +150,8 @@ static unsigned long tegra_cpu_highest_speed(void) return rate; } -static int tegra_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int tegra_target(struct cpufreq_policy *policy, unsigned int index) { - unsigned int idx; unsigned int freq; int ret = 0; @@ -165,10 +162,7 @@ static int tegra_target(struct cpufreq_policy *policy, goto out; } - cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &idx); - - freq = freq_table[idx].frequency; + freq = freq_table[index].frequency; target_cpu_speed[policy->cpu] = freq; @@ -238,7 +232,7 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy) static struct cpufreq_driver tegra_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, - .target = tegra_target, + .target_index = tegra_target, .get = tegra_getspeed, .init = tegra_cpu_init, .exit = tegra_cpu_exit, diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 0aba2a6cadaf..e8c77d330479 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -187,9 +187,11 @@ struct cpufreq_driver { /* define one out of two */ int (*setpolicy) (struct cpufreq_policy *policy); - int (*target) (struct cpufreq_policy *policy, + int (*target) (struct cpufreq_policy *policy, /* Deprecated */ unsigned int target_freq, unsigned int relation); + int (*target_index) (struct cpufreq_policy *policy, + unsigned int index); /* should be defined, if possible */ unsigned int (*get) (unsigned int cpu); -- cgit v1.2.3 From ad7722dab7292dbc1c4586d701ac226b68122d39 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Fri, 18 Oct 2013 19:10:15 +0530 Subject: cpufreq: create per policy rwsem instead of per CPU cpu_policy_rwsem We have per-CPU cpu_policy_rwsem for cpufreq core, but we never use all of them. We always use rwsem of policy->cpu and so we can actually make this rwsem per policy instead. This patch does this change. With this change other tricky situations are also avoided now, like which lock to take while we are changing policy->cpu, etc. Suggested-by: Srivatsa S. Bhat Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Tested-by: Andrew Lunn Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 110 +++++++++++++--------------------------------- include/linux/cpufreq.h | 14 ++++++ 2 files changed, 45 insertions(+), 79 deletions(-) (limited to 'include/linux') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 87ed83a6c894..6c9cbb9ebd1f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -52,47 +52,6 @@ static inline bool has_target(void) return cpufreq_driver->target_index || cpufreq_driver->target; } -/* - * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure - * all cpufreq/hotplug/workqueue/etc related lock issues. - * - * The rules for this semaphore: - * - Any routine that wants to read from the policy structure will - * do a down_read on this semaphore. - * - Any routine that will write to the policy structure and/or may take away - * the policy altogether (eg. CPU hotplug), will hold this lock in write - * mode before doing so. - * - * Additional rules: - * - Governor routines that can be called in cpufreq hotplug path should not - * take this sem as top level hotplug notifier handler takes this. - * - Lock should not be held across - * __cpufreq_governor(data, CPUFREQ_GOV_STOP); - */ -static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); - -#define lock_policy_rwsem(mode, cpu) \ -static void lock_policy_rwsem_##mode(int cpu) \ -{ \ - struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ - BUG_ON(!policy); \ - down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ -} - -lock_policy_rwsem(read, cpu); -lock_policy_rwsem(write, cpu); - -#define unlock_policy_rwsem(mode, cpu) \ -static void unlock_policy_rwsem_##mode(int cpu) \ -{ \ - struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ - BUG_ON(!policy); \ - up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ -} - -unlock_policy_rwsem(read, cpu); -unlock_policy_rwsem(write, cpu); - /* * rwsem to guarantee that cpufreq driver module doesn't unload during critical * sections @@ -688,14 +647,14 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) if (!down_read_trylock(&cpufreq_rwsem)) return -EINVAL; - lock_policy_rwsem_read(policy->cpu); + down_read(&policy->rwsem); if (fattr->show) ret = fattr->show(policy, buf); else ret = -EIO; - unlock_policy_rwsem_read(policy->cpu); + up_read(&policy->rwsem); up_read(&cpufreq_rwsem); return ret; @@ -716,14 +675,14 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, if (!down_read_trylock(&cpufreq_rwsem)) goto unlock; - lock_policy_rwsem_write(policy->cpu); + down_write(&policy->rwsem); if (fattr->store) ret = fattr->store(policy, buf, count); else ret = -EIO; - unlock_policy_rwsem_write(policy->cpu); + up_write(&policy->rwsem); up_read(&cpufreq_rwsem); unlock: @@ -900,7 +859,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, } } - lock_policy_rwsem_write(policy->cpu); + down_write(&policy->rwsem); write_lock_irqsave(&cpufreq_driver_lock, flags); @@ -908,7 +867,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, per_cpu(cpufreq_cpu_data, cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - unlock_policy_rwsem_write(policy->cpu); + up_write(&policy->rwsem); if (has_target()) { if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || @@ -955,6 +914,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void) goto err_free_cpumask; INIT_LIST_HEAD(&policy->policy_list); + init_rwsem(&policy->rwsem); + return policy; err_free_cpumask: @@ -977,19 +938,12 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) if (WARN_ON(cpu == policy->cpu)) return; - /* - * Take direct locks as lock_policy_rwsem_write wouldn't work here. - * Also lock for last cpu is enough here as contention will happen only - * after policy->cpu is changed and after it is changed, other threads - * will try to acquire lock for new cpu. And policy is already updated - * by then. - */ - down_write(&per_cpu(cpu_policy_rwsem, policy->cpu)); + down_write(&policy->rwsem); policy->last_cpu = policy->cpu; policy->cpu = cpu; - up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu)); + up_write(&policy->rwsem); cpufreq_frequency_table_update_policy_cpu(policy); blocking_notifier_call_chain(&cpufreq_policy_notifier_list, @@ -1181,9 +1135,9 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, if (ret) { pr_err("%s: Failed to move kobj: %d", __func__, ret); - lock_policy_rwsem_write(old_cpu); + down_write(&policy->rwsem); cpumask_set_cpu(old_cpu, policy->cpus); - unlock_policy_rwsem_write(old_cpu); + up_write(&policy->rwsem); ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); @@ -1234,9 +1188,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, policy->governor->name, CPUFREQ_NAME_LEN); #endif - lock_policy_rwsem_read(cpu); + down_read(&policy->rwsem); cpus = cpumask_weight(policy->cpus); - unlock_policy_rwsem_read(cpu); + up_read(&policy->rwsem); if (cpu != policy->cpu) { if (!frozen) @@ -1276,12 +1230,12 @@ static int __cpufreq_remove_dev_finish(struct device *dev, return -EINVAL; } - lock_policy_rwsem_write(cpu); + down_write(&policy->rwsem); cpus = cpumask_weight(policy->cpus); if (cpus > 1) cpumask_clear_cpu(cpu, policy->cpus); - unlock_policy_rwsem_write(cpu); + up_write(&policy->rwsem); /* If cpu is last user of policy, free policy */ if (cpus == 1) { @@ -1296,10 +1250,10 @@ static int __cpufreq_remove_dev_finish(struct device *dev, } if (!frozen) { - lock_policy_rwsem_read(cpu); + down_read(&policy->rwsem); kobj = &policy->kobj; cmp = &policy->kobj_unregister; - unlock_policy_rwsem_read(cpu); + up_read(&policy->rwsem); kobject_put(kobj); /* @@ -1479,19 +1433,22 @@ static unsigned int __cpufreq_get(unsigned int cpu) */ unsigned int cpufreq_get(unsigned int cpu) { + struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); unsigned int ret_freq = 0; if (cpufreq_disabled() || !cpufreq_driver) return -ENOENT; + BUG_ON(!policy); + if (!down_read_trylock(&cpufreq_rwsem)) return 0; - lock_policy_rwsem_read(cpu); + down_read(&policy->rwsem); ret_freq = __cpufreq_get(cpu); - unlock_policy_rwsem_read(cpu); + up_read(&policy->rwsem); up_read(&cpufreq_rwsem); return ret_freq; @@ -1744,11 +1701,11 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, { int ret = -EINVAL; - lock_policy_rwsem_write(policy->cpu); + down_write(&policy->rwsem); ret = __cpufreq_driver_target(policy, target_freq, relation); - unlock_policy_rwsem_write(policy->cpu); + up_write(&policy->rwsem); return ret; } @@ -1979,10 +1936,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, /* end old governor */ if (policy->governor) { __cpufreq_governor(policy, CPUFREQ_GOV_STOP); - unlock_policy_rwsem_write(new_policy->cpu); + up_write(&policy->rwsem); __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(new_policy->cpu); + down_write(&policy->rwsem); } /* start new governor */ @@ -1991,10 +1948,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { failed = 0; } else { - unlock_policy_rwsem_write(new_policy->cpu); + up_write(&policy->rwsem); __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(new_policy->cpu); + down_write(&policy->rwsem); } } @@ -2040,7 +1997,7 @@ int cpufreq_update_policy(unsigned int cpu) goto no_policy; } - lock_policy_rwsem_write(cpu); + down_write(&policy->rwsem); pr_debug("updating policy for CPU %u\n", cpu); memcpy(&new_policy, policy, sizeof(*policy)); @@ -2067,7 +2024,7 @@ int cpufreq_update_policy(unsigned int cpu) ret = cpufreq_set_policy(policy, &new_policy); - unlock_policy_rwsem_write(cpu); + up_write(&policy->rwsem); cpufreq_cpu_put(policy); no_policy: @@ -2225,14 +2182,9 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); static int __init cpufreq_core_init(void) { - int cpu; - if (cpufreq_disabled()) return -ENODEV; - for_each_possible_cpu(cpu) - init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); - cpufreq_global_kobject = kobject_create(); BUG_ON(!cpufreq_global_kobject); register_syscore_ops(&cpufreq_syscore_ops); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e8c77d330479..93a8c34d6c7f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -85,6 +85,20 @@ struct cpufreq_policy { struct list_head policy_list; struct kobject kobj; struct completion kobj_unregister; + + /* + * The rules for this semaphore: + * - Any routine that wants to read from the policy structure will + * do a down_read on this semaphore. + * - Any routine that will write to the policy structure and/or may take away + * the policy altogether (eg. CPU hotplug), will hold this lock in write + * mode before doing so. + * + * Additional rules: + * - Lock should not be held across + * __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + */ + struct rw_semaphore rwsem; }; /* Only for ACPI */ -- cgit v1.2.3 From 6587fca23001c33813d56309faf41188b5fbdb70 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 3 Oct 2013 21:26:40 +0530 Subject: cpuidle: fix indentation of cpumask Use tabs for cpumask indentation in struct cpuidle_driver. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpuidle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 781addc66f03..c082425757f4 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -114,7 +114,7 @@ struct cpuidle_driver { int safe_state_index; /* the driver handles the cpus in cpumask */ - struct cpumask *cpumask; + struct cpumask *cpumask; }; #ifdef CONFIG_CPU_IDLE -- cgit v1.2.3 From f60e230f6be5672241e48434a6c2a417d9674d42 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 3 Oct 2013 21:26:55 +0530 Subject: cpuidle: remove cpuidle_unregister_governor() cpuidle_unregister_governor() and cpuidle_replace_governor() aren't used anymore and can be removed. They were used by cpufreq governors earlier, but since the governors can't be compiled as modules any more, these two functions aren't necessary. Suggested-by: Daniel Lezcano Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpuidle/governor.txt | 1 - drivers/cpuidle/governor.c | 43 -------------------------------------- include/linux/cpuidle.h | 6 ------ 3 files changed, 50 deletions(-) (limited to 'include/linux') diff --git a/Documentation/cpuidle/governor.txt b/Documentation/cpuidle/governor.txt index 12c6bd50c9f6..d9020f5e847b 100644 --- a/Documentation/cpuidle/governor.txt +++ b/Documentation/cpuidle/governor.txt @@ -25,5 +25,4 @@ kernel configuration and platform will be selected by cpuidle. Interfaces: extern int cpuidle_register_governor(struct cpuidle_governor *gov); -extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); struct cpuidle_governor diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index ea2f8e7aa24a..ca89412f5122 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c @@ -96,46 +96,3 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) return ret; } - -/** - * cpuidle_replace_governor - find a replacement governor - * @exclude_rating: the rating that will be skipped while looking for - * new governor. - */ -static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating) -{ - struct cpuidle_governor *gov; - struct cpuidle_governor *ret_gov = NULL; - unsigned int max_rating = 0; - - list_for_each_entry(gov, &cpuidle_governors, governor_list) { - if (gov->rating == exclude_rating) - continue; - if (gov->rating > max_rating) { - max_rating = gov->rating; - ret_gov = gov; - } - } - - return ret_gov; -} - -/** - * cpuidle_unregister_governor - unregisters a governor - * @gov: the governor - */ -void cpuidle_unregister_governor(struct cpuidle_governor *gov) -{ - if (!gov) - return; - - mutex_lock(&cpuidle_lock); - if (gov == cpuidle_curr_governor) { - struct cpuidle_governor *new_gov; - new_gov = cpuidle_replace_governor(gov->rating); - cpuidle_switch_governor(new_gov); - } - list_del(&gov->governor_list); - mutex_unlock(&cpuidle_lock); -} - diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index c082425757f4..50fcbb0ac4e7 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -195,16 +195,10 @@ struct cpuidle_governor { }; #ifdef CONFIG_CPU_IDLE - extern int cpuidle_register_governor(struct cpuidle_governor *gov); -extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); - #else - static inline int cpuidle_register_governor(struct cpuidle_governor *gov) {return 0;} -static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } - #endif #ifdef CONFIG_ARCH_HAS_CPU_RELAX -- cgit v1.2.3 From 7dbf694db6ac7c759599316d50d7050efcbd512a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 29 Oct 2013 18:56:06 +0530 Subject: cpufreq: distinguish drivers that do asynchronous notifications There are few special cases like exynos5440 which doesn't send POSTCHANGE notification from their ->target() routine and call some kind of bottom halves for doing this work, work/tasklet/etc.. From which they finally send POSTCHANGE notification. Its better if we distinguish them from other cpufreq drivers in some way so that core can handle them specially. So this patch introduces another flag: CPUFREQ_ASYNC_NOTIFICATION, which will be set by such drivers. This also changes exynos5440-cpufreq.c and powernow-k8 in order to set this flag. Acked-by: Amit Daniel Kachhap Acked-by: Kukjin Kim Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/exynos5440-cpufreq.c | 2 +- drivers/cpufreq/powernow-k8.c | 1 + include/linux/cpufreq.h | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 1bf9b060d522..76bef8b078cb 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -312,7 +312,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) } static struct cpufreq_driver exynos_driver = { - .flags = CPUFREQ_STICKY, + .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION, .verify = cpufreq_generic_frequency_table_verify, .target_index = exynos_target, .get = exynos_getspeed, diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 62a1ce47d3df..0023c7d40a51 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1204,6 +1204,7 @@ out: } static struct cpufreq_driver cpufreq_amd64_driver = { + .flags = CPUFREQ_ASYNC_NOTIFICATION, .verify = cpufreq_generic_frequency_table_verify, .target_index = powernowk8_target, .bios_limit = acpi_processor_get_bios_limit, diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 93a8c34d6c7f..5bd6ab9b0c27 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -237,6 +237,13 @@ struct cpufreq_driver { */ #define CPUFREQ_HAVE_GOVERNOR_PER_POLICY (1 << 3) +/* + * Driver will do POSTCHANGE notifications from outside of their ->target() + * routine and so must set cpufreq_driver->flags with this flag, so that core + * can handle them specially. + */ +#define CPUFREQ_ASYNC_NOTIFICATION (1 << 4) + int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); -- cgit v1.2.3