Commit 478c7cf7a8ff7ad587bd76f8ce9cfeede0df45fb
Exists in
ti-lsk-linux-4.1.y
and in
12 other branches
Merge tag 'pm+acpi-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "Still fixing regressions (partly by reverting commits that broke things for people), fixing other stable-candidate bugs and adding some blacklist entries for ACPI video and _OSI. Two ACPICA regression fixes (one recent and one for a 3.14 commit), a fix for an ACPI-related regression in TPM (introduced in 3.14), a revert of the ACPI AC driver conversion in 3.13 that went wrong for an unknown reason, two reverts of commits that attempted to remove an old user space interface in /proc and broke some utilities, in 3.13 too, a fix for a CPU hotplug bug in the ACPI processor driver (stable material), two (stable candidate) fixes for intel_pstate and a few new blacklist entries, mostly for systems that shipped with Windows 8. Specifics: - ACPICA fix for a stale pointer access introduced by a recent commit in the XSDT validation code from Lv Zheng. - ACPICA fix for the default value of the command line switch to favor 32-bit FADT addresses (in case there's a conflict between a 64-bit and a 32-bit address). The previous default was that the 32-bit version would take precedence and we tried to change it to the other way around and it didn't work. From Lv Zheng. - A TPM commit related to ACPI _DSM in 3.14 caused the driver to refuse to load if a specific _DSM was missing and that broke resume from system suspend on Chromebooks that require the TPM hardware to be restored to a working state during resume by the OS. Restore the old behavior to load the driver if the _DSM in question is not present, but prevent it from using the feature the _DSM is for. - ACPI AC driver conversion in 3.13 broke thermal management on at least one machine and has to be reverted. From Guenter Roeck. - Two reverts of 3.13 commits that attempted to remove the old ACPI battery interface in /proc, but turned out to break some utilities still using that interface. From Lan Tianyu. - ACPI processor driver fix to prevent acpi_processor_add() from modifying the CPU device's .offline field which leads to breakage if the initial online of the CPU fails. From Igor Mammedov. - Two intel_pstate fixes, one to take a BayTrail documentation update into account and one to avoid forcing the maximum P-state on init which causes CPU PM trouble on systems with P-states coordination when one of the CPU cores is initialized after an offline/online cycle triggered by user space. Both stable candidates, from Dirk Brandewie. - Fix for the ACPI video DMI blacklist entry for Dell Inspiron 7520 from Aaron Lu. - Two new ACPI video blacklist entries for machines shipping with Win8 that need to use native backlight so that it can be controlled in a usual way (which doesn't work otherwise due bugs in the ACPI tables) from Hans de Goede. - Two ACPI _OSI quirks for systems that need them to work correctly with Linux from Edward Lin and Hans de Goede" * tag 'pm+acpi-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / video: Revert native brightness quirk for ThinkPad T530 intel_pstate: remove setting P state to MAX on init ACPICA: Tables: Restore old behavor to favor 32-bit FADT addresses. ACPI / video: correct DMI tag for Dell Inspiron 7520 intel_pstate: Set turbo VID for BayTrail ACPI / TPM: Fix resume regression on Chromebooks ACPI / proc: Do not say when /proc interfaces will be deleted in Kconfig ACPI / processor: do not mark present at boot but not onlined CPU as onlined ACPI: Revert "ACPI / AC: convert ACPI ac driver to platform bus" ACPI / blacklist: Add dmi_enable_osi_linux quirk for Asus EEE PC 1015PX ACPI: blacklist win8 OSI for Dell Inspiron 7737 ACPI / video: Add use_native_backlight quirks for more systems ACPI: Revert "ACPI / Battery: Remove battery's proc directory" ACPI: Revert "ACPI: Remove CONFIG_ACPI_PROCFS_POWER and cm_sbsc.c" ACPICA: Tables: Fix invalid pointer accesses in acpi_tb_parse_root_table().
Showing 13 changed files Side-by-side Diff
- drivers/acpi/Kconfig
- drivers/acpi/Makefile
- drivers/acpi/ac.c
- drivers/acpi/acpi_platform.c
- drivers/acpi/acpi_processor.c
- drivers/acpi/acpica/acglobal.h
- drivers/acpi/acpica/tbutils.c
- drivers/acpi/battery.c
- drivers/acpi/blacklist.c
- drivers/acpi/cm_sbs.c
- drivers/acpi/video.c
- drivers/char/tpm/tpm_ppi.c
- drivers/cpufreq/intel_pstate.c
drivers/acpi/Kconfig
... | ... | @@ -47,6 +47,23 @@ |
47 | 47 | depends on SUSPEND || HIBERNATION |
48 | 48 | default y |
49 | 49 | |
50 | +config ACPI_PROCFS_POWER | |
51 | + bool "Deprecated power /proc/acpi directories" | |
52 | + depends on PROC_FS | |
53 | + help | |
54 | + For backwards compatibility, this option allows | |
55 | + deprecated power /proc/acpi/ directories to exist, even when | |
56 | + they have been replaced by functions in /sys. | |
57 | + The deprecated directories (and their replacements) include: | |
58 | + /proc/acpi/battery/* (/sys/class/power_supply/*) | |
59 | + /proc/acpi/ac_adapter/* (sys/class/power_supply/*) | |
60 | + This option has no effect on /proc/acpi/ directories | |
61 | + and functions, which do not yet exist in /sys | |
62 | + This option, together with the proc directories, will be | |
63 | + deleted in the future. | |
64 | + | |
65 | + Say N to delete power /proc/acpi/ directories that have moved to /sys/ | |
66 | + | |
50 | 67 | config ACPI_EC_DEBUGFS |
51 | 68 | tristate "EC read/write access through /sys/kernel/debug/ec" |
52 | 69 | default n |
drivers/acpi/Makefile
drivers/acpi/ac.c
... | ... | @@ -52,11 +52,39 @@ |
52 | 52 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); |
53 | 53 | MODULE_LICENSE("GPL"); |
54 | 54 | |
55 | +static int acpi_ac_add(struct acpi_device *device); | |
56 | +static int acpi_ac_remove(struct acpi_device *device); | |
57 | +static void acpi_ac_notify(struct acpi_device *device, u32 event); | |
58 | + | |
59 | +static const struct acpi_device_id ac_device_ids[] = { | |
60 | + {"ACPI0003", 0}, | |
61 | + {"", 0}, | |
62 | +}; | |
63 | +MODULE_DEVICE_TABLE(acpi, ac_device_ids); | |
64 | + | |
65 | +#ifdef CONFIG_PM_SLEEP | |
66 | +static int acpi_ac_resume(struct device *dev); | |
67 | +#endif | |
68 | +static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | |
69 | + | |
55 | 70 | static int ac_sleep_before_get_state_ms; |
56 | 71 | |
72 | +static struct acpi_driver acpi_ac_driver = { | |
73 | + .name = "ac", | |
74 | + .class = ACPI_AC_CLASS, | |
75 | + .ids = ac_device_ids, | |
76 | + .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | |
77 | + .ops = { | |
78 | + .add = acpi_ac_add, | |
79 | + .remove = acpi_ac_remove, | |
80 | + .notify = acpi_ac_notify, | |
81 | + }, | |
82 | + .drv.pm = &acpi_ac_pm, | |
83 | +}; | |
84 | + | |
57 | 85 | struct acpi_ac { |
58 | 86 | struct power_supply charger; |
59 | - struct platform_device *pdev; | |
87 | + struct acpi_device * device; | |
60 | 88 | unsigned long long state; |
61 | 89 | struct notifier_block battery_nb; |
62 | 90 | }; |
63 | 91 | |
... | ... | @@ -69,10 +97,12 @@ |
69 | 97 | |
70 | 98 | static int acpi_ac_get_state(struct acpi_ac *ac) |
71 | 99 | { |
72 | - acpi_status status; | |
73 | - acpi_handle handle = ACPI_HANDLE(&ac->pdev->dev); | |
100 | + acpi_status status = AE_OK; | |
74 | 101 | |
75 | - status = acpi_evaluate_integer(handle, "_PSR", NULL, | |
102 | + if (!ac) | |
103 | + return -EINVAL; | |
104 | + | |
105 | + status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, | |
76 | 106 | &ac->state); |
77 | 107 | if (ACPI_FAILURE(status)) { |
78 | 108 | ACPI_EXCEPTION((AE_INFO, status, |
79 | 109 | |
... | ... | @@ -117,10 +147,9 @@ |
117 | 147 | Driver Model |
118 | 148 | -------------------------------------------------------------------------- */ |
119 | 149 | |
120 | -static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) | |
150 | +static void acpi_ac_notify(struct acpi_device *device, u32 event) | |
121 | 151 | { |
122 | - struct acpi_ac *ac = data; | |
123 | - struct acpi_device *adev; | |
152 | + struct acpi_ac *ac = acpi_driver_data(device); | |
124 | 153 | |
125 | 154 | if (!ac) |
126 | 155 | return; |
... | ... | @@ -143,11 +172,10 @@ |
143 | 172 | msleep(ac_sleep_before_get_state_ms); |
144 | 173 | |
145 | 174 | acpi_ac_get_state(ac); |
146 | - adev = ACPI_COMPANION(&ac->pdev->dev); | |
147 | - acpi_bus_generate_netlink_event(adev->pnp.device_class, | |
148 | - dev_name(&ac->pdev->dev), | |
149 | - event, (u32) ac->state); | |
150 | - acpi_notifier_call_chain(adev, event, (u32) ac->state); | |
175 | + acpi_bus_generate_netlink_event(device->pnp.device_class, | |
176 | + dev_name(&device->dev), event, | |
177 | + (u32) ac->state); | |
178 | + acpi_notifier_call_chain(device, event, (u32) ac->state); | |
151 | 179 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
152 | 180 | } |
153 | 181 | |
154 | 182 | |
155 | 183 | |
156 | 184 | |
157 | 185 | |
158 | 186 | |
159 | 187 | |
160 | 188 | |
161 | 189 | |
... | ... | @@ -192,49 +220,39 @@ |
192 | 220 | {}, |
193 | 221 | }; |
194 | 222 | |
195 | -static int acpi_ac_probe(struct platform_device *pdev) | |
223 | +static int acpi_ac_add(struct acpi_device *device) | |
196 | 224 | { |
197 | 225 | int result = 0; |
198 | 226 | struct acpi_ac *ac = NULL; |
199 | - struct acpi_device *adev; | |
200 | 227 | |
201 | - if (!pdev) | |
228 | + | |
229 | + if (!device) | |
202 | 230 | return -EINVAL; |
203 | 231 | |
204 | - adev = ACPI_COMPANION(&pdev->dev); | |
205 | - if (!adev) | |
206 | - return -ENODEV; | |
207 | - | |
208 | 232 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); |
209 | 233 | if (!ac) |
210 | 234 | return -ENOMEM; |
211 | 235 | |
212 | - strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); | |
213 | - strcpy(acpi_device_class(adev), ACPI_AC_CLASS); | |
214 | - ac->pdev = pdev; | |
215 | - platform_set_drvdata(pdev, ac); | |
236 | + ac->device = device; | |
237 | + strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | |
238 | + strcpy(acpi_device_class(device), ACPI_AC_CLASS); | |
239 | + device->driver_data = ac; | |
216 | 240 | |
217 | 241 | result = acpi_ac_get_state(ac); |
218 | 242 | if (result) |
219 | 243 | goto end; |
220 | 244 | |
221 | - ac->charger.name = acpi_device_bid(adev); | |
245 | + ac->charger.name = acpi_device_bid(device); | |
222 | 246 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; |
223 | 247 | ac->charger.properties = ac_props; |
224 | 248 | ac->charger.num_properties = ARRAY_SIZE(ac_props); |
225 | 249 | ac->charger.get_property = get_ac_property; |
226 | - result = power_supply_register(&pdev->dev, &ac->charger); | |
250 | + result = power_supply_register(&ac->device->dev, &ac->charger); | |
227 | 251 | if (result) |
228 | 252 | goto end; |
229 | 253 | |
230 | - result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), | |
231 | - ACPI_ALL_NOTIFY, acpi_ac_notify_handler, ac); | |
232 | - if (result) { | |
233 | - power_supply_unregister(&ac->charger); | |
234 | - goto end; | |
235 | - } | |
236 | 254 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
237 | - acpi_device_name(adev), acpi_device_bid(adev), | |
255 | + acpi_device_name(device), acpi_device_bid(device), | |
238 | 256 | ac->state ? "on-line" : "off-line"); |
239 | 257 | |
240 | 258 | ac->battery_nb.notifier_call = acpi_ac_battery_notify; |
... | ... | @@ -256,7 +274,7 @@ |
256 | 274 | if (!dev) |
257 | 275 | return -EINVAL; |
258 | 276 | |
259 | - ac = platform_get_drvdata(to_platform_device(dev)); | |
277 | + ac = acpi_driver_data(to_acpi_device(dev)); | |
260 | 278 | if (!ac) |
261 | 279 | return -EINVAL; |
262 | 280 | |
263 | 281 | |
264 | 282 | |
265 | 283 | |
266 | 284 | |
267 | 285 | |
... | ... | @@ -270,19 +288,17 @@ |
270 | 288 | #else |
271 | 289 | #define acpi_ac_resume NULL |
272 | 290 | #endif |
273 | -static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | |
274 | 291 | |
275 | -static int acpi_ac_remove(struct platform_device *pdev) | |
292 | +static int acpi_ac_remove(struct acpi_device *device) | |
276 | 293 | { |
277 | - struct acpi_ac *ac; | |
294 | + struct acpi_ac *ac = NULL; | |
278 | 295 | |
279 | - if (!pdev) | |
296 | + | |
297 | + if (!device || !acpi_driver_data(device)) | |
280 | 298 | return -EINVAL; |
281 | 299 | |
282 | - acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), | |
283 | - ACPI_ALL_NOTIFY, acpi_ac_notify_handler); | |
300 | + ac = acpi_driver_data(device); | |
284 | 301 | |
285 | - ac = platform_get_drvdata(pdev); | |
286 | 302 | if (ac->charger.dev) |
287 | 303 | power_supply_unregister(&ac->charger); |
288 | 304 | unregister_acpi_notifier(&ac->battery_nb); |
... | ... | @@ -292,23 +308,6 @@ |
292 | 308 | return 0; |
293 | 309 | } |
294 | 310 | |
295 | -static const struct acpi_device_id acpi_ac_match[] = { | |
296 | - { "ACPI0003", 0 }, | |
297 | - { } | |
298 | -}; | |
299 | -MODULE_DEVICE_TABLE(acpi, acpi_ac_match); | |
300 | - | |
301 | -static struct platform_driver acpi_ac_driver = { | |
302 | - .probe = acpi_ac_probe, | |
303 | - .remove = acpi_ac_remove, | |
304 | - .driver = { | |
305 | - .name = "acpi-ac", | |
306 | - .owner = THIS_MODULE, | |
307 | - .pm = &acpi_ac_pm_ops, | |
308 | - .acpi_match_table = ACPI_PTR(acpi_ac_match), | |
309 | - }, | |
310 | -}; | |
311 | - | |
312 | 311 | static int __init acpi_ac_init(void) |
313 | 312 | { |
314 | 313 | int result; |
... | ... | @@ -316,7 +315,7 @@ |
316 | 315 | if (acpi_disabled) |
317 | 316 | return -ENODEV; |
318 | 317 | |
319 | - result = platform_driver_register(&acpi_ac_driver); | |
318 | + result = acpi_bus_register_driver(&acpi_ac_driver); | |
320 | 319 | if (result < 0) |
321 | 320 | return -ENODEV; |
322 | 321 | |
... | ... | @@ -325,7 +324,7 @@ |
325 | 324 | |
326 | 325 | static void __exit acpi_ac_exit(void) |
327 | 326 | { |
328 | - platform_driver_unregister(&acpi_ac_driver); | |
327 | + acpi_bus_unregister_driver(&acpi_ac_driver); | |
329 | 328 | } |
330 | 329 | module_init(acpi_ac_init); |
331 | 330 | module_exit(acpi_ac_exit); |
drivers/acpi/acpi_platform.c
drivers/acpi/acpi_processor.c
drivers/acpi/acpica/acglobal.h
... | ... | @@ -141,9 +141,9 @@ |
141 | 141 | * address. Although ACPICA adheres to the ACPI specification which |
142 | 142 | * requires the use of the corresponding 64-bit address if it is non-zero, |
143 | 143 | * some machines have been found to have a corrupted non-zero 64-bit |
144 | - * address. Default is FALSE, do not favor the 32-bit addresses. | |
144 | + * address. Default is TRUE, favor the 32-bit addresses. | |
145 | 145 | */ |
146 | -ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, FALSE); | |
146 | +ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE); | |
147 | 147 | |
148 | 148 | /* |
149 | 149 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility |
drivers/acpi/acpica/tbutils.c
... | ... | @@ -461,6 +461,7 @@ |
461 | 461 | u32 table_count; |
462 | 462 | struct acpi_table_header *table; |
463 | 463 | acpi_physical_address address; |
464 | + acpi_physical_address rsdt_address; | |
464 | 465 | u32 length; |
465 | 466 | u8 *table_entry; |
466 | 467 | acpi_status status; |
467 | 468 | |
... | ... | @@ -488,11 +489,14 @@ |
488 | 489 | * as per the ACPI specification. |
489 | 490 | */ |
490 | 491 | address = (acpi_physical_address) rsdp->xsdt_physical_address; |
492 | + rsdt_address = | |
493 | + (acpi_physical_address) rsdp->rsdt_physical_address; | |
491 | 494 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; |
492 | 495 | } else { |
493 | 496 | /* Root table is an RSDT (32-bit physical addresses) */ |
494 | 497 | |
495 | 498 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
499 | + rsdt_address = address; | |
496 | 500 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
497 | 501 | } |
498 | 502 | |
... | ... | @@ -515,8 +519,7 @@ |
515 | 519 | |
516 | 520 | /* Fall back to the RSDT */ |
517 | 521 | |
518 | - address = | |
519 | - (acpi_physical_address) rsdp->rsdt_physical_address; | |
522 | + address = rsdt_address; | |
520 | 523 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
521 | 524 | } |
522 | 525 | } |
drivers/acpi/battery.c
... | ... | @@ -36,6 +36,12 @@ |
36 | 36 | #include <linux/suspend.h> |
37 | 37 | #include <asm/unaligned.h> |
38 | 38 | |
39 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
40 | +#include <linux/proc_fs.h> | |
41 | +#include <linux/seq_file.h> | |
42 | +#include <asm/uaccess.h> | |
43 | +#endif | |
44 | + | |
39 | 45 | #include <linux/acpi.h> |
40 | 46 | #include <linux/power_supply.h> |
41 | 47 | |
... | ... | @@ -64,6 +70,19 @@ |
64 | 70 | module_param(cache_time, uint, 0644); |
65 | 71 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
66 | 72 | |
73 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
74 | +extern struct proc_dir_entry *acpi_lock_battery_dir(void); | |
75 | +extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | |
76 | + | |
77 | +enum acpi_battery_files { | |
78 | + info_tag = 0, | |
79 | + state_tag, | |
80 | + alarm_tag, | |
81 | + ACPI_BATTERY_NUMFILES, | |
82 | +}; | |
83 | + | |
84 | +#endif | |
85 | + | |
67 | 86 | static const struct acpi_device_id battery_device_ids[] = { |
68 | 87 | {"PNP0C0A", 0}, |
69 | 88 | {"", 0}, |
... | ... | @@ -299,6 +318,14 @@ |
299 | 318 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
300 | 319 | }; |
301 | 320 | |
321 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
322 | +inline char *acpi_battery_units(struct acpi_battery *battery) | |
323 | +{ | |
324 | + return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? | |
325 | + "mA" : "mW"; | |
326 | +} | |
327 | +#endif | |
328 | + | |
302 | 329 | /* -------------------------------------------------------------------------- |
303 | 330 | Battery Management |
304 | 331 | -------------------------------------------------------------------------- */ |
... | ... | @@ -717,6 +744,279 @@ |
717 | 744 | } |
718 | 745 | |
719 | 746 | /* -------------------------------------------------------------------------- |
747 | + FS Interface (/proc) | |
748 | + -------------------------------------------------------------------------- */ | |
749 | + | |
750 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
751 | +static struct proc_dir_entry *acpi_battery_dir; | |
752 | + | |
753 | +static int acpi_battery_print_info(struct seq_file *seq, int result) | |
754 | +{ | |
755 | + struct acpi_battery *battery = seq->private; | |
756 | + | |
757 | + if (result) | |
758 | + goto end; | |
759 | + | |
760 | + seq_printf(seq, "present: %s\n", | |
761 | + acpi_battery_present(battery) ? "yes" : "no"); | |
762 | + if (!acpi_battery_present(battery)) | |
763 | + goto end; | |
764 | + if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | |
765 | + seq_printf(seq, "design capacity: unknown\n"); | |
766 | + else | |
767 | + seq_printf(seq, "design capacity: %d %sh\n", | |
768 | + battery->design_capacity, | |
769 | + acpi_battery_units(battery)); | |
770 | + | |
771 | + if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | |
772 | + seq_printf(seq, "last full capacity: unknown\n"); | |
773 | + else | |
774 | + seq_printf(seq, "last full capacity: %d %sh\n", | |
775 | + battery->full_charge_capacity, | |
776 | + acpi_battery_units(battery)); | |
777 | + | |
778 | + seq_printf(seq, "battery technology: %srechargeable\n", | |
779 | + (!battery->technology)?"non-":""); | |
780 | + | |
781 | + if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | |
782 | + seq_printf(seq, "design voltage: unknown\n"); | |
783 | + else | |
784 | + seq_printf(seq, "design voltage: %d mV\n", | |
785 | + battery->design_voltage); | |
786 | + seq_printf(seq, "design capacity warning: %d %sh\n", | |
787 | + battery->design_capacity_warning, | |
788 | + acpi_battery_units(battery)); | |
789 | + seq_printf(seq, "design capacity low: %d %sh\n", | |
790 | + battery->design_capacity_low, | |
791 | + acpi_battery_units(battery)); | |
792 | + seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | |
793 | + seq_printf(seq, "capacity granularity 1: %d %sh\n", | |
794 | + battery->capacity_granularity_1, | |
795 | + acpi_battery_units(battery)); | |
796 | + seq_printf(seq, "capacity granularity 2: %d %sh\n", | |
797 | + battery->capacity_granularity_2, | |
798 | + acpi_battery_units(battery)); | |
799 | + seq_printf(seq, "model number: %s\n", battery->model_number); | |
800 | + seq_printf(seq, "serial number: %s\n", battery->serial_number); | |
801 | + seq_printf(seq, "battery type: %s\n", battery->type); | |
802 | + seq_printf(seq, "OEM info: %s\n", battery->oem_info); | |
803 | + end: | |
804 | + if (result) | |
805 | + seq_printf(seq, "ERROR: Unable to read battery info\n"); | |
806 | + return result; | |
807 | +} | |
808 | + | |
809 | +static int acpi_battery_print_state(struct seq_file *seq, int result) | |
810 | +{ | |
811 | + struct acpi_battery *battery = seq->private; | |
812 | + | |
813 | + if (result) | |
814 | + goto end; | |
815 | + | |
816 | + seq_printf(seq, "present: %s\n", | |
817 | + acpi_battery_present(battery) ? "yes" : "no"); | |
818 | + if (!acpi_battery_present(battery)) | |
819 | + goto end; | |
820 | + | |
821 | + seq_printf(seq, "capacity state: %s\n", | |
822 | + (battery->state & 0x04) ? "critical" : "ok"); | |
823 | + if ((battery->state & 0x01) && (battery->state & 0x02)) | |
824 | + seq_printf(seq, | |
825 | + "charging state: charging/discharging\n"); | |
826 | + else if (battery->state & 0x01) | |
827 | + seq_printf(seq, "charging state: discharging\n"); | |
828 | + else if (battery->state & 0x02) | |
829 | + seq_printf(seq, "charging state: charging\n"); | |
830 | + else | |
831 | + seq_printf(seq, "charging state: charged\n"); | |
832 | + | |
833 | + if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) | |
834 | + seq_printf(seq, "present rate: unknown\n"); | |
835 | + else | |
836 | + seq_printf(seq, "present rate: %d %s\n", | |
837 | + battery->rate_now, acpi_battery_units(battery)); | |
838 | + | |
839 | + if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) | |
840 | + seq_printf(seq, "remaining capacity: unknown\n"); | |
841 | + else | |
842 | + seq_printf(seq, "remaining capacity: %d %sh\n", | |
843 | + battery->capacity_now, acpi_battery_units(battery)); | |
844 | + if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) | |
845 | + seq_printf(seq, "present voltage: unknown\n"); | |
846 | + else | |
847 | + seq_printf(seq, "present voltage: %d mV\n", | |
848 | + battery->voltage_now); | |
849 | + end: | |
850 | + if (result) | |
851 | + seq_printf(seq, "ERROR: Unable to read battery state\n"); | |
852 | + | |
853 | + return result; | |
854 | +} | |
855 | + | |
856 | +static int acpi_battery_print_alarm(struct seq_file *seq, int result) | |
857 | +{ | |
858 | + struct acpi_battery *battery = seq->private; | |
859 | + | |
860 | + if (result) | |
861 | + goto end; | |
862 | + | |
863 | + if (!acpi_battery_present(battery)) { | |
864 | + seq_printf(seq, "present: no\n"); | |
865 | + goto end; | |
866 | + } | |
867 | + seq_printf(seq, "alarm: "); | |
868 | + if (!battery->alarm) | |
869 | + seq_printf(seq, "unsupported\n"); | |
870 | + else | |
871 | + seq_printf(seq, "%u %sh\n", battery->alarm, | |
872 | + acpi_battery_units(battery)); | |
873 | + end: | |
874 | + if (result) | |
875 | + seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | |
876 | + return result; | |
877 | +} | |
878 | + | |
879 | +static ssize_t acpi_battery_write_alarm(struct file *file, | |
880 | + const char __user * buffer, | |
881 | + size_t count, loff_t * ppos) | |
882 | +{ | |
883 | + int result = 0; | |
884 | + char alarm_string[12] = { '\0' }; | |
885 | + struct seq_file *m = file->private_data; | |
886 | + struct acpi_battery *battery = m->private; | |
887 | + | |
888 | + if (!battery || (count > sizeof(alarm_string) - 1)) | |
889 | + return -EINVAL; | |
890 | + if (!acpi_battery_present(battery)) { | |
891 | + result = -ENODEV; | |
892 | + goto end; | |
893 | + } | |
894 | + if (copy_from_user(alarm_string, buffer, count)) { | |
895 | + result = -EFAULT; | |
896 | + goto end; | |
897 | + } | |
898 | + alarm_string[count] = '\0'; | |
899 | + battery->alarm = simple_strtol(alarm_string, NULL, 0); | |
900 | + result = acpi_battery_set_alarm(battery); | |
901 | + end: | |
902 | + if (!result) | |
903 | + return count; | |
904 | + return result; | |
905 | +} | |
906 | + | |
907 | +typedef int(*print_func)(struct seq_file *seq, int result); | |
908 | + | |
909 | +static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { | |
910 | + acpi_battery_print_info, | |
911 | + acpi_battery_print_state, | |
912 | + acpi_battery_print_alarm, | |
913 | +}; | |
914 | + | |
915 | +static int acpi_battery_read(int fid, struct seq_file *seq) | |
916 | +{ | |
917 | + struct acpi_battery *battery = seq->private; | |
918 | + int result = acpi_battery_update(battery); | |
919 | + return acpi_print_funcs[fid](seq, result); | |
920 | +} | |
921 | + | |
922 | +#define DECLARE_FILE_FUNCTIONS(_name) \ | |
923 | +static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ | |
924 | +{ \ | |
925 | + return acpi_battery_read(_name##_tag, seq); \ | |
926 | +} \ | |
927 | +static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ | |
928 | +{ \ | |
929 | + return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ | |
930 | +} | |
931 | + | |
932 | +DECLARE_FILE_FUNCTIONS(info); | |
933 | +DECLARE_FILE_FUNCTIONS(state); | |
934 | +DECLARE_FILE_FUNCTIONS(alarm); | |
935 | + | |
936 | +#undef DECLARE_FILE_FUNCTIONS | |
937 | + | |
938 | +#define FILE_DESCRIPTION_RO(_name) \ | |
939 | + { \ | |
940 | + .name = __stringify(_name), \ | |
941 | + .mode = S_IRUGO, \ | |
942 | + .ops = { \ | |
943 | + .open = acpi_battery_##_name##_open_fs, \ | |
944 | + .read = seq_read, \ | |
945 | + .llseek = seq_lseek, \ | |
946 | + .release = single_release, \ | |
947 | + .owner = THIS_MODULE, \ | |
948 | + }, \ | |
949 | + } | |
950 | + | |
951 | +#define FILE_DESCRIPTION_RW(_name) \ | |
952 | + { \ | |
953 | + .name = __stringify(_name), \ | |
954 | + .mode = S_IFREG | S_IRUGO | S_IWUSR, \ | |
955 | + .ops = { \ | |
956 | + .open = acpi_battery_##_name##_open_fs, \ | |
957 | + .read = seq_read, \ | |
958 | + .llseek = seq_lseek, \ | |
959 | + .write = acpi_battery_write_##_name, \ | |
960 | + .release = single_release, \ | |
961 | + .owner = THIS_MODULE, \ | |
962 | + }, \ | |
963 | + } | |
964 | + | |
965 | +static const struct battery_file { | |
966 | + struct file_operations ops; | |
967 | + umode_t mode; | |
968 | + const char *name; | |
969 | +} acpi_battery_file[] = { | |
970 | + FILE_DESCRIPTION_RO(info), | |
971 | + FILE_DESCRIPTION_RO(state), | |
972 | + FILE_DESCRIPTION_RW(alarm), | |
973 | +}; | |
974 | + | |
975 | +#undef FILE_DESCRIPTION_RO | |
976 | +#undef FILE_DESCRIPTION_RW | |
977 | + | |
978 | +static int acpi_battery_add_fs(struct acpi_device *device) | |
979 | +{ | |
980 | + struct proc_dir_entry *entry = NULL; | |
981 | + int i; | |
982 | + | |
983 | + printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," | |
984 | + " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | |
985 | + if (!acpi_device_dir(device)) { | |
986 | + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | |
987 | + acpi_battery_dir); | |
988 | + if (!acpi_device_dir(device)) | |
989 | + return -ENODEV; | |
990 | + } | |
991 | + | |
992 | + for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { | |
993 | + entry = proc_create_data(acpi_battery_file[i].name, | |
994 | + acpi_battery_file[i].mode, | |
995 | + acpi_device_dir(device), | |
996 | + &acpi_battery_file[i].ops, | |
997 | + acpi_driver_data(device)); | |
998 | + if (!entry) | |
999 | + return -ENODEV; | |
1000 | + } | |
1001 | + return 0; | |
1002 | +} | |
1003 | + | |
1004 | +static void acpi_battery_remove_fs(struct acpi_device *device) | |
1005 | +{ | |
1006 | + int i; | |
1007 | + if (!acpi_device_dir(device)) | |
1008 | + return; | |
1009 | + for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) | |
1010 | + remove_proc_entry(acpi_battery_file[i].name, | |
1011 | + acpi_device_dir(device)); | |
1012 | + | |
1013 | + remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | |
1014 | + acpi_device_dir(device) = NULL; | |
1015 | +} | |
1016 | + | |
1017 | +#endif | |
1018 | + | |
1019 | +/* -------------------------------------------------------------------------- | |
720 | 1020 | Driver Interface |
721 | 1021 | -------------------------------------------------------------------------- */ |
722 | 1022 | |
... | ... | @@ -790,6 +1090,15 @@ |
790 | 1090 | result = acpi_battery_update(battery); |
791 | 1091 | if (result) |
792 | 1092 | goto fail; |
1093 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1094 | + result = acpi_battery_add_fs(device); | |
1095 | +#endif | |
1096 | + if (result) { | |
1097 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1098 | + acpi_battery_remove_fs(device); | |
1099 | +#endif | |
1100 | + goto fail; | |
1101 | + } | |
793 | 1102 | |
794 | 1103 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", |
795 | 1104 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), |
... | ... | @@ -816,6 +1125,9 @@ |
816 | 1125 | return -EINVAL; |
817 | 1126 | battery = acpi_driver_data(device); |
818 | 1127 | unregister_pm_notifier(&battery->pm_nb); |
1128 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1129 | + acpi_battery_remove_fs(device); | |
1130 | +#endif | |
819 | 1131 | sysfs_remove_battery(battery); |
820 | 1132 | mutex_destroy(&battery->lock); |
821 | 1133 | mutex_destroy(&battery->sysfs_lock); |
... | ... | @@ -866,7 +1178,19 @@ |
866 | 1178 | |
867 | 1179 | if (dmi_check_system(bat_dmi_table)) |
868 | 1180 | battery_bix_broken_package = 1; |
869 | - acpi_bus_register_driver(&acpi_battery_driver); | |
1181 | + | |
1182 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1183 | + acpi_battery_dir = acpi_lock_battery_dir(); | |
1184 | + if (!acpi_battery_dir) | |
1185 | + return; | |
1186 | +#endif | |
1187 | + if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | |
1188 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1189 | + acpi_unlock_battery_dir(acpi_battery_dir); | |
1190 | +#endif | |
1191 | + return; | |
1192 | + } | |
1193 | + return; | |
870 | 1194 | } |
871 | 1195 | |
872 | 1196 | static int __init acpi_battery_init(void) |
... | ... | @@ -878,6 +1202,9 @@ |
878 | 1202 | static void __exit acpi_battery_exit(void) |
879 | 1203 | { |
880 | 1204 | acpi_bus_unregister_driver(&acpi_battery_driver); |
1205 | +#ifdef CONFIG_ACPI_PROCFS_POWER | |
1206 | + acpi_unlock_battery_dir(acpi_battery_dir); | |
1207 | +#endif | |
881 | 1208 | } |
882 | 1209 | |
883 | 1210 | module_init(acpi_battery_init); |
drivers/acpi/blacklist.c
... | ... | @@ -314,6 +314,14 @@ |
314 | 314 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), |
315 | 315 | }, |
316 | 316 | }, |
317 | + { | |
318 | + .callback = dmi_disable_osi_win8, | |
319 | + .ident = "Dell Inspiron 7737", | |
320 | + .matches = { | |
321 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
322 | + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), | |
323 | + }, | |
324 | + }, | |
317 | 325 | |
318 | 326 | /* |
319 | 327 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
... | ... | @@ -372,6 +380,19 @@ |
372 | 380 | .matches = { |
373 | 381 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
374 | 382 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), |
383 | + }, | |
384 | + }, | |
385 | + /* | |
386 | + * Without this this EEEpc exports a non working WMI interface, with | |
387 | + * this it exports a working "good old" eeepc_laptop interface, fixing | |
388 | + * both brightness control, and rfkill not working. | |
389 | + */ | |
390 | + { | |
391 | + .callback = dmi_enable_osi_linux, | |
392 | + .ident = "Asus EEE PC 1015PX", | |
393 | + .matches = { | |
394 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), | |
395 | + DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), | |
375 | 396 | }, |
376 | 397 | }, |
377 | 398 | {} |
drivers/acpi/cm_sbs.c
1 | +/* | |
2 | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
3 | + * | |
4 | + * This program is free software; you can redistribute it and/or modify | |
5 | + * it under the terms of the GNU General Public License as published by | |
6 | + * the Free Software Foundation; either version 2 of the License, or (at | |
7 | + * your option) any later version. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, but | |
10 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | + * General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License along | |
15 | + * with this program; if not, write to the Free Software Foundation, Inc., | |
16 | + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
17 | + * | |
18 | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
19 | + */ | |
20 | + | |
21 | +#include <linux/kernel.h> | |
22 | +#include <linux/module.h> | |
23 | +#include <linux/init.h> | |
24 | +#include <linux/acpi.h> | |
25 | +#include <linux/types.h> | |
26 | +#include <linux/proc_fs.h> | |
27 | +#include <linux/seq_file.h> | |
28 | +#include <acpi/acpi_bus.h> | |
29 | +#include <acpi/acpi_drivers.h> | |
30 | + | |
31 | +#define PREFIX "ACPI: " | |
32 | + | |
33 | +ACPI_MODULE_NAME("cm_sbs"); | |
34 | +#define ACPI_AC_CLASS "ac_adapter" | |
35 | +#define ACPI_BATTERY_CLASS "battery" | |
36 | +#define _COMPONENT ACPI_SBS_COMPONENT | |
37 | +static struct proc_dir_entry *acpi_ac_dir; | |
38 | +static struct proc_dir_entry *acpi_battery_dir; | |
39 | + | |
40 | +static DEFINE_MUTEX(cm_sbs_mutex); | |
41 | + | |
42 | +static int lock_ac_dir_cnt; | |
43 | +static int lock_battery_dir_cnt; | |
44 | + | |
45 | +struct proc_dir_entry *acpi_lock_ac_dir(void) | |
46 | +{ | |
47 | + mutex_lock(&cm_sbs_mutex); | |
48 | + if (!acpi_ac_dir) | |
49 | + acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | |
50 | + if (acpi_ac_dir) { | |
51 | + lock_ac_dir_cnt++; | |
52 | + } else { | |
53 | + printk(KERN_ERR PREFIX | |
54 | + "Cannot create %s\n", ACPI_AC_CLASS); | |
55 | + } | |
56 | + mutex_unlock(&cm_sbs_mutex); | |
57 | + return acpi_ac_dir; | |
58 | +} | |
59 | +EXPORT_SYMBOL(acpi_lock_ac_dir); | |
60 | + | |
61 | +void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) | |
62 | +{ | |
63 | + mutex_lock(&cm_sbs_mutex); | |
64 | + if (acpi_ac_dir_param) | |
65 | + lock_ac_dir_cnt--; | |
66 | + if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { | |
67 | + remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | |
68 | + acpi_ac_dir = NULL; | |
69 | + } | |
70 | + mutex_unlock(&cm_sbs_mutex); | |
71 | +} | |
72 | +EXPORT_SYMBOL(acpi_unlock_ac_dir); | |
73 | + | |
74 | +struct proc_dir_entry *acpi_lock_battery_dir(void) | |
75 | +{ | |
76 | + mutex_lock(&cm_sbs_mutex); | |
77 | + if (!acpi_battery_dir) { | |
78 | + acpi_battery_dir = | |
79 | + proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | |
80 | + } | |
81 | + if (acpi_battery_dir) { | |
82 | + lock_battery_dir_cnt++; | |
83 | + } else { | |
84 | + printk(KERN_ERR PREFIX | |
85 | + "Cannot create %s\n", ACPI_BATTERY_CLASS); | |
86 | + } | |
87 | + mutex_unlock(&cm_sbs_mutex); | |
88 | + return acpi_battery_dir; | |
89 | +} | |
90 | +EXPORT_SYMBOL(acpi_lock_battery_dir); | |
91 | + | |
92 | +void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | |
93 | +{ | |
94 | + mutex_lock(&cm_sbs_mutex); | |
95 | + if (acpi_battery_dir_param) | |
96 | + lock_battery_dir_cnt--; | |
97 | + if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param | |
98 | + && acpi_battery_dir) { | |
99 | + remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | |
100 | + acpi_battery_dir = NULL; | |
101 | + } | |
102 | + mutex_unlock(&cm_sbs_mutex); | |
103 | + return; | |
104 | +} | |
105 | +EXPORT_SYMBOL(acpi_unlock_battery_dir); |
drivers/acpi/video.c
... | ... | @@ -457,10 +457,10 @@ |
457 | 457 | }, |
458 | 458 | { |
459 | 459 | .callback = video_set_use_native_backlight, |
460 | - .ident = "ThinkPad T430s", | |
460 | + .ident = "ThinkPad T430 and T430s", | |
461 | 461 | .matches = { |
462 | 462 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
463 | - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), | |
463 | + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"), | |
464 | 464 | }, |
465 | 465 | }, |
466 | 466 | { |
... | ... | @@ -472,7 +472,7 @@ |
472 | 472 | }, |
473 | 473 | }, |
474 | 474 | { |
475 | - .callback = video_set_use_native_backlight, | |
475 | + .callback = video_set_use_native_backlight, | |
476 | 476 | .ident = "ThinkPad X1 Carbon", |
477 | 477 | .matches = { |
478 | 478 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
... | ... | @@ -500,7 +500,7 @@ |
500 | 500 | .ident = "Dell Inspiron 7520", |
501 | 501 | .matches = { |
502 | 502 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
503 | - DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"), | |
503 | + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), | |
504 | 504 | }, |
505 | 505 | }, |
506 | 506 | { |
... | ... | @@ -509,6 +509,14 @@ |
509 | 509 | .matches = { |
510 | 510 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
511 | 511 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"), |
512 | + }, | |
513 | + }, | |
514 | + { | |
515 | + .callback = video_set_use_native_backlight, | |
516 | + .ident = "Acer Aspire 5742G", | |
517 | + .matches = { | |
518 | + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | |
519 | + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5742G"), | |
512 | 520 | }, |
513 | 521 | }, |
514 | 522 | { |
drivers/char/tpm/tpm_ppi.c
... | ... | @@ -328,14 +328,12 @@ |
328 | 328 | /* Cache TPM ACPI handle and version string */ |
329 | 329 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, |
330 | 330 | ppi_callback, NULL, NULL, &tpm_ppi_handle); |
331 | - if (tpm_ppi_handle == NULL) | |
332 | - return -ENODEV; | |
333 | - | |
334 | - return sysfs_create_group(parent, &ppi_attr_grp); | |
331 | + return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0; | |
335 | 332 | } |
336 | 333 | |
337 | 334 | void tpm_remove_ppi(struct kobject *parent) |
338 | 335 | { |
339 | - sysfs_remove_group(parent, &ppi_attr_grp); | |
336 | + if (tpm_ppi_handle) | |
337 | + sysfs_remove_group(parent, &ppi_attr_grp); | |
340 | 338 | } |
drivers/cpufreq/intel_pstate.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #define BYT_RATIOS 0x66a |
38 | 38 | #define BYT_VIDS 0x66b |
39 | 39 | #define BYT_TURBO_RATIOS 0x66c |
40 | +#define BYT_TURBO_VIDS 0x66d | |
40 | 41 | |
41 | 42 | |
42 | 43 | #define FRAC_BITS 6 |
... | ... | @@ -70,8 +71,9 @@ |
70 | 71 | }; |
71 | 72 | |
72 | 73 | struct vid_data { |
73 | - int32_t min; | |
74 | - int32_t max; | |
74 | + int min; | |
75 | + int max; | |
76 | + int turbo; | |
75 | 77 | int32_t ratio; |
76 | 78 | }; |
77 | 79 | |
78 | 80 | |
... | ... | @@ -359,14 +361,14 @@ |
359 | 361 | { |
360 | 362 | u64 value; |
361 | 363 | rdmsrl(BYT_RATIOS, value); |
362 | - return (value >> 8) & 0xFF; | |
364 | + return (value >> 8) & 0x3F; | |
363 | 365 | } |
364 | 366 | |
365 | 367 | static int byt_get_max_pstate(void) |
366 | 368 | { |
367 | 369 | u64 value; |
368 | 370 | rdmsrl(BYT_RATIOS, value); |
369 | - return (value >> 16) & 0xFF; | |
371 | + return (value >> 16) & 0x3F; | |
370 | 372 | } |
371 | 373 | |
372 | 374 | static int byt_get_turbo_pstate(void) |
... | ... | @@ -393,6 +395,9 @@ |
393 | 395 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); |
394 | 396 | vid = fp_toint(vid_fp); |
395 | 397 | |
398 | + if (pstate > cpudata->pstate.max_pstate) | |
399 | + vid = cpudata->vid.turbo; | |
400 | + | |
396 | 401 | val |= vid; |
397 | 402 | |
398 | 403 | wrmsrl(MSR_IA32_PERF_CTL, val); |
399 | 404 | |
400 | 405 | |
... | ... | @@ -402,13 +407,17 @@ |
402 | 407 | { |
403 | 408 | u64 value; |
404 | 409 | |
410 | + | |
405 | 411 | rdmsrl(BYT_VIDS, value); |
406 | - cpudata->vid.min = int_tofp((value >> 8) & 0x7f); | |
407 | - cpudata->vid.max = int_tofp((value >> 16) & 0x7f); | |
412 | + cpudata->vid.min = int_tofp((value >> 8) & 0x3f); | |
413 | + cpudata->vid.max = int_tofp((value >> 16) & 0x3f); | |
408 | 414 | cpudata->vid.ratio = div_fp( |
409 | 415 | cpudata->vid.max - cpudata->vid.min, |
410 | 416 | int_tofp(cpudata->pstate.max_pstate - |
411 | 417 | cpudata->pstate.min_pstate)); |
418 | + | |
419 | + rdmsrl(BYT_TURBO_VIDS, value); | |
420 | + cpudata->vid.turbo = value & 0x7f; | |
412 | 421 | } |
413 | 422 | |
414 | 423 | |
... | ... | @@ -545,12 +554,7 @@ |
545 | 554 | |
546 | 555 | if (pstate_funcs.get_vid) |
547 | 556 | pstate_funcs.get_vid(cpu); |
548 | - | |
549 | - /* | |
550 | - * goto max pstate so we don't slow up boot if we are built-in if we are | |
551 | - * a module we will take care of it during normal operation | |
552 | - */ | |
553 | - intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | |
557 | + intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); | |
554 | 558 | } |
555 | 559 | |
556 | 560 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
... | ... | @@ -695,11 +699,6 @@ |
695 | 699 | cpu = all_cpu_data[cpunum]; |
696 | 700 | |
697 | 701 | intel_pstate_get_cpu_pstates(cpu); |
698 | - if (!cpu->pstate.current_pstate) { | |
699 | - all_cpu_data[cpunum] = NULL; | |
700 | - kfree(cpu); | |
701 | - return -ENODATA; | |
702 | - } | |
703 | 702 | |
704 | 703 | cpu->cpu = cpunum; |
705 | 704 | |
... | ... | @@ -710,7 +709,6 @@ |
710 | 709 | cpu->timer.expires = jiffies + HZ/100; |
711 | 710 | intel_pstate_busy_pid_reset(cpu); |
712 | 711 | intel_pstate_sample(cpu); |
713 | - intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | |
714 | 712 | |
715 | 713 | add_timer_on(&cpu->timer, cpunum); |
716 | 714 |