Hi Tejun, Today's linux-next merge of the workqueues tree got a conflict in drivers/cpufreq/powernow-k8.c between commit e1f0b8e9b04a ("cpufreq: Remove support for hardware P-state chips from powernow-k8") from the pm tree and commit 5d7efe7bf90f ("cpufreq/powernow-k8: workqueue user shouldn't migrate the kworker to another CPU") from the workqueues tree. I fixed it up (I think - see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx diff --cc drivers/cpufreq/powernow-k8.c index 0b19faf,1a40935..0000000 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@@ -978,11 -1104,52 +977,18 @@@ static int transition_frequency_fidvid( return res; } - /* Driver entry point to switch to the target frequency */ - static int powernowk8_target(struct cpufreq_policy *pol, - unsigned targfreq, unsigned relation) -/* Take a frequency, and issue the hardware pstate transition command */ -static int transition_frequency_pstate(struct powernow_k8_data *data, - unsigned int index) -{ - u32 pstate = 0; - int res, i; - struct cpufreq_freqs freqs; - - pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); - - /* get MSR index for hardware pstate transition */ - pstate = index & HW_PSTATE_MASK; - if (pstate > data->max_hw_pstate) - return -EINVAL; - - freqs.old = find_khz_freq_from_pstate(data->powernow_table, - data->currpstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - res = transition_pstate(data, pstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - return res; -} - + struct powernowk8_target_arg { + struct cpufreq_policy *pol; + unsigned targfreq; + unsigned relation; + }; + + static long powernowk8_target_fn(void *arg) { - cpumask_var_t oldmask; + struct powernowk8_target_arg *pta = arg; + struct cpufreq_policy *pol = pta->pol; + unsigned targfreq = pta->targfreq; + unsigned relation = pta->relation; struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); u32 checkfid; u32 checkvid; @@@ -1017,17 -1171,20 +1010,17 @@@ pol->cpu, targfreq, pol->min, pol->max, relation); if (query_current_values_with_pending_wait(data)) - goto err_out; + return -EIO; - if (cpu_family != CPU_HW_PSTATE) { - pr_debug("targ: curr fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); + pr_debug("targ: curr fid 0x%x, vid 0x%x\n", + data->currfid, data->currvid); - if ((checkvid != data->currvid) || - (checkfid != data->currfid)) { - printk(KERN_INFO PFX - "error - out of sync, fix 0x%x 0x%x, " - "vid 0x%x 0x%x\n", - checkfid, data->currfid, - checkvid, data->currvid); - } + if ((checkvid != data->currvid) || + (checkfid != data->currfid)) { + pr_info(PFX + "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", + checkfid, data->currfid, + checkvid, data->currvid); } if (cpufreq_frequency_table_target(pol, data->powernow_table, @@@ -1038,23 -1195,42 +1031,35 @@@ powernow_k8_acpi_pst_values(data, newstate); - if (cpu_family == CPU_HW_PSTATE) - ret = transition_frequency_pstate(data, - data->powernow_table[newstate].index); - else - ret = transition_frequency_fidvid(data, newstate); + ret = transition_frequency_fidvid(data, newstate); + if (ret) { printk(KERN_ERR PFX "transition frequency failed\n"); - ret = 1; mutex_unlock(&fidvid_mutex); - goto err_out; + return 1; } mutex_unlock(&fidvid_mutex); - if (cpu_family == CPU_HW_PSTATE) - pol->cur = find_khz_freq_from_pstate(data->powernow_table, - data->powernow_table[newstate].index); - else - pol->cur = find_khz_freq_from_fid(data->currfid); + pol->cur = find_khz_freq_from_fid(data->currfid); - ret = 0; - err_out: - set_cpus_allowed_ptr(current, oldmask); - free_cpumask_var(oldmask); - return ret; + return 0; + } + + /* Driver entry point to switch to the target frequency */ + static int powernowk8_target(struct cpufreq_policy *pol, + unsigned targfreq, unsigned relation) + { + struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, + .relation = relation }; + + /* + * Must run on @pol->cpu. cpufreq core is responsible for ensuring + * that we're bound to the current CPU and pol->cpu stays online. + */ + if (smp_processor_id() == pol->cpu) + return powernowk8_target_fn(&pta); + else + return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); } /* Driver entry point to verify the policy and range of frequencies */
Attachment:
pgpfG0FWHZgDS.pgp
Description: PGP signature