diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-02-07 15:12:21 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-02-07 15:12:21 -0500 |
| commit | 22446d3f23dd250ed1922edc8cc8a003bcb2538e (patch) | |
| tree | e13cb0713f382d27f5d932ac80cdfecf933a82e1 | |
| parent | 9343224bfd4be6a02e6ae0c0d66426c955c7d76e (diff) | |
| parent | a2ff34c433932e201ea3c5081335f3beeb2509bd (diff) | |
Merge tag 'pm+acpi-3.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki:
"These include a fix for a recent ACPI hotplug regression, four
concurrency related fixes and one PCI device removal fix for
ACPI-based PCI hotplug (ACPIPHP), intel_pstate fix that should go into
stable, three simple ACPI cleanups and a new entry for the ACPI video
blacklist.
Specifics:
- Fix for a recent ACPI hotplug regression causing a NULL pointer
dereference to occur while handling ACPI eject notifications for
already ejected devices. From Toshi Kani.
- Four concurrency-related fixes for ACPIPHP. Two of them add
missing locking and the other two fix race conditions related to
reference counting.
- ACPIPHP fix to avoid NULL pointer dereferences during device
removal involving Virtual Funcions.
- intel_pstate fix to make it compute the percentage of time the CPU
is busy properly. From Dirk Brandewie.
- Removal of two unnecessary NULL pointer checks in ACPI code and a
fix for sscanf() format string from Dan Carpenter and Luis G.F.
- New ACPI video blacklist entry for HP EliteBook Revolve 810 from
Mika Westerberg"
* tag 'pm+acpi-3.14-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI / hotplug: Fix panic on eject to ejected device
ACPI / battery: Fix incorrect sscanf() string in acpi_battery_init_alarm()
ACPI / proc: remove unneeded NULL check
ACPI / utils: remove a pointless NULL check
ACPI / video: Add HP EliteBook Revolve 810 to the blacklist
intel_pstate: Take core C0 time into account for core busy calculation
ACPI / hotplug / PCI: Fix bridge removal race vs dock events
ACPI / hotplug / PCI: Fix bridge removal race in handle_hotplug_event()
ACPI / hotplug / PCI: Scan root bus under the PCI rescan-remove lock
ACPI / hotplug / PCI: Move PCI rescan-remove locking to hotplug_event()
ACPI / hotplug / PCI: Remove entries from bus->devices in reverse order
| -rw-r--r-- | drivers/acpi/battery.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/proc.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 6 | ||||
| -rw-r--r-- | drivers/acpi/utils.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/video_detect.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 21 | ||||
| -rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 55 |
7 files changed, 75 insertions, 23 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 470e7542bf31..018a42883706 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -549,7 +549,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
| 549 | { | 549 | { |
| 550 | unsigned long x; | 550 | unsigned long x; |
| 551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); | 551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
| 552 | if (sscanf(buf, "%ld\n", &x) == 1) | 552 | if (sscanf(buf, "%lu\n", &x) == 1) |
| 553 | battery->alarm = x/1000; | 553 | battery->alarm = x/1000; |
| 554 | if (acpi_battery_present(battery)) | 554 | if (acpi_battery_present(battery)) |
| 555 | acpi_battery_set_alarm(battery); | 555 | acpi_battery_set_alarm(battery); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 50fe34ffe932..75c28eae8860 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
| @@ -60,7 +60,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
| 60 | seq_printf(seq, "%c%-8s %s:%s\n", | 60 | seq_printf(seq, "%c%-8s %s:%s\n", |
| 61 | dev->wakeup.flags.run_wake ? '*' : ' ', | 61 | dev->wakeup.flags.run_wake ? '*' : ' ', |
| 62 | (device_may_wakeup(&dev->dev) || | 62 | (device_may_wakeup(&dev->dev) || |
| 63 | (ldev && device_may_wakeup(ldev))) ? | 63 | device_may_wakeup(ldev)) ? |
| 64 | "enabled" : "disabled", | 64 | "enabled" : "disabled", |
| 65 | ldev->bus ? ldev->bus->name : | 65 | ldev->bus ? ldev->bus->name : |
| 66 | "no-bus", dev_name(ldev)); | 66 | "no-bus", dev_name(ldev)); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7384158c7f87..57b053f424d1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -484,7 +484,6 @@ static void acpi_device_hotplug(void *data, u32 src) | |||
| 484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
| 485 | { | 485 | { |
| 486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
| 487 | struct acpi_scan_handler *handler = data; | ||
| 488 | struct acpi_device *adev; | 487 | struct acpi_device *adev; |
| 489 | acpi_status status; | 488 | acpi_status status; |
| 490 | 489 | ||
| @@ -500,7 +499,10 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
| 500 | break; | 499 | break; |
| 501 | case ACPI_NOTIFY_EJECT_REQUEST: | 500 | case ACPI_NOTIFY_EJECT_REQUEST: |
| 502 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 501 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
| 503 | if (!handler->hotplug.enabled) { | 502 | if (!adev->handler) |
| 503 | goto err_out; | ||
| 504 | |||
| 505 | if (!adev->handler->hotplug.enabled) { | ||
| 504 | acpi_handle_err(handle, "Eject disabled\n"); | 506 | acpi_handle_err(handle, "Eject disabled\n"); |
| 505 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 507 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; |
| 506 | goto err_out; | 508 | goto err_out; |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 0347a37eb438..85e3b612bdc0 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
| @@ -99,10 +99,6 @@ acpi_extract_package(union acpi_object *package, | |||
| 99 | 99 | ||
| 100 | union acpi_object *element = &(package->package.elements[i]); | 100 | union acpi_object *element = &(package->package.elements[i]); |
| 101 | 101 | ||
| 102 | if (!element) { | ||
| 103 | return AE_BAD_DATA; | ||
| 104 | } | ||
| 105 | |||
| 106 | switch (element->type) { | 102 | switch (element->type) { |
| 107 | 103 | ||
| 108 | case ACPI_TYPE_INTEGER: | 104 | case ACPI_TYPE_INTEGER: |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index f0447d3daf2c..a697b77b8865 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
| @@ -170,6 +170,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
| 170 | }, | 170 | }, |
| 171 | { | 171 | { |
| 172 | .callback = video_detect_force_vendor, | 172 | .callback = video_detect_force_vendor, |
| 173 | .ident = "HP EliteBook Revolve 810", | ||
| 174 | .matches = { | ||
| 175 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 176 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Revolve 810 G1"), | ||
| 177 | }, | ||
| 178 | }, | ||
| 179 | { | ||
| 180 | .callback = video_detect_force_vendor, | ||
| 173 | .ident = "Lenovo Yoga 13", | 181 | .ident = "Lenovo Yoga 13", |
| 174 | .matches = { | 182 | .matches = { |
| 175 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 183 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7e257b233602..79606f473f48 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -57,6 +57,7 @@ struct sample { | |||
| 57 | int32_t core_pct_busy; | 57 | int32_t core_pct_busy; |
| 58 | u64 aperf; | 58 | u64 aperf; |
| 59 | u64 mperf; | 59 | u64 mperf; |
| 60 | unsigned long long tsc; | ||
| 60 | int freq; | 61 | int freq; |
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| @@ -96,6 +97,7 @@ struct cpudata { | |||
| 96 | 97 | ||
| 97 | u64 prev_aperf; | 98 | u64 prev_aperf; |
| 98 | u64 prev_mperf; | 99 | u64 prev_mperf; |
| 100 | unsigned long long prev_tsc; | ||
| 99 | int sample_ptr; | 101 | int sample_ptr; |
| 100 | struct sample samples[SAMPLE_COUNT]; | 102 | struct sample samples[SAMPLE_COUNT]; |
| 101 | }; | 103 | }; |
| @@ -548,30 +550,41 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, | |||
| 548 | struct sample *sample) | 550 | struct sample *sample) |
| 549 | { | 551 | { |
| 550 | u64 core_pct; | 552 | u64 core_pct; |
| 551 | core_pct = div64_u64(int_tofp(sample->aperf * 100), | 553 | u64 c0_pct; |
| 552 | sample->mperf); | ||
| 553 | sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000); | ||
| 554 | 554 | ||
| 555 | sample->core_pct_busy = core_pct; | 555 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); |
| 556 | |||
| 557 | c0_pct = div64_u64(sample->mperf * 100, sample->tsc); | ||
| 558 | sample->freq = fp_toint( | ||
| 559 | mul_fp(int_tofp(cpu->pstate.max_pstate), | ||
| 560 | int_tofp(core_pct * 1000))); | ||
| 561 | |||
| 562 | sample->core_pct_busy = mul_fp(int_tofp(core_pct), | ||
| 563 | div_fp(int_tofp(c0_pct + 1), int_tofp(100))); | ||
| 556 | } | 564 | } |
| 557 | 565 | ||
| 558 | static inline void intel_pstate_sample(struct cpudata *cpu) | 566 | static inline void intel_pstate_sample(struct cpudata *cpu) |
| 559 | { | 567 | { |
| 560 | u64 aperf, mperf; | 568 | u64 aperf, mperf; |
| 569 | unsigned long long tsc; | ||
| 561 | 570 | ||
| 562 | rdmsrl(MSR_IA32_APERF, aperf); | 571 | rdmsrl(MSR_IA32_APERF, aperf); |
| 563 | rdmsrl(MSR_IA32_MPERF, mperf); | 572 | rdmsrl(MSR_IA32_MPERF, mperf); |
| 573 | tsc = native_read_tsc(); | ||
| 564 | 574 | ||
| 565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 575 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
| 566 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 576 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
| 567 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 577 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
| 578 | cpu->samples[cpu->sample_ptr].tsc = tsc; | ||
| 568 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; | 579 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; |
| 569 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; | 580 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; |
| 581 | cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; | ||
| 570 | 582 | ||
| 571 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); | 583 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); |
| 572 | 584 | ||
| 573 | cpu->prev_aperf = aperf; | 585 | cpu->prev_aperf = aperf; |
| 574 | cpu->prev_mperf = mperf; | 586 | cpu->prev_mperf = mperf; |
| 587 | cpu->prev_tsc = tsc; | ||
| 575 | } | 588 | } |
| 576 | 589 | ||
| 577 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 590 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cd929aed3613..e2a783fdb98f 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -210,10 +210,29 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) | |||
| 210 | } | 210 | } |
