|
Lines 33-39
Link Here
|
| 33 |
static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ |
33 |
static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */ |
| 34 |
static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ |
34 |
static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ |
| 35 |
static unsigned int cpu_is_managed[NR_CPUS]; |
35 |
static unsigned int cpu_is_managed[NR_CPUS]; |
| 36 |
static struct cpufreq_policy current_policy[NR_CPUS]; |
|
|
| 37 |
|
36 |
|
| 38 |
static DECLARE_MUTEX (userspace_sem); |
37 |
static DECLARE_MUTEX (userspace_sem); |
| 39 |
|
38 |
|
|
Lines 64-85
Link Here
|
| 64 |
* |
63 |
* |
| 65 |
* Sets the CPU frequency to freq. |
64 |
* Sets the CPU frequency to freq. |
| 66 |
*/ |
65 |
*/ |
| 67 |
static int cpufreq_set(unsigned int freq, unsigned int cpu) |
66 |
static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) |
| 68 |
{ |
67 |
{ |
| 69 |
int ret = -EINVAL; |
68 |
int ret = -EINVAL; |
| 70 |
|
69 |
|
| 71 |
dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq); |
70 |
dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); |
| 72 |
|
71 |
|
| 73 |
down(&userspace_sem); |
72 |
down(&userspace_sem); |
| 74 |
if (!cpu_is_managed[cpu]) |
73 |
if (!cpu_is_managed[policy->cpu]) |
| 75 |
goto err; |
74 |
goto err; |
| 76 |
|
75 |
|
| 77 |
cpu_set_freq[cpu] = freq; |
76 |
cpu_set_freq[policy->cpu] = freq; |
| 78 |
|
77 |
|
| 79 |
if (freq < cpu_min_freq[cpu]) |
78 |
if (freq < cpu_min_freq[policy->cpu]) |
| 80 |
freq = cpu_min_freq[cpu]; |
79 |
freq = cpu_min_freq[policy->cpu]; |
| 81 |
if (freq > cpu_max_freq[cpu]) |
80 |
if (freq > cpu_max_freq[policy->cpu]) |
| 82 |
freq = cpu_max_freq[cpu]; |
81 |
freq = cpu_max_freq[policy->cpu]; |
| 83 |
|
82 |
|
| 84 |
/* |
83 |
/* |
| 85 |
* We're safe from concurrent calls to ->target() here |
84 |
* We're safe from concurrent calls to ->target() here |
|
Lines 88-95
Link Here
|
| 88 |
* A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock) |
87 |
* A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock) |
| 89 |
* B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem) |
88 |
* B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem) |
| 90 |
*/ |
89 |
*/ |
| 91 |
ret = __cpufreq_driver_target(¤t_policy[cpu], freq, |
90 |
ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); |
| 92 |
CPUFREQ_RELATION_L); |
|
|
| 93 |
|
91 |
|
| 94 |
err: |
92 |
err: |
| 95 |
up(&userspace_sem); |
93 |
up(&userspace_sem); |
|
Lines 113-119
Link Here
|
| 113 |
if (ret != 1) |
111 |
if (ret != 1) |
| 114 |
return -EINVAL; |
112 |
return -EINVAL; |
| 115 |
|
113 |
|
| 116 |
cpufreq_set(freq, policy->cpu); |
114 |
cpufreq_set(freq, policy); |
| 117 |
|
115 |
|
| 118 |
return count; |
116 |
return count; |
| 119 |
} |
117 |
} |
|
Lines 141-147
Link Here
|
| 141 |
cpu_cur_freq[cpu] = policy->cur; |
139 |
cpu_cur_freq[cpu] = policy->cur; |
| 142 |
cpu_set_freq[cpu] = policy->cur; |
140 |
cpu_set_freq[cpu] = policy->cur; |
| 143 |
sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); |
141 |
sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); |
| 144 |
memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); |
|
|
| 145 |
dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); |
142 |
dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); |
| 146 |
up(&userspace_sem); |
143 |
up(&userspace_sem); |
| 147 |
break; |
144 |
break; |
|
Lines 161-176
Link Here
|
| 161 |
cpu_max_freq[cpu] = policy->max; |
158 |
cpu_max_freq[cpu] = policy->max; |
| 162 |
dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); |
159 |
dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]); |
| 163 |
if (policy->max < cpu_set_freq[cpu]) { |
160 |
if (policy->max < cpu_set_freq[cpu]) { |
| 164 |
__cpufreq_driver_target(¤t_policy[cpu], policy->max, |
161 |
if (!__cpufreq_driver_target(policy, policy->max, |
| 165 |
CPUFREQ_RELATION_H); |
162 |
CPUFREQ_RELATION_H)) |
|
|
163 |
cpu_cur_freq[cpu] = policy->max; |
| 166 |
} else if (policy->min > cpu_set_freq[cpu]) { |
164 |
} else if (policy->min > cpu_set_freq[cpu]) { |
| 167 |
__cpufreq_driver_target(¤t_policy[cpu], policy->min, |
165 |
if (!__cpufreq_driver_target(policy, policy->min, |
| 168 |
CPUFREQ_RELATION_L); |
166 |
CPUFREQ_RELATION_L)) |
|
|
167 |
cpu_cur_freq[cpu] = policy->min; |
| 169 |
} else { |
168 |
} else { |
| 170 |
__cpufreq_driver_target(¤t_policy[cpu], cpu_set_freq[cpu], |
169 |
__cpufreq_driver_target(policy, cpu_set_freq[cpu], |
| 171 |
CPUFREQ_RELATION_L); |
170 |
CPUFREQ_RELATION_L); |
| 172 |
} |
171 |
} |
| 173 |
memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); |
|
|
| 174 |
up(&userspace_sem); |
172 |
up(&userspace_sem); |
| 175 |
break; |
173 |
break; |
| 176 |
} |
174 |
} |