Commit 8ced6789 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-cpufreq'

* pm-cpufreq: (37 commits)
  cpufreq: dt: allow driver to boot automatically
  intel_pstate: Fix overflow in busy_scaled due to long delay
  cpufreq: qoriq: optimize the CPU frequency switching time
  cpufreq: gx-suspmod: Fix two typos in two comments
  cpufreq: nforce2: Fix typo in comment to function nforce2_init()
  cpufreq: governor: Serialize governor callbacks
  cpufreq: governor: split cpufreq_governor_dbs()
  cpufreq: governor: register notifier from cs_init()
  cpufreq: Remove cpufreq_update_policy()
  cpufreq: Restart governor as soon as possible
  cpufreq: Call cpufreq_policy_put_kobj() from cpufreq_policy_free()
  cpufreq: Initialize policy->kobj while allocating policy
  cpufreq: Stop migrating sysfs files on hotplug
  cpufreq: Don't allow updating inactive policies from sysfs
  intel_pstate: Force setting target pstate when required
  intel_pstate: change some inconsistent debug information
  cpufreq: Track cpu managing sysfs kobjects separately
  cpufreq: Fix for typos in two comments
  cpufreq: Mark policy->governor = NULL for inactive policies
  cpufreq: Manage governor usage history with 'policy->last_governor'
  ...
parents 4a3004e5 07949bf9
......@@ -196,8 +196,6 @@ affected_cpus : List of Online CPUs that require software
related_cpus : List of Online + Offline CPUs that need software
coordination of frequency.
scaling_driver : Hardware driver for cpufreq.
scaling_cur_freq : Current frequency of the CPU as determined by
the governor and cpufreq core, in KHz. This is
the frequency the kernel thinks the CPU runs
......
......@@ -5,7 +5,7 @@
# big LITTLE core layer and glue drivers
config ARM_BIG_LITTLE_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver"
depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK
select PM_OPP
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
......
......@@ -31,7 +31,6 @@
#include <linux/slab.h>
#include <linux/topology.h>
#include <linux/types.h>
#include <asm/bL_switcher.h>
#include "arm_big_little.h"
......@@ -41,12 +40,16 @@
#define MAX_CLUSTERS 2
#ifdef CONFIG_BL_SWITCHER
#include <asm/bL_switcher.h>
static bool bL_switching_enabled;
#define is_bL_switching_enabled() bL_switching_enabled
#define set_switching_enabled(x) (bL_switching_enabled = (x))
#else
#define is_bL_switching_enabled() false
#define set_switching_enabled(x) do { } while (0)
#define bL_switch_request(...) do { } while (0)
#define bL_switcher_put_enabled() do { } while (0)
#define bL_switcher_get_enabled() do { } while (0)
#endif
#define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq)
......@@ -186,6 +189,15 @@ bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate)
mutex_unlock(&cluster_lock[old_cluster]);
}
/*
* FIXME: clk_set_rate has to handle the case where clk_change_rate
* can fail due to hardware or firmware issues. Until the clk core
* layer is fixed, we can check here. In most of the cases we will
* be reading only the cached value anyway. This needs to be removed
* once clk core is fixed.
*/
if (bL_cpufreq_get_rate(cpu) != new_rate)
return -EIO;
return 0;
}
......@@ -322,7 +334,6 @@ static void put_cluster_clk_and_freq_table(struct device *cpu_dev)
static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
{
u32 cluster = raw_cpu_to_cluster(cpu_dev->id);
char name[14] = "cpu-cluster.";
int ret;
if (freq_table[cluster])
......@@ -342,8 +353,7 @@ static int _get_cluster_clk_and_freq_table(struct device *cpu_dev)
goto free_opp_table;
}
name[12] = cluster + '0';
clk[cluster] = clk_get(cpu_dev, name);
clk[cluster] = clk_get(cpu_dev, NULL);
if (!IS_ERR(clk[cluster])) {
dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p, cluster: %d\n",
__func__, clk[cluster], freq_table[cluster],
......@@ -506,6 +516,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
.attr = cpufreq_generic_attr,
};
#ifdef CONFIG_BL_SWITCHER
static int bL_cpufreq_switcher_notifier(struct notifier_block *nfb,
unsigned long action, void *_arg)
{
......@@ -538,6 +549,20 @@ static struct notifier_block bL_switcher_notifier = {
.notifier_call = bL_cpufreq_switcher_notifier,
};
static int __bLs_register_notifier(void)
{
return bL_switcher_register_notifier(&bL_switcher_notifier);
}
static int __bLs_unregister_notifier(void)
{
return bL_switcher_unregister_notifier(&bL_switcher_notifier);
}
#else
static int __bLs_register_notifier(void) { return 0; }
static int __bLs_unregister_notifier(void) { return 0; }
#endif
int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
{
int ret, i;
......@@ -555,8 +580,7 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
arm_bL_ops = ops;
ret = bL_switcher_get_enabled();
set_switching_enabled(ret);
set_switching_enabled(bL_switcher_get_enabled());
for (i = 0; i < MAX_CLUSTERS; i++)
mutex_init(&cluster_lock[i]);
......@@ -567,7 +591,7 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
__func__, ops->name, ret);
arm_bL_ops = NULL;
} else {
ret = bL_switcher_register_notifier(&bL_switcher_notifier);
ret = __bLs_register_notifier();
if (ret) {
cpufreq_unregister_driver(&bL_cpufreq_driver);
arm_bL_ops = NULL;
......@@ -591,7 +615,7 @@ void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops)
}
bL_switcher_get_enabled();
bL_switcher_unregister_notifier(&bL_switcher_notifier);
__bLs_unregister_notifier();
cpufreq_unregister_driver(&bL_cpufreq_driver);
bL_switcher_put_enabled();
pr_info("%s: Un-registered platform driver: %s\n", __func__,
......
......@@ -416,6 +416,7 @@ static struct platform_driver dt_cpufreq_platdrv = {
};
module_platform_driver(dt_cpufreq_platdrv);
MODULE_ALIAS("platform:cpufreq-dt");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("Generic cpufreq driver");
......
......@@ -414,7 +414,7 @@ static int nforce2_detect_chipset(void)
* nforce2_init - initializes the nForce2 CPUFreq driver
*
* Initializes the nForce2 FSB support. Returns -ENODEV on unsupported
* devices, -EINVAL on problems during initiatization, and zero on
* devices, -EINVAL on problems during initialization, and zero on
* success.
*/
static int __init nforce2_init(void)
......
This diff is collapsed.
......@@ -148,6 +148,10 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
return 0;
}
static struct notifier_block cs_cpufreq_notifier_block = {
.notifier_call = dbs_cpufreq_notifier,
};
/************************** sysfs interface ************************/
static struct common_dbs_data cs_dbs_cdata;
......@@ -317,7 +321,7 @@ static struct attribute_group cs_attr_group_gov_pol = {
/************************** sysfs end ************************/
static int cs_init(struct dbs_data *dbs_data)
static int cs_init(struct dbs_data *dbs_data, bool notify)
{
struct cs_dbs_tuners *tuners;
......@@ -336,25 +340,25 @@ static int cs_init(struct dbs_data *dbs_data)
dbs_data->tuners = tuners;
dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
jiffies_to_usecs(10);
mutex_init(&dbs_data->mutex);
if (notify)
cpufreq_register_notifier(&cs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
return 0;
}
static void cs_exit(struct dbs_data *dbs_data)
static void cs_exit(struct dbs_data *dbs_data, bool notify)
{
if (notify)
cpufreq_unregister_notifier(&cs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
kfree(dbs_data->tuners);
}
define_get_cpu_dbs_routines(cs_cpu_dbs_info);
static struct notifier_block cs_cpufreq_notifier_block = {
.notifier_call = dbs_cpufreq_notifier,
};
static struct cs_ops cs_ops = {
.notifier_block = &cs_cpufreq_notifier_block,
};
static struct common_dbs_data cs_dbs_cdata = {
.governor = GOV_CONSERVATIVE,
.attr_group_gov_sys = &cs_attr_group_gov_sys,
......@@ -363,9 +367,9 @@ static struct common_dbs_data cs_dbs_cdata = {
.get_cpu_dbs_info_s = get_cpu_dbs_info_s,
.gov_dbs_timer = cs_dbs_timer,
.gov_check_cpu = cs_check_cpu,
.gov_ops = &cs_ops,
.init = cs_init,
.exit = cs_exit,
.mutex = __MUTEX_INITIALIZER(cs_dbs_cdata.mutex),
};
static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy,
......
This diff is collapsed.
......@@ -208,11 +208,16 @@ struct common_dbs_data {
void *(*get_cpu_dbs_info_s)(int cpu);
void (*gov_dbs_timer)(struct work_struct *work);
void (*gov_check_cpu)(int cpu, unsigned int load);
int (*init)(struct dbs_data *dbs_data);
void (*exit)(struct dbs_data *dbs_data);
int (*init)(struct dbs_data *dbs_data, bool notify);
void (*exit)(struct dbs_data *dbs_data, bool notify);
/* Governor specific ops, see below */
void *gov_ops;
/*
* Protects governor's data (struct dbs_data and struct common_dbs_data)
*/
struct mutex mutex;
};
/* Governor Per policy data */
......@@ -221,9 +226,6 @@ struct dbs_data {
unsigned int min_sampling_rate;
int usage_count;
void *tuners;
/* dbs_mutex protects dbs_enable in governor start/stop */
struct mutex mutex;
};
/* Governor specific ops, will be passed to dbs_data->gov_ops */
......@@ -234,10 +236,6 @@ struct od_ops {
void (*freq_increase)(struct cpufreq_policy *policy, unsigned int freq);
};
struct cs_ops {
struct notifier_block *notifier_block;
};
static inline int delay_for_sampling_rate(unsigned int sampling_rate)
{
int delay = usecs_to_jiffies(sampling_rate);
......
......@@ -475,7 +475,7 @@ static struct attribute_group od_attr_group_gov_pol = {
/************************** sysfs end ************************/
static int od_init(struct dbs_data *dbs_data)
static int od_init(struct dbs_data *dbs_data, bool notify)
{
struct od_dbs_tuners *tuners;
u64 idle_time;
......@@ -513,11 +513,10 @@ static int od_init(struct dbs_data *dbs_data)
tuners->io_is_busy = should_io_be_busy();
dbs_data->tuners = tuners;
mutex_init(&dbs_data->mutex);
return 0;
}
static void od_exit(struct dbs_data *dbs_data)
static void od_exit(struct dbs_data *dbs_data, bool notify)
{
kfree(dbs_data->tuners);
}
......@@ -541,6 +540,7 @@ static struct common_dbs_data od_dbs_cdata = {
.gov_ops = &od_ops,
.init = od_init,
.exit = od_exit,
.mutex = __MUTEX_INITIALIZER(od_dbs_cdata.mutex),
};
static void od_set_powersave_bias(unsigned int powersave_bias)
......
......@@ -144,7 +144,7 @@ module_param(max_duration, int, 0444);
/**
* we can detect a core multipiler from dir0_lsb
* we can detect a core multiplier from dir0_lsb
* from GX1 datasheet p.56,
* MULT[3:0]:
* 0000 = SYSCLK multiplied by 4 (test only)
......@@ -346,7 +346,7 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy)
/* it needs to be assured that at least one supported frequency is
* within policy->min and policy->max. If it is not, policy->max
* needs to be increased until one freuqency is supported.
* needs to be increased until one frequency is supported.
* policy->min may not be decreased, though. This way we guarantee a
* specific processing capacity.
*/
......
......@@ -48,9 +48,9 @@ static inline int32_t mul_fp(int32_t x, int32_t y)
return ((int64_t)x * (int64_t)y) >> FRAC_BITS;
}
static inline int32_t div_fp(int32_t x, int32_t y)
static inline int32_t div_fp(s64 x, s64 y)
{
return div_s64((int64_t)x << FRAC_BITS, y);
return div64_s64((int64_t)x << FRAC_BITS, y);
}
static inline int ceiling_fp(int32_t x)
......@@ -68,6 +68,7 @@ struct sample {
int32_t core_pct_busy;
u64 aperf;
u64 mperf;
u64 tsc;
int freq;
ktime_t time;
};
......@@ -109,6 +110,7 @@ struct cpudata {
ktime_t last_sample_time;
u64 prev_aperf;
u64 prev_mperf;
u64 prev_tsc;
struct sample sample;
};
......@@ -396,7 +398,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
update_turbo_state();
if (limits.turbo_disabled) {
pr_warn("Turbo disabled by BIOS or unavailable on processor\n");
pr_warn("intel_pstate: Turbo disabled by BIOS or unavailable on processor\n");
return -EPERM;
}
......@@ -484,7 +486,7 @@ static void __init intel_pstate_sysfs_expose_params(void)
static void intel_pstate_hwp_enable(void)
{
hwp_active++;
pr_info("intel_pstate HWP enabled\n");
pr_info("intel_pstate: HWP enabled\n");
wrmsrl( MSR_PM_ENABLE, 0x1);
}
......@@ -535,7 +537,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate)
val |= vid;
wrmsrl(MSR_IA32_PERF_CTL, val);
wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val);
}
#define BYT_BCLK_FREQS 5
......@@ -704,19 +706,20 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
}
static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, bool force)
{
int max_perf, min_perf;
update_turbo_state();
intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
if (force) {
update_turbo_state();
pstate = clamp_t(int, pstate, min_perf, max_perf);
intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
if (pstate == cpu->pstate.current_pstate)
return;
pstate = clamp_t(int, pstate, min_perf, max_perf);
if (pstate == cpu->pstate.current_pstate)
return;
}
trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
cpu->pstate.current_pstate = pstate;
......@@ -733,7 +736,7 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
if (pstate_funcs.get_vid)
pstate_funcs.get_vid(cpu);
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false);
}
static inline void intel_pstate_calc_busy(struct cpudata *cpu)
......@@ -756,23 +759,28 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
{
u64 aperf, mperf;
unsigned long flags;
u64 tsc;
local_irq_save(flags);
rdmsrl(MSR_IA32_APERF, aperf);
rdmsrl(MSR_IA32_MPERF, mperf);
tsc = native_read_tsc();
local_irq_restore(flags);
cpu->last_sample_time = cpu->sample.time;
cpu->sample.time = ktime_get();
cpu->sample.aperf = aperf;
cpu->sample.mperf = mperf;
cpu->sample.tsc = tsc;
cpu->sample.aperf -= cpu->prev_aperf;
cpu->sample.mperf -= cpu->prev_mperf;
cpu->sample.tsc -= cpu->prev_tsc;
intel_pstate_calc_busy(cpu);
cpu->prev_aperf = aperf;
cpu->prev_mperf = mperf;
cpu->prev_tsc = tsc;
}
static inline void intel_hwp_set_sample_time(struct cpudata *cpu)
......@@ -794,7 +802,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
{
int32_t core_busy, max_pstate, current_pstate, sample_ratio;
u32 duration_us;
s64 duration_us;
u32 sample_time;
/*
......@@ -821,8 +829,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
* to adjust our busyness.
*/
sample_time = pid_params.sample_rate_ms * USEC_PER_MSEC;
duration_us = (u32) ktime_us_delta(cpu->sample.time,
cpu->last_sample_time);
duration_us = ktime_us_delta(cpu->sample.time,
cpu->last_sample_time);
if (duration_us > sample_time * 3) {
sample_ratio = div_fp(int_tofp(sample_time),
int_tofp(duration_us));
......@@ -837,6 +845,10 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
int32_t busy_scaled;
struct _pid *pid;
signed int ctl;
int from;
struct sample *sample;
from = cpu->pstate.current_pstate;
pid = &cpu->pid;
busy_scaled = intel_pstate_get_scaled_busy(cpu);
......@@ -844,7 +856,17 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
ctl = pid_calc(pid, busy_scaled);
/* Negative values of ctl increase the pstate and vice versa */
intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl, true);
sample = &cpu->sample;
trace_pstate_sample(fp_toint(sample->core_pct_busy),
fp_toint(busy_scaled),
from,
cpu->pstate.current_pstate,
sample->mperf,
sample->aperf,
sample->tsc,
sample->freq);
}
static void intel_hwp_timer_func(unsigned long __data)
......@@ -858,21 +880,11 @@ static void intel_hwp_timer_func(unsigned long __data)
static void intel_pstate_timer_func(unsigned long __data)
{
struct cpudata *cpu = (struct cpudata *) __data;
struct sample *sample;
intel_pstate_sample(cpu);
sample = &cpu->sample;
intel_pstate_adjust_busy_pstate(cpu);
trace_pstate_sample(fp_toint(sample->core_pct_busy),
fp_toint(intel_pstate_get_scaled_busy(cpu)),
cpu->pstate.current_pstate,
sample->mperf,
sample->aperf,
sample->freq);
intel_pstate_set_sample_time(cpu);
}
......@@ -935,7 +947,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
add_timer_on(&cpu->timer, cpunum);
pr_debug("Intel pstate controlling: cpu %d\n", cpunum);
pr_debug("intel_pstate: controlling: cpu %d\n", cpunum);
return 0;
}
......@@ -1001,13 +1013,13 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
int cpu_num = policy->cpu;
struct cpudata *cpu = all_cpu_data[cpu_num];
pr_info("intel_pstate CPU %d exiting\n", cpu_num);
pr_debug("intel_pstate: CPU %d exiting\n", cpu_num);
del_timer_sync(&all_cpu_data[cpu_num]->timer);
if (hwp_active)
return;
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false);
}
static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
......
......@@ -56,7 +56,7 @@ module_param(pxa27x_maxfreq, uint, 0);
MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
"(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
typedef struct {
struct pxa_freqs {
unsigned int khz;
unsigned int membus;
unsigned int cccr;
......@@ -64,7 +64,7 @@ typedef struct {
unsigned int cclkcfg;
int vmin;
int vmax;
} pxa_freqs_t;
};
/* Define the refresh period in mSec for the SDRAM and the number of rows */
#define SDRAM_TREF 64 /* standard 64ms SDRAM */
......@@ -86,7 +86,7 @@ static unsigned int sdram_rows;
/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
#define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS
static pxa_freqs_t pxa255_run_freqs[] =
static const struct pxa_freqs pxa255_run_freqs[] =
{
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
{ 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
......@@ -98,7 +98,7 @@ static pxa_freqs_t pxa255_run_freqs[] =
};
/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
static pxa_freqs_t pxa255_turbo_freqs[] =
static const struct pxa_freqs pxa255_turbo_freqs[] =
{
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
{ 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
......@@ -153,7 +153,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
((HT) ? CCLKCFG_HALFTURBO : 0) | \
((T) ? CCLKCFG_TURBO : 0))
static pxa_freqs_t pxa27x_freqs[] = {
static struct pxa_freqs pxa27x_freqs[] = {
{104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 },
{156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
......@@ -171,7 +171,7 @@ extern unsigned get_clk_frequency_khz(int info);
#ifdef CONFIG_REGULATOR
static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq)
{
int ret = 0;
int vmin, vmax;
......@@ -202,7 +202,7 @@ static void __init pxa_cpufreq_init_voltages(void)
}
}
#else
static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq)
{
return 0;
}
......@@ -211,7 +211,7 @@ static void __init pxa_cpufreq_init_voltages(void) { }
#endif
static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
pxa_freqs_t **pxa_freqs)
const struct pxa_freqs **pxa_freqs)
{
if (cpu_is_pxa25x()) {
if (!pxa255_turbo_table) {
......@@ -270,7 +270,7 @@ static unsigned int pxa_cpufreq_get(unsigned int cpu)
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;
const struct pxa_freqs *pxa_freq_settings;
unsigned long flags;
unsigned int new_freq_cpu, new_freq_mem;
unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
......@@ -361,7 +361,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
int i;
unsigned int freq;
struct cpufreq_frequency_table *pxa255_freq_table;
pxa_freqs_t *pxa255_freqs;
const struct pxa_freqs *pxa255_freqs;
/* try to guess pxa27x cpu */
if (cpu_is_pxa27x())
......
......@@ -27,11 +27,11 @@
/**
* struct cpu_data
* @parent: the parent node of cpu clock
* @pclk: the parent clock of cpu
* @table: frequency table
*/
struct cpu_data {
struct device_node *parent;
struct clk **pclk;
struct cpufreq_frequency_table *table;
};
......@@ -196,7 +196,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
struct device_node *np;
struct device_node *np, *pnode;
int i, count, ret;
u32 freq, mask;
struct clk *clk;
......@@ -219,17 +219,23 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_nomem2;
}
data->parent = of_parse_phandle(np, "clocks", 0);
if (!data->parent) {
pnode = of_parse_phandle(np, "clocks", 0);
if (!pnode) {
pr_err("%s: could not get clock information\n", __func__);
goto err_nomem2;
}
count = of_property_count_strings(data->parent, "clock-names");
count = of_property_count_strings(pnode, "clock-names");
data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
if (!data->pclk) {
pr_err("%s: no memory\n", __func__);
goto err_node;
}
table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
if (!table) {
pr_err("%s: no memory\n", __func__);
goto err_node;
goto err_pclk;
}
if (fmask)
......@@ -238,7 +244,8 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
mask = 0x0;
for (i = 0; i < count; i++) {
clk = of_clk_get(data->parent, i);
clk = of_clk_get(pnode, i);
data->pclk[i] = clk;
freq = clk_get_rate(clk);
/*
* the clock is valid if its frequency is not masked
......@@ -273,13 +280,16 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = u64temp + 1;
of_node_put(np);
of_node_put(pnode);
return 0;
err_nomem1:
kfree(table);
err_pclk:
kfree(data->pclk);
err_node:
of_node_put(data->parent);
of_node_put(pnode);
err_nomem2:
policy->driver_data = NULL;
kfree(data);
......@@ -293,7 +303,7 @@ static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
{
struct cpu_data *data = policy->driver_data;
of_node_put(data->parent);
kfree(data->pclk);
kfree(data->table);
kfree(data);
policy->driver_data = NULL;
......@@ -307,7 +317,7 @@ static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
struct clk *parent;
struct cpu_data *data = policy->driver_data;
parent = of_clk_get(data->parent, data->table[index].driver_data);
parent = data->pclk[data->table[index].driver_data];
return clk_set_parent(policy->clk, parent);
}
......
......@@ -65,7 +65,9 @@ struct cpufreq_policy {
unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs
should set cpufreq */
unsigned int cpu; /* cpu nr of CPU managing this policy */
unsigned int cpu; /* cpu managing this policy, must be online */
unsigned int kobj_cpu; /* cpu managing sysfs files, can be offline */
struct clk *clk;
struct cpufreq_cpuinfo cpuinfo;/* see above */
......@@ -80,6 +82,7 @@ struct cpufreq_policy {
struct cpufreq_governor *governor; /* see below */
void *governor_data;
bool governor_enabled; /* governor start/stop flag */
char last_governor[CPUFREQ_NAME_LEN]; /* last governor used */
struct work_struct update; /* if update_policy() needs to be
* called, but you're in IRQ context */
......
......@@ -42,45 +42,54 @@ TRACE_EVENT(pstate_sample,
TP_PROTO(u32 core_busy,
u32 scaled_busy,
u32 state,
u32 from,
u32 to,
u64 mperf,
u64 aperf,
u64 tsc,
u32 freq
),
TP_ARGS(core_busy,
scaled_busy,
state,
from,
to,
mperf,
aperf,
tsc,
freq
),
TP_STRUCT__entry(
__field(u32, core_busy)
__field(u32, scaled_busy)
__field(u32, state)
__field(u32, from)
__field(u32, to)
__field(u64, mperf)
__field(u64, aperf)
__field(u64, tsc)
__field(u32, freq)
),
),
TP_fast_assign(
__entry->core_busy = core_busy;
__entry->scaled_busy = scaled_busy;
__entry->state = state;
__entry->from = from;
__entry->to = to;
__entry->mperf = mperf;
__entry->aperf = aperf;
__entry->tsc = tsc;
__entry->freq = freq;
),
TP_printk("core_busy=%lu scaled=%lu state=%lu mperf=%llu aperf=%llu freq=%lu ",
TP_printk("core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu ",
(unsigned long)__entry->core_busy,
(unsigned long)__entry->scaled_busy,
(unsigned long)__entry->state,
(unsigned long)__entry->from,
(unsigned long)__entry->to,
(unsigned long long)__entry->mperf,
(unsigned long long)__entry->aperf,
(unsigned long long)__entry->tsc,
(unsigned long)__entry->freq
)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment