Skip to content

Commit 6c6ca9c

Browse files
committed
Merge tag 'pm+acpi-3.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "A bunch of regression fixes this time. They fix two regressions in the PNP subsystem, one in the ACPI processor driver and one in the ACPI EC driver, four cpufreq driver regressions and an unrelated bug in one of the drivers. The regressions are recent or introduced in 3.14. Specifics: - There are two bugs in the ACPI PNP core that cause errors to be returned if optional ACPI methods are not present. After an ACPI core change made in 3.14 one of those errors leads to serial port suspend failures on some systems. Fix from Rafael J Wysocki. - A recently added PNP quirk related to Intel chipsets intorduced a build error in unusual configurations (PNP without PCI). Fix from Bjorn Helgaas. - An ACPI EC workaround related to system suspend on Samsung machines added in 3.14 introduced a race causing some valid EC events to be discarded. Fix from Kieran Clancy. - The acpi-cpufreq driver fails to load on some systems after a 3.14 commit related to APIC ID parsing that overlooked one corner case. Fix from Lan Tianyu. - Fix for a recently introduced build problem in the ppc-corenet cpufreq driver from Tim Gardner. - A recent cpufreq core change to ensure serialization of frequency transitions for drivers with a ->target_index() callback overlooked the fact that some of those drivers had been doing operations introduced by it into the core already by themselves. That resulted in a mess in which the core and the drivers try to do the same thing and block each other which leads to deadlocks. Fixes for the powernow-k7, powernow-k6, and longhaul cpufreq drivers from Srivatsa S Bhat. - Fix for a computational error in the powernow-k6 cpufreq driver from Srivatsa S Bhat" * tag 'pm+acpi-3.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / processor: Fix failure of loading acpi-cpufreq driver PNP / ACPI: Do not return errors if _DIS or _SRS are not present PNP: Fix compile error in quirks.c ACPI / EC: Process rather than discard events in acpi_ec_clear cpufreq: ppc-corenet-cpufreq: Fix __udivdi3 modpost error cpufreq: powernow-k7: Fix double invocation of cpufreq_freq_transition_begin/end cpufreq: powernow-k6: Fix double invocation of cpufreq_freq_transition_begin/end cpufreq: powernow-k6: Fix incorrect comparison with max_multipler cpufreq: longhaul: Fix double invocation of cpufreq_freq_transition_begin/end
2 parents e981e79 + de3afce commit 6c6ca9c

File tree

8 files changed

+85
-59
lines changed

8 files changed

+85
-59
lines changed

drivers/acpi/acpi_processor.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
170170
acpi_status status;
171171
int ret;
172172

173+
if (pr->apic_id == -1)
174+
return -ENODEV;
175+
173176
status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
174177
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
175178
return -ENODEV;
@@ -260,10 +263,8 @@ static int acpi_processor_get_info(struct acpi_device *device)
260263
}
261264

262265
apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
263-
if (apic_id < 0) {
266+
if (apic_id < 0)
264267
acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n");
265-
return -ENODEV;
266-
}
267268
pr->apic_id = apic_id;
268269

269270
cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);

drivers/acpi/ec.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,13 @@ static void advance_transaction(struct acpi_ec *ec, u8 status)
206206
spin_unlock_irqrestore(&ec->lock, flags);
207207
}
208208

209-
static int acpi_ec_sync_query(struct acpi_ec *ec);
209+
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
210210

211211
static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
212212
{
213213
if (state & ACPI_EC_FLAG_SCI) {
214214
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
215-
return acpi_ec_sync_query(ec);
215+
return acpi_ec_sync_query(ec, NULL);
216216
}
217217
return 0;
218218
}
@@ -443,10 +443,8 @@ acpi_handle ec_get_handle(void)
443443

444444
EXPORT_SYMBOL(ec_get_handle);
445445

446-
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data);
447-
448446
/*
449-
* Clears stale _Q events that might have accumulated in the EC.
447+
* Process _Q events that might have accumulated in the EC.
450448
* Run with locked ec mutex.
451449
*/
452450
static void acpi_ec_clear(struct acpi_ec *ec)
@@ -455,7 +453,7 @@ static void acpi_ec_clear(struct acpi_ec *ec)
455453
u8 value = 0;
456454

457455
for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
458-
status = acpi_ec_query_unlocked(ec, &value);
456+
status = acpi_ec_sync_query(ec, &value);
459457
if (status || !value)
460458
break;
461459
}
@@ -582,13 +580,18 @@ static void acpi_ec_run(void *cxt)
582580
kfree(handler);
583581
}
584582

585-
static int acpi_ec_sync_query(struct acpi_ec *ec)
583+
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
586584
{
587585
u8 value = 0;
588586
int status;
589587
struct acpi_ec_query_handler *handler, *copy;
590-
if ((status = acpi_ec_query_unlocked(ec, &value)))
588+
589+
status = acpi_ec_query_unlocked(ec, &value);
590+
if (data)
591+
*data = value;
592+
if (status)
591593
return status;
594+
592595
list_for_each_entry(handler, &ec->list, node) {
593596
if (value == handler->query_bit) {
594597
/* have custom handler for this bit */
@@ -612,7 +615,7 @@ static void acpi_ec_gpe_query(void *ec_cxt)
612615
if (!ec)
613616
return;
614617
mutex_lock(&ec->mutex);
615-
acpi_ec_sync_query(ec);
618+
acpi_ec_sync_query(ec, NULL);
616619
mutex_unlock(&ec->mutex);
617620
}
618621

drivers/cpufreq/longhaul.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static void do_powersaver(int cx_address, unsigned int mults_index,
242242
* Sets a new clock ratio.
243243
*/
244244

245-
static void longhaul_setstate(struct cpufreq_policy *policy,
245+
static int longhaul_setstate(struct cpufreq_policy *policy,
246246
unsigned int table_index)
247247
{
248248
unsigned int mults_index;
@@ -258,19 +258,19 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
258258
/* Safety precautions */
259259
mult = mults[mults_index & 0x1f];
260260
if (mult == -1)
261-
return;
261+
return -EINVAL;
262+
262263
speed = calc_speed(mult);
263264
if ((speed > highest_speed) || (speed < lowest_speed))
264-
return;
265+
return -EINVAL;
266+
265267
/* Voltage transition before frequency transition? */
266268
if (can_scale_voltage && longhaul_index < table_index)
267269
dir = 1;
268270

269271
freqs.old = calc_speed(longhaul_get_cpu_mult());
270272
freqs.new = speed;
271273

272-
cpufreq_freq_transition_begin(policy, &freqs);
273-
274274
pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
275275
fsb, mult/10, mult%10, print_speed(speed/1000));
276276
retry_loop:
@@ -385,12 +385,14 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
385385
goto retry_loop;
386386
}
387387
}
388-
/* Report true CPU frequency */
389-
cpufreq_freq_transition_end(policy, &freqs, 0);
390388

391-
if (!bm_timeout)
389+
if (!bm_timeout) {
392390
printk(KERN_INFO PFX "Warning: Timeout while waiting for "
393391
"idle PCI bus.\n");
392+
return -EBUSY;
393+
}
394+
395+
return 0;
394396
}
395397

396398
/*
@@ -631,9 +633,10 @@ static int longhaul_target(struct cpufreq_policy *policy,
631633
unsigned int i;
632634
unsigned int dir = 0;
633635
u8 vid, current_vid;
636+
int retval = 0;
634637

635638
if (!can_scale_voltage)
636-
longhaul_setstate(policy, table_index);
639+
retval = longhaul_setstate(policy, table_index);
637640
else {
638641
/* On test system voltage transitions exceeding single
639642
* step up or down were turning motherboard off. Both
@@ -648,7 +651,7 @@ static int longhaul_target(struct cpufreq_policy *policy,
648651
while (i != table_index) {
649652
vid = (longhaul_table[i].driver_data >> 8) & 0x1f;
650653
if (vid != current_vid) {
651-
longhaul_setstate(policy, i);
654+
retval = longhaul_setstate(policy, i);
652655
current_vid = vid;
653656
msleep(200);
654657
}
@@ -657,10 +660,11 @@ static int longhaul_target(struct cpufreq_policy *policy,
657660
else
658661
i--;
659662
}
660-
longhaul_setstate(policy, table_index);
663+
retval = longhaul_setstate(policy, table_index);
661664
}
665+
662666
longhaul_index = table_index;
663-
return 0;
667+
return retval;
664668
}
665669

666670

@@ -968,7 +972,15 @@ static void __exit longhaul_exit(void)
968972

969973
for (i = 0; i < numscales; i++) {
970974
if (mults[i] == maxmult) {
975+
struct cpufreq_freqs freqs;
976+
977+
freqs.old = policy->cur;
978+
freqs.new = longhaul_table[i].frequency;
979+
freqs.flags = 0;
980+
981+
cpufreq_freq_transition_begin(policy, &freqs);
971982
longhaul_setstate(policy, i);
983+
cpufreq_freq_transition_end(policy, &freqs, 0);
972984
break;
973985
}
974986
}

drivers/cpufreq/powernow-k6.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,14 @@ static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
138138
static int powernow_k6_target(struct cpufreq_policy *policy,
139139
unsigned int best_i)
140140
{
141-
struct cpufreq_freqs freqs;
142141

143142
if (clock_ratio[best_i].driver_data > max_multiplier) {
144143
printk(KERN_ERR PFX "invalid target frequency\n");
145144
return -EINVAL;
146145
}
147146

148-
freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
149-
freqs.new = busfreq * clock_ratio[best_i].driver_data;
150-
151-
cpufreq_freq_transition_begin(policy, &freqs);
152-
153147
powernow_k6_set_cpu_multiplier(best_i);
154148

155-
cpufreq_freq_transition_end(policy, &freqs, 0);
156-
157149
return 0;
158150
}
159151

@@ -227,9 +219,20 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
227219
static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
228220
{
229221
unsigned int i;
230-
for (i = 0; i < 8; i++) {
231-
if (i == max_multiplier)
222+
223+
for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
224+
if (clock_ratio[i].driver_data == max_multiplier) {
225+
struct cpufreq_freqs freqs;
226+
227+
freqs.old = policy->cur;
228+
freqs.new = clock_ratio[i].frequency;
229+
freqs.flags = 0;
230+
231+
cpufreq_freq_transition_begin(policy, &freqs);
232232
powernow_k6_target(policy, i);
233+
cpufreq_freq_transition_end(policy, &freqs, 0);
234+
break;
235+
}
233236
}
234237
return 0;
235238
}

drivers/cpufreq/powernow-k7.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
269269

270270
freqs.new = powernow_table[index].frequency;
271271

272-
cpufreq_freq_transition_begin(policy, &freqs);
273-
274272
/* Now do the magic poking into the MSRs. */
275273

276274
if (have_a0 == 1) /* A0 errata 5 */
@@ -290,8 +288,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
290288
if (have_a0 == 1)
291289
local_irq_enable();
292290

293-
cpufreq_freq_transition_end(policy, &freqs, 0);
294-
295291
return 0;
296292
}
297293

drivers/cpufreq/ppc-corenet-cpufreq.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
138138
struct cpufreq_frequency_table *table;
139139
struct cpu_data *data;
140140
unsigned int cpu = policy->cpu;
141+
u64 transition_latency_hz;
141142

142143
np = of_get_cpu_node(cpu, NULL);
143144
if (!np)
@@ -205,8 +206,10 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
205206
for_each_cpu(i, per_cpu(cpu_mask, cpu))
206207
per_cpu(cpu_data, i) = data;
207208

209+
transition_latency_hz = 12ULL * NSEC_PER_SEC;
208210
policy->cpuinfo.transition_latency =
209-
(12ULL * NSEC_PER_SEC) / fsl_get_sys_freq();
211+
do_div(transition_latency_hz, fsl_get_sys_freq());
212+
210213
of_node_put(np);
211214

212215
return 0;

drivers/pnp/pnpacpi/core.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
8383
{
8484
struct acpi_device *acpi_dev;
8585
acpi_handle handle;
86-
struct acpi_buffer buffer;
87-
int ret;
86+
int ret = 0;
8887

8988
pnp_dbg(&dev->dev, "set resources\n");
9089

@@ -97,27 +96,34 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
9796
if (WARN_ON_ONCE(acpi_dev != dev->data))
9897
dev->data = acpi_dev;
9998

100-
ret = pnpacpi_build_resource_template(dev, &buffer);
101-
if (ret)
102-
return ret;
103-
ret = pnpacpi_encode_resources(dev, &buffer);
104-
if (ret) {
99+
if (acpi_has_method(handle, METHOD_NAME__SRS)) {
100+
struct acpi_buffer buffer;
101+
102+
ret = pnpacpi_build_resource_template(dev, &buffer);
103+
if (ret)
104+
return ret;
105+
106+
ret = pnpacpi_encode_resources(dev, &buffer);
107+
if (!ret) {
108+
acpi_status status;
109+
110+
status = acpi_set_current_resources(handle, &buffer);
111+
if (ACPI_FAILURE(status))
112+
ret = -EIO;
113+
}
105114
kfree(buffer.pointer);
106-
return ret;
107115
}
108-
if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
109-
ret = -EINVAL;
110-
else if (acpi_bus_power_manageable(handle))
116+
if (!ret && acpi_bus_power_manageable(handle))
111117
ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
112-
kfree(buffer.pointer);
118+
113119
return ret;
114120
}
115121

116122
static int pnpacpi_disable_resources(struct pnp_dev *dev)
117123
{
118124
struct acpi_device *acpi_dev;
119125
acpi_handle handle;
120-
int ret;
126+
acpi_status status;
121127

122128
dev_dbg(&dev->dev, "disable resources\n");
123129

@@ -128,13 +134,15 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
128134
}
129135

130136
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
131-
ret = 0;
132137
if (acpi_bus_power_manageable(handle))
133138
acpi_bus_set_power(handle, ACPI_STATE_D3_COLD);
134-
/* continue even if acpi_bus_set_power() fails */
135-
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
136-
ret = -ENODEV;
137-
return ret;
139+
140+
/* continue even if acpi_bus_set_power() fails */
141+
status = acpi_evaluate_object(handle, "_DIS", NULL, NULL);
142+
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
143+
return -ENODEV;
144+
145+
return 0;
138146
}
139147

140148
#ifdef CONFIG_ACPI_SLEEP

drivers/pnp/quirks.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
335335
}
336336
#endif
337337

338-
#ifdef CONFIG_X86
338+
#ifdef CONFIG_PCI
339339
/* Device IDs of parts that have 32KB MCH space */
340340
static const unsigned int mch_quirk_devices[] = {
341341
0x0154, /* Ivy Bridge */
@@ -440,7 +440,7 @@ static struct pnp_fixup pnp_fixups[] = {
440440
#ifdef CONFIG_AMD_NB
441441
{"PNP0c01", quirk_amd_mmconfig_area},
442442
#endif
443-
#ifdef CONFIG_X86
443+
#ifdef CONFIG_PCI
444444
{"PNP0c02", quirk_intel_mch},
445445
#endif
446446
{""}

0 commit comments

Comments
 (0)