Skip to content

Commit 6c128e7

Browse files
committed
Merge branches 'acpi-cppc', 'acpi-misc', 'acpi-battery' and 'acpi-ac'
* acpi-cppc: mailbox: PCC: erroneous error message when parsing ACPI PCCT ACPI / CPPC: Fix invalid PCC channel status errors ACPI / CPPC: Document CPPC sysfs interface cpufreq / CPPC: Support for CPPC v3 ACPI / CPPC: Check for valid PCC subspace only if PCC is used ACPI / CPPC: Add support for CPPC v3 * acpi-misc: ACPI: Add missing prototype_for arch_post_acpi_subsys_init() ACPI: add missing newline to printk * acpi-battery: ACPI / battery: Add quirk to avoid checking for PMIC with native driver ACPI / battery: Ignore AC state in handle_discharging on systems where it is broken ACPI / battery: Add handling for devices which wrongly report discharging state ACPI / battery: Remove initializer for unused ident dmi_system_id ACPI / AC: Remove initializer for unused ident dmi_system_id * acpi-ac: ACPI / AC: Add quirk to avoid checking for PMIC with native driver
5 parents ba609f7 + 8f8027c + 63fab69 + ec625a3 + 91ea5b1 commit 6c128e7

File tree

9 files changed

+400
-137
lines changed

9 files changed

+400
-137
lines changed

Documentation/acpi/cppc_sysfs.txt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
Collaborative Processor Performance Control (CPPC)
3+
4+
CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
5+
performance of a logical processor on a contigious and abstract performance
6+
scale. CPPC exposes a set of registers to describe abstract performance scale,
7+
to request performance levels and to measure per-cpu delivered performance.
8+
9+
For more details on CPPC please refer to the ACPI specification at:
10+
11+
http://uefi.org/specifications
12+
13+
Some of the CPPC registers are exposed via sysfs under:
14+
15+
/sys/devices/system/cpu/cpuX/acpi_cppc/
16+
17+
for each cpu X
18+
19+
--------------------------------------------------------------------------------
20+
21+
$ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/
22+
/sys/devices/system/cpu/cpu0/acpi_cppc/:
23+
total 0
24+
-r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs
25+
-r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf
26+
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq
27+
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf
28+
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf
29+
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq
30+
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf
31+
-r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf
32+
-r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time
33+
34+
--------------------------------------------------------------------------------
35+
36+
* highest_perf : Highest performance of this processor (abstract scale).
37+
* nominal_perf : Highest sustained performance of this processor (abstract scale).
38+
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
39+
power savings (abstract scale).
40+
* lowest_perf : Lowest performance of this processor (abstract scale).
41+
42+
* lowest_freq : CPU frequency corresponding to lowest_perf (in MHz).
43+
* nominal_freq : CPU frequency corresponding to nominal_perf (in MHz).
44+
The above frequencies should only be used to report processor performance in
45+
freqency instead of abstract scale. These values should not be used for any
46+
functional decisions.
47+
48+
* feedback_ctrs : Includes both Reference and delivered performance counter.
49+
Reference counter ticks up proportional to processor's reference performance.
50+
Delivered counter ticks up proportional to processor's delivered performance.
51+
* wraparound_time: Minimum time for the feedback counters to wraparound (seconds).
52+
* reference_perf : Performance level at which reference performance counter
53+
accumulates (abstract scale).
54+
55+
--------------------------------------------------------------------------------
56+
57+
Computing Average Delivered Performance
58+
59+
Below describes the steps to compute the average performance delivered by taking
60+
two different snapshots of feedback counters at time T1 and T2.
61+
62+
T1: Read feedback_ctrs as fbc_t1
63+
Wait or run some workload
64+
T2: Read feedback_ctrs as fbc_t2
65+
66+
delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
67+
reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]
68+
69+
delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta

drivers/acpi/ac.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);
8787

8888

8989
static int ac_sleep_before_get_state_ms;
90+
static int ac_check_pmic = 1;
9091

9192
static struct acpi_driver acpi_ac_driver = {
9293
.name = "ac",
@@ -310,21 +311,43 @@ static int acpi_ac_battery_notify(struct notifier_block *nb,
310311
return NOTIFY_OK;
311312
}
312313

313-
static int thinkpad_e530_quirk(const struct dmi_system_id *d)
314+
static int __init thinkpad_e530_quirk(const struct dmi_system_id *d)
314315
{
315316
ac_sleep_before_get_state_ms = 1000;
316317
return 0;
317318
}
318319

319-
static const struct dmi_system_id ac_dmi_table[] = {
320+
static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
321+
{
322+
ac_check_pmic = 0;
323+
return 0;
324+
}
325+
326+
static const struct dmi_system_id ac_dmi_table[] __initconst = {
320327
{
328+
/* Thinkpad e530 */
321329
.callback = thinkpad_e530_quirk,
322-
.ident = "thinkpad e530",
323330
.matches = {
324331
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
325332
DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
326333
},
327334
},
335+
{
336+
/* ECS EF20EA */
337+
.callback = ac_do_not_check_pmic_quirk,
338+
.matches = {
339+
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
340+
},
341+
},
342+
{
343+
/* Lenovo Ideapad Miix 320 */
344+
.callback = ac_do_not_check_pmic_quirk,
345+
.matches = {
346+
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
347+
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
348+
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
349+
},
350+
},
328351
{},
329352
};
330353

@@ -384,7 +407,6 @@ static int acpi_ac_add(struct acpi_device *device)
384407
kfree(ac);
385408
}
386409

387-
dmi_check_system(ac_dmi_table);
388410
return result;
389411
}
390412

@@ -442,13 +464,17 @@ static int __init acpi_ac_init(void)
442464
if (acpi_disabled)
443465
return -ENODEV;
444466

445-
for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
446-
if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
447-
acpi_ac_blacklist[i].hrv)) {
448-
pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
449-
acpi_ac_blacklist[i].hid);
450-
return -ENODEV;
451-
}
467+
dmi_check_system(ac_dmi_table);
468+
469+
if (ac_check_pmic) {
470+
for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
471+
if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
472+
acpi_ac_blacklist[i].hrv)) {
473+
pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
474+
acpi_ac_blacklist[i].hid);
475+
return -ENODEV;
476+
}
477+
}
452478

453479
#ifdef CONFIG_ACPI_PROCFS_POWER
454480
acpi_ac_dir = acpi_lock_ac_dir();

drivers/acpi/battery.c

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static async_cookie_t async_cookie;
7474
static bool battery_driver_registered;
7575
static int battery_bix_broken_package;
7676
static int battery_notification_delay_ms;
77+
static int battery_ac_is_broken;
78+
static int battery_check_pmic = 1;
7779
static unsigned int cache_time = 1000;
7880
module_param(cache_time, uint, 0644);
7981
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
@@ -215,6 +217,20 @@ static bool acpi_battery_is_degraded(struct acpi_battery *battery)
215217
battery->full_charge_capacity < battery->design_capacity;
216218
}
217219

220+
static int acpi_battery_handle_discharging(struct acpi_battery *battery)
221+
{
222+
/*
223+
* Some devices wrongly report discharging if the battery's charge level
224+
* was above the device's start charging threshold atm the AC adapter
225+
* was plugged in and the device thus did not start a new charge cycle.
226+
*/
227+
if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
228+
battery->rate_now == 0)
229+
return POWER_SUPPLY_STATUS_NOT_CHARGING;
230+
231+
return POWER_SUPPLY_STATUS_DISCHARGING;
232+
}
233+
218234
static int acpi_battery_get_property(struct power_supply *psy,
219235
enum power_supply_property psp,
220236
union power_supply_propval *val)
@@ -230,7 +246,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
230246
switch (psp) {
231247
case POWER_SUPPLY_PROP_STATUS:
232248
if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
233-
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
249+
val->intval = acpi_battery_handle_discharging(battery);
234250
else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
235251
val->intval = POWER_SUPPLY_STATUS_CHARGING;
236252
else if (acpi_battery_is_charged(battery))
@@ -1332,23 +1348,64 @@ battery_notification_delay_quirk(const struct dmi_system_id *d)
13321348
return 0;
13331349
}
13341350

1351+
static int __init
1352+
battery_ac_is_broken_quirk(const struct dmi_system_id *d)
1353+
{
1354+
battery_ac_is_broken = 1;
1355+
return 0;
1356+
}
1357+
1358+
static int __init
1359+
battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
1360+
{
1361+
battery_check_pmic = 0;
1362+
return 0;
1363+
}
1364+
13351365
static const struct dmi_system_id bat_dmi_table[] __initconst = {
13361366
{
1367+
/* NEC LZ750/LS */
13371368
.callback = battery_bix_broken_package_quirk,
1338-
.ident = "NEC LZ750/LS",
13391369
.matches = {
13401370
DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
13411371
DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
13421372
},
13431373
},
13441374
{
1375+
/* Acer Aspire V5-573G */
13451376
.callback = battery_notification_delay_quirk,
1346-
.ident = "Acer Aspire V5-573G",
13471377
.matches = {
13481378
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
13491379
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
13501380
},
13511381
},
1382+
{
1383+
/* Point of View mobii wintab p800w */
1384+
.callback = battery_ac_is_broken_quirk,
1385+
.matches = {
1386+
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1387+
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1388+
DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1389+
/* Above matches are too generic, add bios-date match */
1390+
DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1391+
},
1392+
},
1393+
{
1394+
/* ECS EF20EA */
1395+
.callback = battery_do_not_check_pmic_quirk,
1396+
.matches = {
1397+
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
1398+
},
1399+
},
1400+
{
1401+
/* Lenovo Ideapad Miix 320 */
1402+
.callback = battery_do_not_check_pmic_quirk,
1403+
.matches = {
1404+
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1405+
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
1406+
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
1407+
},
1408+
},
13521409
{},
13531410
};
13541411

@@ -1488,16 +1545,18 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
14881545
unsigned int i;
14891546
int result;
14901547

1491-
for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1492-
if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1493-
pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1494-
": found native %s PMIC, not loading\n",
1495-
acpi_battery_blacklist[i]);
1496-
return;
1497-
}
1498-
14991548
dmi_check_system(bat_dmi_table);
15001549

1550+
if (battery_check_pmic) {
1551+
for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1552+
if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1553+
pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1554+
": found native %s PMIC, not loading\n",
1555+
acpi_battery_blacklist[i]);
1556+
return;
1557+
}
1558+
}
1559+
15011560
#ifdef CONFIG_ACPI_PROCFS_POWER
15021561
acpi_battery_dir = acpi_lock_battery_dir();
15031562
if (!acpi_battery_dir)

0 commit comments

Comments
 (0)