···784784785785EXPORT_SYMBOL(acpi_processor_register_performance);786786787787-void788788-acpi_processor_unregister_performance(struct acpi_processor_performance789789- *performance, unsigned int cpu)787787+void acpi_processor_unregister_performance(unsigned int cpu)790788{791789 struct acpi_processor *pr;792790
+51-42
drivers/cpufreq/acpi-cpufreq.c
···6565#define MSR_K7_HWCR_CPB_DIS (1ULL << 25)66666767struct acpi_cpufreq_data {6868- struct acpi_processor_performance *acpi_data;6968 struct cpufreq_frequency_table *freq_table;7069 unsigned int resume;7170 unsigned int cpu_feature;7171+ unsigned int acpi_perf_cpu;7272 cpumask_var_t freqdomain_cpus;7373};74747575-static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);7676-7775/* acpi_perf_data is a pointer to percpu data. */7876static struct acpi_processor_performance __percpu *acpi_perf_data;7777+7878+static inline struct acpi_processor_performance *to_perf_data(struct acpi_cpufreq_data *data)7979+{8080+ return per_cpu_ptr(acpi_perf_data, data->acpi_perf_cpu);8181+}79828083static struct cpufreq_driver acpi_cpufreq_driver;8184···147144148145static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)149146{150150- struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);147147+ struct acpi_cpufreq_data *data = policy->driver_data;151148152149 return cpufreq_show_cpus(data->freqdomain_cpus, buf);153150}···205202 struct acpi_processor_performance *perf;206203 int i;207204208208- perf = data->acpi_data;205205+ perf = to_perf_data(data);209206210207 for (i = 0; i < perf->state_count; i++) {211208 if (value == perf->states[i].status)···224221 else225222 msr &= INTEL_MSR_RANGE;226223227227- perf = data->acpi_data;224224+ perf = to_perf_data(data);228225229226 cpufreq_for_each_entry(pos, data->freq_table)230227 if (msr == perf->states[pos->driver_data].status)···330327 put_cpu();331328}332329333333-static u32 get_cur_val(const struct cpumask *mask)330330+static u32331331+get_cur_val(const struct cpumask *mask, struct acpi_cpufreq_data *data)334332{335333 struct acpi_processor_performance *perf;336334 struct drv_cmd cmd;···339335 if (unlikely(cpumask_empty(mask)))340336 return 0;341337342342- switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {338338+ switch (data->cpu_feature) {343339 case SYSTEM_INTEL_MSR_CAPABLE:344340 cmd.type = SYSTEM_INTEL_MSR_CAPABLE;345341 cmd.addr.msr.reg = MSR_IA32_PERF_CTL;···350346 break;351347 case SYSTEM_IO_CAPABLE:352348 cmd.type = SYSTEM_IO_CAPABLE;353353- perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;349349+ perf = to_perf_data(data);354350 cmd.addr.io.port = perf->control_register.address;355351 cmd.addr.io.bit_width = perf->control_register.bit_width;356352 break;···368364369365static unsigned int get_cur_freq_on_cpu(unsigned int cpu)370366{371371- struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);367367+ struct acpi_cpufreq_data *data;368368+ struct cpufreq_policy *policy;372369 unsigned int freq;373370 unsigned int cached_freq;374371375372 pr_debug("get_cur_freq_on_cpu (%d)\n", cpu);376373377377- if (unlikely(data == NULL ||378378- data->acpi_data == NULL || data->freq_table == NULL)) {374374+ policy = cpufreq_cpu_get(cpu);375375+ if (unlikely(!policy))379376 return 0;380380- }381377382382- cached_freq = data->freq_table[data->acpi_data->state].frequency;383383- freq = extract_freq(get_cur_val(cpumask_of(cpu)), data);378378+ data = policy->driver_data;379379+ cpufreq_cpu_put(policy);380380+ if (unlikely(!data || !data->freq_table))381381+ return 0;382382+383383+ cached_freq = data->freq_table[to_perf_data(data)->state].frequency;384384+ freq = extract_freq(get_cur_val(cpumask_of(cpu), data), data);384385 if (freq != cached_freq) {385386 /*386387 * The dreaded BIOS frequency change behind our back.···406397 unsigned int i;407398408399 for (i = 0; i < 100; i++) {409409- cur_freq = extract_freq(get_cur_val(mask), data);400400+ cur_freq = extract_freq(get_cur_val(mask, data), data);410401 if (cur_freq == freq)411402 return 1;412403 udelay(10);···417408static int acpi_cpufreq_target(struct cpufreq_policy *policy,418409 unsigned int index)419410{420420- struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);411411+ struct acpi_cpufreq_data *data = policy->driver_data;421412 struct acpi_processor_performance *perf;422413 struct drv_cmd cmd;423414 unsigned int next_perf_state = 0; /* Index into perf table */424415 int result = 0;425416426426- if (unlikely(data == NULL ||427427- data->acpi_data == NULL || data->freq_table == NULL)) {417417+ if (unlikely(data == NULL || data->freq_table == NULL)) {428418 return -ENODEV;429419 }430420431431- perf = data->acpi_data;421421+ perf = to_perf_data(data);432422 next_perf_state = data->freq_table[index].driver_data;433423 if (perf->state == next_perf_state) {434424 if (unlikely(data->resume)) {···490482static unsigned long491483acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)492484{493493- struct acpi_processor_performance *perf = data->acpi_data;485485+ struct acpi_processor_performance *perf;494486487487+ perf = to_perf_data(data);495488 if (cpu_khz) {496489 /* search the closest match to cpu_khz */497490 unsigned int i;···681672 goto err_free;682673 }683674684684- data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);685685- per_cpu(acfreq_data, cpu) = data;675675+ perf = per_cpu_ptr(acpi_perf_data, cpu);676676+ data->acpi_perf_cpu = cpu;677677+ policy->driver_data = data;686678687679 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))688680 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;689681690690- result = acpi_processor_register_performance(data->acpi_data, cpu);682682+ result = acpi_processor_register_performance(perf, cpu);691683 if (result)692684 goto err_free_mask;693685694694- perf = data->acpi_data;695686 policy->shared_type = perf->shared_type;696687697688 /*···847838err_freqfree:848839 kfree(data->freq_table);849840err_unreg:850850- acpi_processor_unregister_performance(perf, cpu);841841+ acpi_processor_unregister_performance(cpu);851842err_free_mask:852843 free_cpumask_var(data->freqdomain_cpus);853844err_free:854845 kfree(data);855855- per_cpu(acfreq_data, cpu) = NULL;846846+ policy->driver_data = NULL;856847857848 return result;858849}859850860851static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)861852{862862- struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);853853+ struct acpi_cpufreq_data *data = policy->driver_data;863854864855 pr_debug("acpi_cpufreq_cpu_exit\n");865856866857 if (data) {867867- per_cpu(acfreq_data, policy->cpu) = NULL;868868- acpi_processor_unregister_performance(data->acpi_data,869869- policy->cpu);858858+ policy->driver_data = NULL;859859+ acpi_processor_unregister_performance(data->acpi_perf_cpu);870860 free_cpumask_var(data->freqdomain_cpus);871861 kfree(data->freq_table);872862 kfree(data);···876868877869static int acpi_cpufreq_resume(struct cpufreq_policy *policy)878870{879879- struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);871871+ struct acpi_cpufreq_data *data = policy->driver_data;880872881873 pr_debug("acpi_cpufreq_resume\n");882874···888880static struct freq_attr *acpi_cpufreq_attr[] = {889881 &cpufreq_freq_attr_scaling_available_freqs,890882 &freqdomain_cpus,891891- NULL, /* this is a placeholder for cpb, do not remove */883883+#ifdef CONFIG_X86_ACPI_CPUFREQ_CPB884884+ &cpb,885885+#endif892886 NULL,893887};894888···963953 * only if configured. This is considered legacy code, which964954 * will probably be removed at some point in the future.965955 */966966- if (check_amd_hwpstate_cpu(0)) {967967- struct freq_attr **iter;956956+ if (!check_amd_hwpstate_cpu(0)) {957957+ struct freq_attr **attr;968958969969- pr_debug("adding sysfs entry for cpb\n");959959+ pr_debug("CPB unsupported, do not expose it\n");970960971971- for (iter = acpi_cpufreq_attr; *iter != NULL; iter++)972972- ;973973-974974- /* make sure there is a terminator behind it */975975- if (iter[1] == NULL)976976- *iter = &cpb;961961+ for (attr = acpi_cpufreq_attr; *attr; attr++)962962+ if (*attr == &cpb) {963963+ *attr = NULL;964964+ break;965965+ }977966 }978967#endif979968 acpi_cpufreq_boost_init();
+145-177
drivers/cpufreq/cpufreq.c
···112112 return cpufreq_driver->target_index || cpufreq_driver->target;113113}114114115115-/*116116- * rwsem to guarantee that cpufreq driver module doesn't unload during critical117117- * sections118118- */119119-static DECLARE_RWSEM(cpufreq_rwsem);120120-121115/* internal prototypes */122116static int __cpufreq_governor(struct cpufreq_policy *policy,123117 unsigned int event);···271277 * If corresponding call cpufreq_cpu_put() isn't made, the policy wouldn't be272278 * freed as that depends on the kobj count.273279 *274274- * It also takes a read-lock of 'cpufreq_rwsem' and doesn't put it back if a275275- * valid policy is found. This is done to make sure the driver doesn't get276276- * unregistered while the policy is being used.277277- *278280 * Return: A valid policy on success, otherwise NULL on failure.279281 */280282struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)···279289 unsigned long flags;280290281291 if (WARN_ON(cpu >= nr_cpu_ids))282282- return NULL;283283-284284- if (!down_read_trylock(&cpufreq_rwsem))285292 return NULL;286293287294 /* get the cpufreq driver */···293306294307 read_unlock_irqrestore(&cpufreq_driver_lock, flags);295308296296- if (!policy)297297- up_read(&cpufreq_rwsem);298298-299309 return policy;300310}301311EXPORT_SYMBOL_GPL(cpufreq_cpu_get);···304320 *305321 * This decrements the kobject reference count incremented earlier by calling306322 * cpufreq_cpu_get().307307- *308308- * It also drops the read-lock of 'cpufreq_rwsem' taken at cpufreq_cpu_get().309323 */310324void cpufreq_cpu_put(struct cpufreq_policy *policy)311325{312326 kobject_put(&policy->kobj);313313- up_read(&cpufreq_rwsem);314327}315328EXPORT_SYMBOL_GPL(cpufreq_cpu_put);316329···832851 struct freq_attr *fattr = to_attr(attr);833852 ssize_t ret;834853835835- if (!down_read_trylock(&cpufreq_rwsem))836836- return -EINVAL;837837-838854 down_read(&policy->rwsem);839855840856 if (fattr->show)···840862 ret = -EIO;841863842864 up_read(&policy->rwsem);843843- up_read(&cpufreq_rwsem);844865845866 return ret;846867}···854877 get_online_cpus();855878856879 if (!cpu_online(policy->cpu))857857- goto unlock;858858-859859- if (!down_read_trylock(&cpufreq_rwsem))860880 goto unlock;861881862882 down_write(&policy->rwsem);···871897872898unlock_policy_rwsem:873899 up_write(&policy->rwsem);874874-875875- up_read(&cpufreq_rwsem);876900unlock:877901 put_online_cpus();878902···9991027 }10001028}1001102910021002-static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,10031003- struct device *dev)10301030+static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)10041031{10051032 struct freq_attr **drv_attr;10061033 int ret = 0;···10311060 return cpufreq_add_dev_symlink(policy);10321061}1033106210341034-static void cpufreq_init_policy(struct cpufreq_policy *policy)10631063+static int cpufreq_init_policy(struct cpufreq_policy *policy)10351064{10361065 struct cpufreq_governor *gov = NULL;10371066 struct cpufreq_policy new_policy;10381038- int ret = 0;1039106710401068 memcpy(&new_policy, policy, sizeof(*policy));10411069···10531083 cpufreq_parse_governor(gov->name, &new_policy.policy, NULL);1054108410551085 /* set default policy */10561056- ret = cpufreq_set_policy(policy, &new_policy);10571057- if (ret) {10581058- pr_debug("setting policy failed\n");10591059- if (cpufreq_driver->exit)10601060- cpufreq_driver->exit(policy);10611061- }10861086+ return cpufreq_set_policy(policy, &new_policy);10621087}1063108810641064-static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,10651065- unsigned int cpu, struct device *dev)10891089+static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)10661090{10671091 int ret = 0;10681092···10901126 return 0;10911127}1092112810931093-static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)11291129+static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)10941130{10951095- struct cpufreq_policy *policy;10961096- unsigned long flags;10971097-10981098- read_lock_irqsave(&cpufreq_driver_lock, flags);10991099- policy = per_cpu(cpufreq_cpu_data, cpu);11001100- read_unlock_irqrestore(&cpufreq_driver_lock, flags);11011101-11021102- if (likely(policy)) {11031103- /* Policy should be inactive here */11041104- WARN_ON(!policy_is_inactive(policy));11051105-11061106- down_write(&policy->rwsem);11071107- policy->cpu = cpu;11081108- policy->governor = NULL;11091109- up_write(&policy->rwsem);11101110- }11111111-11121112- return policy;11131113-}11141114-11151115-static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev)11161116-{11311131+ struct device *dev = get_cpu_device(cpu);11171132 struct cpufreq_policy *policy;11181133 int ret;11341134+11351135+ if (WARN_ON(!dev))11361136+ return NULL;1119113711201138 policy = kzalloc(sizeof(*policy), GFP_KERNEL);11211139 if (!policy)···11261180 init_completion(&policy->kobj_unregister);11271181 INIT_WORK(&policy->update, handle_update);1128118211291129- policy->cpu = dev->id;11831183+ policy->cpu = cpu;1130118411311185 /* Set this once on allocation */11321132- policy->kobj_cpu = dev->id;11861186+ policy->kobj_cpu = cpu;1133118711341188 return policy;11351189···11911245 kfree(policy);11921246}1193124711941194-/**11951195- * cpufreq_add_dev - add a CPU device11961196- *11971197- * Adds the cpufreq interface for a CPU device.11981198- *11991199- * The Oracle says: try running cpufreq registration/unregistration concurrently12001200- * with with cpu hotplugging and all hell will break loose. Tried to clean this12011201- * mess up, but more thorough testing is needed. - Mathieu12021202- */12031203-static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)12481248+static int cpufreq_online(unsigned int cpu)12041249{12051205- unsigned int j, cpu = dev->id;12061206- int ret = -ENOMEM;12071250 struct cpufreq_policy *policy;12511251+ bool new_policy;12081252 unsigned long flags;12091209- bool recover_policy = !sif;12531253+ unsigned int j;12541254+ int ret;1210125512111211- pr_debug("adding CPU %u\n", cpu);12121212-12131213- if (cpu_is_offline(cpu)) {12141214- /*12151215- * Only possible if we are here from the subsys_interface add12161216- * callback. A hotplug notifier will follow and we will handle12171217- * it as CPU online then. For now, just create the sysfs link,12181218- * unless there is no policy or the link is already present.12191219- */12201220- policy = per_cpu(cpufreq_cpu_data, cpu);12211221- return policy && !cpumask_test_and_set_cpu(cpu, policy->real_cpus)12221222- ? add_cpu_dev_symlink(policy, cpu) : 0;12231223- }12241224-12251225- if (!down_read_trylock(&cpufreq_rwsem))12261226- return 0;12561256+ pr_debug("%s: bringing CPU%u online\n", __func__, cpu);1227125712281258 /* Check if this CPU already has a policy to manage it */12291259 policy = per_cpu(cpufreq_cpu_data, cpu);12301230- if (policy && !policy_is_inactive(policy)) {12601260+ if (policy) {12311261 WARN_ON(!cpumask_test_cpu(cpu, policy->related_cpus));12321232- ret = cpufreq_add_policy_cpu(policy, cpu, dev);12331233- up_read(&cpufreq_rwsem);12341234- return ret;12351235- }12621262+ if (!policy_is_inactive(policy))12631263+ return cpufreq_add_policy_cpu(policy, cpu);1236126412371237- /*12381238- * Restore the saved policy when doing light-weight init and fall back12391239- * to the full init if that fails.12401240- */12411241- policy = recover_policy ? cpufreq_policy_restore(cpu) : NULL;12421242- if (!policy) {12431243- recover_policy = false;12441244- policy = cpufreq_policy_alloc(dev);12651265+ /* This is the only online CPU for the policy. Start over. */12661266+ new_policy = false;12671267+ down_write(&policy->rwsem);12681268+ policy->cpu = cpu;12691269+ policy->governor = NULL;12701270+ up_write(&policy->rwsem);12711271+ } else {12721272+ new_policy = true;12731273+ policy = cpufreq_policy_alloc(cpu);12451274 if (!policy)12461246- goto nomem_out;12751275+ return -ENOMEM;12471276 }1248127712491278 cpumask_copy(policy->cpus, cpumask_of(cpu));···12291308 ret = cpufreq_driver->init(policy);12301309 if (ret) {12311310 pr_debug("initialization failed\n");12321232- goto err_set_policy_cpu;13111311+ goto out_free_policy;12331312 }1234131312351314 down_write(&policy->rwsem);1236131512371237- /* related cpus should atleast have policy->cpus */12381238- cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);12391239-12401240- /* Remember which CPUs have been present at the policy creation time. */12411241- if (!recover_policy)13161316+ if (new_policy) {13171317+ /* related_cpus should at least include policy->cpus. */13181318+ cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);13191319+ /* Remember CPUs present at the policy creation time. */12421320 cpumask_and(policy->real_cpus, policy->cpus, cpu_present_mask);13211321+ }1243132212441323 /*12451324 * affected cpus must always be the one, which are online. We aren't···12471326 */12481327 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);1249132812501250- if (!recover_policy) {13291329+ if (new_policy) {12511330 policy->user_policy.min = policy->min;12521331 policy->user_policy.max = policy->max;12531332···12611340 policy->cur = cpufreq_driver->get(policy->cpu);12621341 if (!policy->cur) {12631342 pr_err("%s: ->get() failed\n", __func__);12641264- goto err_get_freq;13431343+ goto out_exit_policy;12651344 }12661345 }12671346···13081387 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,13091388 CPUFREQ_START, policy);1310138913111311- if (!recover_policy) {13121312- ret = cpufreq_add_dev_interface(policy, dev);13901390+ if (new_policy) {13911391+ ret = cpufreq_add_dev_interface(policy);13131392 if (ret)13141314- goto err_out_unregister;13931393+ goto out_exit_policy;13151394 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,13161395 CPUFREQ_CREATE_POLICY, policy);13171396···13201399 write_unlock_irqrestore(&cpufreq_driver_lock, flags);13211400 }1322140113231323- cpufreq_init_policy(policy);14021402+ ret = cpufreq_init_policy(policy);14031403+ if (ret) {14041404+ pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n",14051405+ __func__, cpu, ret);14061406+ /* cpufreq_policy_free() will notify based on this */14071407+ new_policy = false;14081408+ goto out_exit_policy;14091409+ }1324141013251325- if (!recover_policy) {14111411+ if (new_policy) {13261412 policy->user_policy.policy = policy->policy;13271413 policy->user_policy.governor = policy->governor;13281414 }13291415 up_write(&policy->rwsem);1330141613311417 kobject_uevent(&policy->kobj, KOBJ_ADD);13321332-13331333- up_read(&cpufreq_rwsem);1334141813351419 /* Callback for handling stuff after policy is ready */13361420 if (cpufreq_driver->ready)···1345141913461420 return 0;1347142113481348-err_out_unregister:13491349-err_get_freq:14221422+out_exit_policy:13501423 up_write(&policy->rwsem);1351142413521425 if (cpufreq_driver->exit)13531426 cpufreq_driver->exit(policy);13541354-err_set_policy_cpu:13551355- cpufreq_policy_free(policy, recover_policy);13561356-nomem_out:13571357- up_read(&cpufreq_rwsem);14271427+out_free_policy:14281428+ cpufreq_policy_free(policy, !new_policy);14291429+ return ret;14301430+}14311431+14321432+/**14331433+ * cpufreq_add_dev - the cpufreq interface for a CPU device.14341434+ * @dev: CPU device.14351435+ * @sif: Subsystem interface structure pointer (not used)14361436+ */14371437+static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)14381438+{14391439+ unsigned cpu = dev->id;14401440+ int ret;14411441+14421442+ dev_dbg(dev, "%s: adding CPU%u\n", __func__, cpu);14431443+14441444+ if (cpu_online(cpu)) {14451445+ ret = cpufreq_online(cpu);14461446+ } else {14471447+ /*14481448+ * A hotplug notifier will follow and we will handle it as CPU14491449+ * online then. For now, just create the sysfs link, unless14501450+ * there is no policy or the link is already present.14511451+ */14521452+ struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);14531453+14541454+ ret = policy && !cpumask_test_and_set_cpu(cpu, policy->real_cpus)14551455+ ? add_cpu_dev_symlink(policy, cpu) : 0;14561456+ }1358145713591458 return ret;13601459}1361146013621362-static int __cpufreq_remove_dev_prepare(struct device *dev)14611461+static void cpufreq_offline_prepare(unsigned int cpu)13631462{13641364- unsigned int cpu = dev->id;13651365- int ret = 0;13661463 struct cpufreq_policy *policy;1367146413681465 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);···13931444 policy = cpufreq_cpu_get_raw(cpu);13941445 if (!policy) {13951446 pr_debug("%s: No cpu_data found\n", __func__);13961396- return -EINVAL;14471447+ return;13971448 }1398144913991450 if (has_target()) {14001400- ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);14511451+ int ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);14011452 if (ret)14021453 pr_err("%s: Failed to stop governor\n", __func__);14031454 }···14181469 /* Start governor again for active policy */14191470 if (!policy_is_inactive(policy)) {14201471 if (has_target()) {14211421- ret = __cpufreq_governor(policy, CPUFREQ_GOV_START);14721472+ int ret = __cpufreq_governor(policy, CPUFREQ_GOV_START);14221473 if (!ret)14231474 ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);14241475···14281479 } else if (cpufreq_driver->stop_cpu) {14291480 cpufreq_driver->stop_cpu(policy);14301481 }14311431-14321432- return ret;14331482}1434148314351435-static int __cpufreq_remove_dev_finish(struct device *dev)14841484+static void cpufreq_offline_finish(unsigned int cpu)14361485{14371437- unsigned int cpu = dev->id;14381438- int ret;14391486 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);1440148714411488 if (!policy) {14421489 pr_debug("%s: No cpu_data found\n", __func__);14431443- return -EINVAL;14901490+ return;14441491 }1445149214461493 /* Only proceed for inactive policies */14471494 if (!policy_is_inactive(policy))14481448- return 0;14951495+ return;1449149614501497 /* If cpu is last user of policy, free policy */14511498 if (has_target()) {14521452- ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);14991499+ int ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);14531500 if (ret)14541501 pr_err("%s: Failed to exit governor\n", __func__);14551502 }···14571512 */14581513 if (cpufreq_driver->exit)14591514 cpufreq_driver->exit(policy);14601460-14611461- return 0;14621515}1463151614641517/**···14731530 return 0;1474153114751532 if (cpu_online(cpu)) {14761476- __cpufreq_remove_dev_prepare(dev);14771477- __cpufreq_remove_dev_finish(dev);15331533+ cpufreq_offline_prepare(cpu);15341534+ cpufreq_offline_finish(cpu);14781535 }1479153614801537 cpumask_clear_cpu(cpu, policy->real_cpus);···2190224721912248 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));2192224921932193- if (new_policy->min > policy->max || new_policy->max < policy->min)22502250+ /*22512251+ * This check works well when we store new min/max freq attributes,22522252+ * because new_policy is a copy of policy with one field updated.22532253+ */22542254+ if (new_policy->min > new_policy->max)21942255 return -EINVAL;2195225621962257 /* verify the cpu speed can be set within this limit */···22432296 old_gov = policy->governor;22442297 /* end old governor */22452298 if (old_gov) {22462246- __cpufreq_governor(policy, CPUFREQ_GOV_STOP);22992299+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);23002300+ if (ret) {23012301+ /* This can happen due to race with other operations */23022302+ pr_debug("%s: Failed to Stop Governor: %s (%d)\n",23032303+ __func__, old_gov->name, ret);23042304+ return ret;23052305+ }23062306+22472307 up_write(&policy->rwsem);22482248- __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);23082308+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);22492309 down_write(&policy->rwsem);23102310+23112311+ if (ret) {23122312+ pr_err("%s: Failed to Exit Governor: %s (%d)\n",23132313+ __func__, old_gov->name, ret);23142314+ return ret;23152315+ }22502316 }2251231722522318 /* start new governor */22532319 policy->governor = new_policy->governor;22542254- if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {22552255- if (!__cpufreq_governor(policy, CPUFREQ_GOV_START))23202320+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT);23212321+ if (!ret) {23222322+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_START);23232323+ if (!ret)22562324 goto out;2257232522582326 up_write(&policy->rwsem);···22792317 pr_debug("starting governor %s failed\n", policy->governor->name);22802318 if (old_gov) {22812319 policy->governor = old_gov;22822282- __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT);22832283- __cpufreq_governor(policy, CPUFREQ_GOV_START);23202320+ if (__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT))23212321+ policy->governor = NULL;23222322+ else23232323+ __cpufreq_governor(policy, CPUFREQ_GOV_START);22842324 }2285232522862286- return -EINVAL;23262326+ return ret;2287232722882328 out:22892329 pr_debug("governor: change or update limits\n");···23512387 unsigned long action, void *hcpu)23522388{23532389 unsigned int cpu = (unsigned long)hcpu;23542354- struct device *dev;2355239023562356- dev = get_cpu_device(cpu);23572357- if (dev) {23582358- switch (action & ~CPU_TASKS_FROZEN) {23592359- case CPU_ONLINE:23602360- cpufreq_add_dev(dev, NULL);23612361- break;23912391+ switch (action & ~CPU_TASKS_FROZEN) {23922392+ case CPU_ONLINE:23932393+ cpufreq_online(cpu);23942394+ break;2362239523632363- case CPU_DOWN_PREPARE:23642364- __cpufreq_remove_dev_prepare(dev);23652365- break;23962396+ case CPU_DOWN_PREPARE:23972397+ cpufreq_offline_prepare(cpu);23982398+ break;2366239923672367- case CPU_POST_DEAD:23682368- __cpufreq_remove_dev_finish(dev);23692369- break;24002400+ case CPU_POST_DEAD:24012401+ cpufreq_offline_finish(cpu);24022402+ break;2370240323712371- case CPU_DOWN_FAILED:23722372- cpufreq_add_dev(dev, NULL);23732373- break;23742374- }24042404+ case CPU_DOWN_FAILED:24052405+ cpufreq_online(cpu);24062406+ break;23752407 }23762408 return NOTIFY_OK;23772409}···2475251524762516 pr_debug("trying to register driver %s\n", driver_data->name);2477251725182518+ /* Protect against concurrent CPU online/offline. */25192519+ get_online_cpus();25202520+24782521 write_lock_irqsave(&cpufreq_driver_lock, flags);24792522 if (cpufreq_driver) {24802523 write_unlock_irqrestore(&cpufreq_driver_lock, flags);24812481- return -EEXIST;25242524+ ret = -EEXIST;25252525+ goto out;24822526 }24832527 cpufreq_driver = driver_data;24842528 write_unlock_irqrestore(&cpufreq_driver_lock, flags);···25212557 register_hotcpu_notifier(&cpufreq_cpu_notifier);25222558 pr_debug("driver %s up and running\n", driver_data->name);2523255925242524- return 0;25602560+out:25612561+ put_online_cpus();25622562+ return ret;25632563+25252564err_if_unreg:25262565 subsys_interface_unregister(&cpufreq_interface);25272566err_boost_unreg:···25342567 write_lock_irqsave(&cpufreq_driver_lock, flags);25352568 cpufreq_driver = NULL;25362569 write_unlock_irqrestore(&cpufreq_driver_lock, flags);25372537- return ret;25702570+ goto out;25382571}25392572EXPORT_SYMBOL_GPL(cpufreq_register_driver);25402573···2555258825562589 pr_debug("unregistering driver %s\n", driver->name);2557259025912591+ /* Protect against concurrent cpu hotplug */25922592+ get_online_cpus();25582593 subsys_interface_unregister(&cpufreq_interface);25592594 if (cpufreq_boost_supported())25602595 cpufreq_sysfs_remove_file(&boost.attr);2561259625622597 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);2563259825642564- down_write(&cpufreq_rwsem);25652599 write_lock_irqsave(&cpufreq_driver_lock, flags);2566260025672601 cpufreq_driver = NULL;2568260225692603 write_unlock_irqrestore(&cpufreq_driver_lock, flags);25702570- up_write(&cpufreq_rwsem);26042604+ put_online_cpus();2571260525722606 return 0;25732607}
+7-18
drivers/cpufreq/cpufreq_conservative.c
···4747static void cs_check_cpu(int cpu, unsigned int load)4848{4949 struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);5050- struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;5050+ struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy;5151 struct dbs_data *dbs_data = policy->governor_data;5252 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;5353···102102 }103103}104104105105-static void cs_dbs_timer(struct work_struct *work)105105+static unsigned int cs_dbs_timer(struct cpu_dbs_info *cdbs,106106+ struct dbs_data *dbs_data, bool modify_all)106107{107107- struct cs_cpu_dbs_info_s *dbs_info = container_of(work,108108- struct cs_cpu_dbs_info_s, cdbs.work.work);109109- unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;110110- struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info,111111- cpu);112112- struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data;113108 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;114114- int delay = delay_for_sampling_rate(cs_tuners->sampling_rate);115115- bool modify_all = true;116109117117- mutex_lock(&core_dbs_info->cdbs.timer_mutex);118118- if (!need_load_eval(&core_dbs_info->cdbs, cs_tuners->sampling_rate))119119- modify_all = false;120120- else121121- dbs_check_cpu(dbs_data, cpu);110110+ if (modify_all)111111+ dbs_check_cpu(dbs_data, cdbs->shared->policy->cpu);122112123123- gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all);124124- mutex_unlock(&core_dbs_info->cdbs.timer_mutex);113113+ return delay_for_sampling_rate(cs_tuners->sampling_rate);125114}126115127116static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,···124135 if (!dbs_info->enable)125136 return 0;126137127127- policy = dbs_info->cdbs.cur_policy;138138+ policy = dbs_info->cdbs.shared->policy;128139129140 /*130141 * we only care if our internally tracked freq moves outside the 'valid'
+146-50
drivers/cpufreq/cpufreq_governor.c
···32323333void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)3434{3535- struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);3535+ struct cpu_dbs_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);3636 struct od_dbs_tuners *od_tuners = dbs_data->tuners;3737 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;3838- struct cpufreq_policy *policy;3838+ struct cpufreq_policy *policy = cdbs->shared->policy;3939 unsigned int sampling_rate;4040 unsigned int max_load = 0;4141 unsigned int ignore_nice;···6060 ignore_nice = cs_tuners->ignore_nice_load;6161 }62626363- policy = cdbs->cur_policy;6464-6563 /* Get Absolute Load */6664 for_each_cpu(j, policy->cpus) {6767- struct cpu_dbs_common_info *j_cdbs;6565+ struct cpu_dbs_info *j_cdbs;6866 u64 cur_wall_time, cur_idle_time;6967 unsigned int idle_time, wall_time;7068 unsigned int load;···161163static inline void __gov_queue_work(int cpu, struct dbs_data *dbs_data,162164 unsigned int delay)163165{164164- struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);166166+ struct cpu_dbs_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);165167166166- mod_delayed_work_on(cpu, system_wq, &cdbs->work, delay);168168+ mod_delayed_work_on(cpu, system_wq, &cdbs->dwork, delay);167169}168170169171void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,···197199static inline void gov_cancel_work(struct dbs_data *dbs_data,198200 struct cpufreq_policy *policy)199201{200200- struct cpu_dbs_common_info *cdbs;202202+ struct cpu_dbs_info *cdbs;201203 int i;202204203205 for_each_cpu(i, policy->cpus) {204206 cdbs = dbs_data->cdata->get_cpu_cdbs(i);205205- cancel_delayed_work_sync(&cdbs->work);207207+ cancel_delayed_work_sync(&cdbs->dwork);206208 }207209}208210209211/* Will return if we need to evaluate cpu load again or not */210210-bool need_load_eval(struct cpu_dbs_common_info *cdbs,211211- unsigned int sampling_rate)212212+static bool need_load_eval(struct cpu_common_dbs_info *shared,213213+ unsigned int sampling_rate)212214{213213- if (policy_is_shared(cdbs->cur_policy)) {215215+ if (policy_is_shared(shared->policy)) {214216 ktime_t time_now = ktime_get();215215- s64 delta_us = ktime_us_delta(time_now, cdbs->time_stamp);217217+ s64 delta_us = ktime_us_delta(time_now, shared->time_stamp);216218217219 /* Do nothing if we recently have sampled */218220 if (delta_us < (s64)(sampling_rate / 2))219221 return false;220222 else221221- cdbs->time_stamp = time_now;223223+ shared->time_stamp = time_now;222224 }223225224226 return true;225227}226226-EXPORT_SYMBOL_GPL(need_load_eval);228228+229229+static void dbs_timer(struct work_struct *work)230230+{231231+ struct cpu_dbs_info *cdbs = container_of(work, struct cpu_dbs_info,232232+ dwork.work);233233+ struct cpu_common_dbs_info *shared = cdbs->shared;234234+ struct cpufreq_policy *policy = shared->policy;235235+ struct dbs_data *dbs_data = policy->governor_data;236236+ unsigned int sampling_rate, delay;237237+ bool modify_all = true;238238+239239+ mutex_lock(&shared->timer_mutex);240240+241241+ if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {242242+ struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;243243+244244+ sampling_rate = cs_tuners->sampling_rate;245245+ } else {246246+ struct od_dbs_tuners *od_tuners = dbs_data->tuners;247247+248248+ sampling_rate = od_tuners->sampling_rate;249249+ }250250+251251+ if (!need_load_eval(cdbs->shared, sampling_rate))252252+ modify_all = false;253253+254254+ delay = dbs_data->cdata->gov_dbs_timer(cdbs, dbs_data, modify_all);255255+ gov_queue_work(dbs_data, policy, delay, modify_all);256256+257257+ mutex_unlock(&shared->timer_mutex);258258+}227259228260static void set_sampling_rate(struct dbs_data *dbs_data,229261 unsigned int sampling_rate)···267239 }268240}269241242242+static int alloc_common_dbs_info(struct cpufreq_policy *policy,243243+ struct common_dbs_data *cdata)244244+{245245+ struct cpu_common_dbs_info *shared;246246+ int j;247247+248248+ /* Allocate memory for the common information for policy->cpus */249249+ shared = kzalloc(sizeof(*shared), GFP_KERNEL);250250+ if (!shared)251251+ return -ENOMEM;252252+253253+ /* Set shared for all CPUs, online+offline */254254+ for_each_cpu(j, policy->related_cpus)255255+ cdata->get_cpu_cdbs(j)->shared = shared;256256+257257+ return 0;258258+}259259+260260+static void free_common_dbs_info(struct cpufreq_policy *policy,261261+ struct common_dbs_data *cdata)262262+{263263+ struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(policy->cpu);264264+ struct cpu_common_dbs_info *shared = cdbs->shared;265265+ int j;266266+267267+ for_each_cpu(j, policy->cpus)268268+ cdata->get_cpu_cdbs(j)->shared = NULL;269269+270270+ kfree(shared);271271+}272272+270273static int cpufreq_governor_init(struct cpufreq_policy *policy,271274 struct dbs_data *dbs_data,272275 struct common_dbs_data *cdata)···305246 unsigned int latency;306247 int ret;307248249249+ /* State should be equivalent to EXIT */250250+ if (policy->governor_data)251251+ return -EBUSY;252252+308253 if (dbs_data) {309254 if (WARN_ON(have_governor_per_policy()))310255 return -EINVAL;256256+257257+ ret = alloc_common_dbs_info(policy, cdata);258258+ if (ret)259259+ return ret;260260+311261 dbs_data->usage_count++;312262 policy->governor_data = dbs_data;313263 return 0;···326258 if (!dbs_data)327259 return -ENOMEM;328260261261+ ret = alloc_common_dbs_info(policy, cdata);262262+ if (ret)263263+ goto free_dbs_data;264264+329265 dbs_data->cdata = cdata;330266 dbs_data->usage_count = 1;331267332268 ret = cdata->init(dbs_data, !policy->governor->initialized);333269 if (ret)334334- goto free_dbs_data;270270+ goto free_common_dbs_info;335271336272 /* policy latency is in ns. Convert it to us first */337273 latency = policy->cpuinfo.transition_latency / 1000;···372300 }373301cdata_exit:374302 cdata->exit(dbs_data, !policy->governor->initialized);303303+free_common_dbs_info:304304+ free_common_dbs_info(policy, cdata);375305free_dbs_data:376306 kfree(dbs_data);377307 return ret;378308}379309380380-static void cpufreq_governor_exit(struct cpufreq_policy *policy,381381- struct dbs_data *dbs_data)310310+static int cpufreq_governor_exit(struct cpufreq_policy *policy,311311+ struct dbs_data *dbs_data)382312{383313 struct common_dbs_data *cdata = dbs_data->cdata;314314+ struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(policy->cpu);315315+316316+ /* State should be equivalent to INIT */317317+ if (!cdbs->shared || cdbs->shared->policy)318318+ return -EBUSY;384319385320 policy->governor_data = NULL;386321 if (!--dbs_data->usage_count) {···402323 cdata->exit(dbs_data, policy->governor->initialized == 1);403324 kfree(dbs_data);404325 }326326+327327+ free_common_dbs_info(policy, cdata);328328+ return 0;405329}406330407331static int cpufreq_governor_start(struct cpufreq_policy *policy,···412330{413331 struct common_dbs_data *cdata = dbs_data->cdata;414332 unsigned int sampling_rate, ignore_nice, j, cpu = policy->cpu;415415- struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu);333333+ struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu);334334+ struct cpu_common_dbs_info *shared = cdbs->shared;416335 int io_busy = 0;417336418337 if (!policy->cur)419338 return -EINVAL;339339+340340+ /* State should be equivalent to INIT */341341+ if (!shared || shared->policy)342342+ return -EBUSY;420343421344 if (cdata->governor == GOV_CONSERVATIVE) {422345 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;···436349 io_busy = od_tuners->io_is_busy;437350 }438351352352+ shared->policy = policy;353353+ shared->time_stamp = ktime_get();354354+ mutex_init(&shared->timer_mutex);355355+439356 for_each_cpu(j, policy->cpus) {440440- struct cpu_dbs_common_info *j_cdbs = cdata->get_cpu_cdbs(j);357357+ struct cpu_dbs_info *j_cdbs = cdata->get_cpu_cdbs(j);441358 unsigned int prev_load;442359443443- j_cdbs->cpu = j;444444- j_cdbs->cur_policy = policy;445360 j_cdbs->prev_cpu_idle =446361 get_cpu_idle_time(j, &j_cdbs->prev_cpu_wall, io_busy);447362···455366 if (ignore_nice)456367 j_cdbs->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];457368458458- mutex_init(&j_cdbs->timer_mutex);459459- INIT_DEFERRABLE_WORK(&j_cdbs->work, cdata->gov_dbs_timer);369369+ INIT_DEFERRABLE_WORK(&j_cdbs->dwork, dbs_timer);460370 }461371462372 if (cdata->governor == GOV_CONSERVATIVE) {···474386 od_ops->powersave_bias_init_cpu(cpu);475387 }476388477477- /* Initiate timer time stamp */478478- cpu_cdbs->time_stamp = ktime_get();479479-480389 gov_queue_work(dbs_data, policy, delay_for_sampling_rate(sampling_rate),481390 true);482391 return 0;483392}484393485485-static void cpufreq_governor_stop(struct cpufreq_policy *policy,486486- struct dbs_data *dbs_data)394394+static int cpufreq_governor_stop(struct cpufreq_policy *policy,395395+ struct dbs_data *dbs_data)487396{488397 struct common_dbs_data *cdata = dbs_data->cdata;489398 unsigned int cpu = policy->cpu;490490- struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu);399399+ struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu);400400+ struct cpu_common_dbs_info *shared = cdbs->shared;401401+402402+ /* State should be equivalent to START */403403+ if (!shared || !shared->policy)404404+ return -EBUSY;405405+406406+ gov_cancel_work(dbs_data, policy);491407492408 if (cdata->governor == GOV_CONSERVATIVE) {493409 struct cs_cpu_dbs_info_s *cs_dbs_info =···500408 cs_dbs_info->enable = 0;501409 }502410503503- gov_cancel_work(dbs_data, policy);504504-505505- mutex_destroy(&cpu_cdbs->timer_mutex);506506- cpu_cdbs->cur_policy = NULL;411411+ shared->policy = NULL;412412+ mutex_destroy(&shared->timer_mutex);413413+ return 0;507414}508415509509-static void cpufreq_governor_limits(struct cpufreq_policy *policy,510510- struct dbs_data *dbs_data)416416+static int cpufreq_governor_limits(struct cpufreq_policy *policy,417417+ struct dbs_data *dbs_data)511418{512419 struct common_dbs_data *cdata = dbs_data->cdata;513420 unsigned int cpu = policy->cpu;514514- struct cpu_dbs_common_info *cpu_cdbs = cdata->get_cpu_cdbs(cpu);421421+ struct cpu_dbs_info *cdbs = cdata->get_cpu_cdbs(cpu);515422516516- if (!cpu_cdbs->cur_policy)517517- return;423423+ /* State should be equivalent to START */424424+ if (!cdbs->shared || !cdbs->shared->policy)425425+ return -EBUSY;518426519519- mutex_lock(&cpu_cdbs->timer_mutex);520520- if (policy->max < cpu_cdbs->cur_policy->cur)521521- __cpufreq_driver_target(cpu_cdbs->cur_policy, policy->max,427427+ mutex_lock(&cdbs->shared->timer_mutex);428428+ if (policy->max < cdbs->shared->policy->cur)429429+ __cpufreq_driver_target(cdbs->shared->policy, policy->max,522430 CPUFREQ_RELATION_H);523523- else if (policy->min > cpu_cdbs->cur_policy->cur)524524- __cpufreq_driver_target(cpu_cdbs->cur_policy, policy->min,431431+ else if (policy->min > cdbs->shared->policy->cur)432432+ __cpufreq_driver_target(cdbs->shared->policy, policy->min,525433 CPUFREQ_RELATION_L);526434 dbs_check_cpu(dbs_data, cpu);527527- mutex_unlock(&cpu_cdbs->timer_mutex);435435+ mutex_unlock(&cdbs->shared->timer_mutex);436436+437437+ return 0;528438}529439530440int cpufreq_governor_dbs(struct cpufreq_policy *policy,531441 struct common_dbs_data *cdata, unsigned int event)532442{533443 struct dbs_data *dbs_data;534534- int ret = 0;444444+ int ret;535445536446 /* Lock governor to block concurrent initialization of governor */537447 mutex_lock(&cdata->mutex);···543449 else544450 dbs_data = cdata->gdbs_data;545451546546- if (WARN_ON(!dbs_data && (event != CPUFREQ_GOV_POLICY_INIT))) {452452+ if (!dbs_data && (event != CPUFREQ_GOV_POLICY_INIT)) {547453 ret = -EINVAL;548454 goto unlock;549455 }···553459 ret = cpufreq_governor_init(policy, dbs_data, cdata);554460 break;555461 case CPUFREQ_GOV_POLICY_EXIT:556556- cpufreq_governor_exit(policy, dbs_data);462462+ ret = cpufreq_governor_exit(policy, dbs_data);557463 break;558464 case CPUFREQ_GOV_START:559465 ret = cpufreq_governor_start(policy, dbs_data);560466 break;561467 case CPUFREQ_GOV_STOP:562562- cpufreq_governor_stop(policy, dbs_data);468468+ ret = cpufreq_governor_stop(policy, dbs_data);563469 break;564470 case CPUFREQ_GOV_LIMITS:565565- cpufreq_governor_limits(policy, dbs_data);471471+ ret = cpufreq_governor_limits(policy, dbs_data);566472 break;473473+ default:474474+ ret = -EINVAL;567475 }568476569477unlock:
+22-18
drivers/cpufreq/cpufreq_governor.h
···109109110110/* create helper routines */111111#define define_get_cpu_dbs_routines(_dbs_info) \112112-static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu) \112112+static struct cpu_dbs_info *get_cpu_cdbs(int cpu) \113113{ \114114 return &per_cpu(_dbs_info, cpu).cdbs; \115115} \···128128 * cs_*: Conservative governor129129 */130130131131+/* Common to all CPUs of a policy */132132+struct cpu_common_dbs_info {133133+ struct cpufreq_policy *policy;134134+ /*135135+ * percpu mutex that serializes governor limit change with dbs_timer136136+ * invocation. We do not want dbs_timer to run when user is changing137137+ * the governor or limits.138138+ */139139+ struct mutex timer_mutex;140140+ ktime_t time_stamp;141141+};142142+131143/* Per cpu structures */132132-struct cpu_dbs_common_info {133133- int cpu;144144+struct cpu_dbs_info {134145 u64 prev_cpu_idle;135146 u64 prev_cpu_wall;136147 u64 prev_cpu_nice;···152141 * wake-up from idle.153142 */154143 unsigned int prev_load;155155- struct cpufreq_policy *cur_policy;156156- struct delayed_work work;157157- /*158158- * percpu mutex that serializes governor limit change with gov_dbs_timer159159- * invocation. We do not want gov_dbs_timer to run when user is changing160160- * the governor or limits.161161- */162162- struct mutex timer_mutex;163163- ktime_t time_stamp;144144+ struct delayed_work dwork;145145+ struct cpu_common_dbs_info *shared;164146};165147166148struct od_cpu_dbs_info_s {167167- struct cpu_dbs_common_info cdbs;149149+ struct cpu_dbs_info cdbs;168150 struct cpufreq_frequency_table *freq_table;169151 unsigned int freq_lo;170152 unsigned int freq_lo_jiffies;···167163};168164169165struct cs_cpu_dbs_info_s {170170- struct cpu_dbs_common_info cdbs;166166+ struct cpu_dbs_info cdbs;171167 unsigned int down_skip;172168 unsigned int requested_freq;173169 unsigned int enable:1;···208204 */209205 struct dbs_data *gdbs_data;210206211211- struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu);207207+ struct cpu_dbs_info *(*get_cpu_cdbs)(int cpu);212208 void *(*get_cpu_dbs_info_s)(int cpu);213213- void (*gov_dbs_timer)(struct work_struct *work);209209+ unsigned int (*gov_dbs_timer)(struct cpu_dbs_info *cdbs,210210+ struct dbs_data *dbs_data,211211+ bool modify_all);214212 void (*gov_check_cpu)(int cpu, unsigned int load);215213 int (*init)(struct dbs_data *dbs_data, bool notify);216214 void (*exit)(struct dbs_data *dbs_data, bool notify);···271265extern struct mutex cpufreq_governor_lock;272266273267void dbs_check_cpu(struct dbs_data *dbs_data, int cpu);274274-bool need_load_eval(struct cpu_dbs_common_info *cdbs,275275- unsigned int sampling_rate);276268int cpufreq_governor_dbs(struct cpufreq_policy *policy,277269 struct common_dbs_data *cdata, unsigned int event);278270void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
···228228229229extern int acpi_processor_register_performance(struct acpi_processor_performance230230 *performance, unsigned int cpu);231231-extern void acpi_processor_unregister_performance(struct232232- acpi_processor_performance233233- *performance,234234- unsigned int cpu);231231+extern void acpi_processor_unregister_performance(unsigned int cpu);235232236233/* note: this locks both the calling module and the processor module237234 if a _PPC object exists, rmmod is disallowed then */