Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e598dd4

Browse files
committed
Merge branches 'acpi-x86', 'acpi-fan', 'acpi-soc' and 'acpi-cppc'
Merge changes in the ACPI x86-specific code, ACPI fan driverm ACPI LPSS (Intel SoC) driver and the ACPI CPPC library for 6.11-rc1: - Switch the ACPI x86 utility code and the ACPI LPSS driver to new Intel CPU model defines (Tony Luck). - Add hwmon interface support to the ACPI fan driver (Armin Wolf). - Add sysfs entry for guaranteed performance to the ACPI CPPC library and replace a ternary operator with umax() in it (Petr Tesařík, Prabhakar Pujeri). * acpi-x86: ACPI: x86: Switch to new Intel CPU model defines * acpi-fan: ACPI: fan: Add hwmon support * acpi-soc: ACPI: LPSS: Switch to new Intel CPU model defines * acpi-cppc: ACPI: CPPC: Replace ternary operator with umax() ACPI: CPPC: add sysfs entry for guaranteed performance
5 parents 233323f + 35ba8ec + 35c50d8 + dde8ec8 + 86932cd commit e598dd4

File tree

7 files changed

+211
-25
lines changed

7 files changed

+211
-25
lines changed

drivers/acpi/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ obj-$(CONFIG_ACPI_TINY_POWER_BUTTON) += tiny-power-button.o
7777
obj-$(CONFIG_ACPI_FAN) += fan.o
7878
fan-objs := fan_core.o
7979
fan-objs += fan_attr.o
80+
fan-$(CONFIG_HWMON) += fan_hwmon.o
8081

8182
obj-$(CONFIG_ACPI_VIDEO) += video.o
8283
obj-$(CONFIG_ACPI_TAD) += acpi_tad.o

drivers/acpi/cppc_acpi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf);
160160
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf);
161161
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf);
162162
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf);
163+
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, guaranteed_perf);
163164
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_freq);
164165
show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq);
165166

@@ -196,6 +197,7 @@ static struct attribute *cppc_attrs[] = {
196197
&highest_perf.attr,
197198
&lowest_perf.attr,
198199
&lowest_nonlinear_perf.attr,
200+
&guaranteed_perf.attr,
199201
&nominal_perf.attr,
200202
&nominal_freq.attr,
201203
&lowest_freq.attr,
@@ -1837,7 +1839,7 @@ static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private)
18371839
dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH) {
18381840
u16 val = (u16)get_unaligned((const u16 *)
18391841
(dmi_data + DMI_PROCESSOR_MAX_SPEED));
1840-
*mhz = val > *mhz ? val : *mhz;
1842+
*mhz = umax(val, *mhz);
18411843
}
18421844
}
18431845

drivers/acpi/fan.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#ifndef _ACPI_FAN_H_
1111
#define _ACPI_FAN_H_
1212

13+
#include <linux/kconfig.h>
14+
1315
#define ACPI_FAN_DEVICE_IDS \
1416
{"INT3404", }, /* Fan */ \
1517
{"INTC1044", }, /* Fan for Tiger Lake generation */ \
@@ -57,4 +59,11 @@ struct acpi_fan {
5759
int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst);
5860
int acpi_fan_create_attributes(struct acpi_device *device);
5961
void acpi_fan_delete_attributes(struct acpi_device *device);
62+
63+
#if IS_REACHABLE(CONFIG_HWMON)
64+
int devm_acpi_fan_create_hwmon(struct acpi_device *device);
65+
#else
66+
static inline int devm_acpi_fan_create_hwmon(struct acpi_device *device) { return 0; };
67+
#endif
68+
6069
#endif

drivers/acpi/fan_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ static int acpi_fan_probe(struct platform_device *pdev)
336336
if (result)
337337
return result;
338338

339+
result = devm_acpi_fan_create_hwmon(device);
340+
if (result)
341+
return result;
342+
339343
result = acpi_fan_create_attributes(device);
340344
if (result)
341345
return result;

drivers/acpi/fan_hwmon.c

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* hwmon interface for the ACPI Fan driver.
4+
*
5+
* Copyright (C) 2024 Armin Wolf <W_Armin@gmx.de>
6+
*/
7+
8+
#include <linux/acpi.h>
9+
#include <linux/device.h>
10+
#include <linux/err.h>
11+
#include <linux/hwmon.h>
12+
#include <linux/limits.h>
13+
#include <linux/types.h>
14+
#include <linux/units.h>
15+
16+
#include "fan.h"
17+
18+
/* Returned when the ACPI fan does not support speed reporting */
19+
#define FAN_SPEED_UNAVAILABLE U32_MAX
20+
#define FAN_POWER_UNAVAILABLE U32_MAX
21+
22+
static struct acpi_fan_fps *acpi_fan_get_current_fps(struct acpi_fan *fan, u64 control)
23+
{
24+
unsigned int i;
25+
26+
for (i = 0; i < fan->fps_count; i++) {
27+
if (fan->fps[i].control == control)
28+
return &fan->fps[i];
29+
}
30+
31+
return NULL;
32+
}
33+
34+
static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
35+
u32 attr, int channel)
36+
{
37+
const struct acpi_fan *fan = drvdata;
38+
unsigned int i;
39+
40+
switch (type) {
41+
case hwmon_fan:
42+
switch (attr) {
43+
case hwmon_fan_input:
44+
return 0444;
45+
case hwmon_fan_target:
46+
/*
47+
* When in fine grain control mode, not every fan control value
48+
* has an associated fan performance state.
49+
*/
50+
if (fan->fif.fine_grain_ctrl)
51+
return 0;
52+
53+
return 0444;
54+
default:
55+
return 0;
56+
}
57+
case hwmon_power:
58+
switch (attr) {
59+
case hwmon_power_input:
60+
/*
61+
* When in fine grain control mode, not every fan control value
62+
* has an associated fan performance state.
63+
*/
64+
if (fan->fif.fine_grain_ctrl)
65+
return 0;
66+
67+
/*
68+
* When all fan performance states contain no valid power data,
69+
* when the associated attribute should not be created.
70+
*/
71+
for (i = 0; i < fan->fps_count; i++) {
72+
if (fan->fps[i].power != FAN_POWER_UNAVAILABLE)
73+
return 0444;
74+
}
75+
76+
return 0;
77+
default:
78+
return 0;
79+
}
80+
default:
81+
return 0;
82+
}
83+
}
84+
85+
static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
86+
int channel, long *val)
87+
{
88+
struct acpi_device *adev = to_acpi_device(dev->parent);
89+
struct acpi_fan *fan = dev_get_drvdata(dev);
90+
struct acpi_fan_fps *fps;
91+
struct acpi_fan_fst fst;
92+
int ret;
93+
94+
ret = acpi_fan_get_fst(adev, &fst);
95+
if (ret < 0)
96+
return ret;
97+
98+
switch (type) {
99+
case hwmon_fan:
100+
switch (attr) {
101+
case hwmon_fan_input:
102+
if (fst.speed == FAN_SPEED_UNAVAILABLE)
103+
return -ENODEV;
104+
105+
if (fst.speed > LONG_MAX)
106+
return -EOVERFLOW;
107+
108+
*val = fst.speed;
109+
return 0;
110+
case hwmon_fan_target:
111+
fps = acpi_fan_get_current_fps(fan, fst.control);
112+
if (!fps)
113+
return -EIO;
114+
115+
if (fps->speed > LONG_MAX)
116+
return -EOVERFLOW;
117+
118+
*val = fps->speed;
119+
return 0;
120+
default:
121+
return -EOPNOTSUPP;
122+
}
123+
case hwmon_power:
124+
switch (attr) {
125+
case hwmon_power_input:
126+
fps = acpi_fan_get_current_fps(fan, fst.control);
127+
if (!fps)
128+
return -EIO;
129+
130+
if (fps->power == FAN_POWER_UNAVAILABLE)
131+
return -ENODEV;
132+
133+
if (fps->power > LONG_MAX / MICROWATT_PER_MILLIWATT)
134+
return -EOVERFLOW;
135+
136+
*val = fps->power * MICROWATT_PER_MILLIWATT;
137+
return 0;
138+
default:
139+
return -EOPNOTSUPP;
140+
}
141+
default:
142+
return -EOPNOTSUPP;
143+
}
144+
}
145+
146+
static const struct hwmon_ops acpi_fan_hwmon_ops = {
147+
.is_visible = acpi_fan_hwmon_is_visible,
148+
.read = acpi_fan_hwmon_read,
149+
};
150+
151+
static const struct hwmon_channel_info * const acpi_fan_hwmon_info[] = {
152+
HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_TARGET),
153+
HWMON_CHANNEL_INFO(power, HWMON_P_INPUT),
154+
NULL
155+
};
156+
157+
static const struct hwmon_chip_info acpi_fan_hwmon_chip_info = {
158+
.ops = &acpi_fan_hwmon_ops,
159+
.info = acpi_fan_hwmon_info,
160+
};
161+
162+
int devm_acpi_fan_create_hwmon(struct acpi_device *device)
163+
{
164+
struct acpi_fan *fan = acpi_driver_data(device);
165+
struct device *hdev;
166+
167+
hdev = devm_hwmon_device_register_with_info(&device->dev, "acpi_fan", fan,
168+
&acpi_fan_hwmon_chip_info, NULL);
169+
return PTR_ERR_OR_ZERO(hdev);
170+
}

drivers/acpi/x86/lpss.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,8 @@ static const struct lpss_device_desc bsw_spi_dev_desc = {
338338
};
339339

340340
static const struct x86_cpu_id lpss_cpu_ids[] = {
341-
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, NULL),
342-
X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, NULL),
341+
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, NULL),
342+
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, NULL),
343343
{}
344344
};
345345

drivers/acpi/x86/utils.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,37 @@ struct override_status_id {
4545
unsigned long long status;
4646
};
4747

48-
#define ENTRY(status, hid, uid, path, cpu_model, dmi...) { \
48+
#define ENTRY(status, hid, uid, path, cpu_vfm, dmi...) { \
4949
{ { hid, }, {} }, \
50-
{ X86_MATCH_INTEL_FAM6_MODEL(cpu_model, NULL), {} }, \
50+
{ X86_MATCH_VFM(cpu_vfm, NULL), {} }, \
5151
{ { .matches = dmi }, {} }, \
5252
uid, \
5353
path, \
5454
status, \
5555
}
5656

57-
#define PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
58-
ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_model, dmi)
57+
#define PRESENT_ENTRY_HID(hid, uid, cpu_vfm, dmi...) \
58+
ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_vfm, dmi)
5959

60-
#define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \
61-
ENTRY(0, hid, uid, NULL, cpu_model, dmi)
60+
#define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_vfm, dmi...) \
61+
ENTRY(0, hid, uid, NULL, cpu_vfm, dmi)
6262

63-
#define PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
64-
ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_model, dmi)
63+
#define PRESENT_ENTRY_PATH(path, cpu_vfm, dmi...) \
64+
ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_vfm, dmi)
6565

66-
#define NOT_PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \
67-
ENTRY(0, "", NULL, path, cpu_model, dmi)
66+
#define NOT_PRESENT_ENTRY_PATH(path, cpu_vfm, dmi...) \
67+
ENTRY(0, "", NULL, path, cpu_vfm, dmi)
6868

6969
static const struct override_status_id override_status_ids[] = {
7070
/*
7171
* Bay / Cherry Trail PWM directly poked by GPU driver in win10,
7272
* but Linux uses a separate PWM driver, harmless if not used.
7373
*/
74-
PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}),
75-
PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}),
74+
PRESENT_ENTRY_HID("80860F09", "1", INTEL_ATOM_SILVERMONT, {}),
75+
PRESENT_ENTRY_HID("80862288", "1", INTEL_ATOM_AIRMONT, {}),
7676

7777
/* The Xiaomi Mi Pad 2 uses PWM2 for touchkeys backlight control */
78-
PRESENT_ENTRY_HID("80862289", "2", ATOM_AIRMONT, {
78+
PRESENT_ENTRY_HID("80862289", "2", INTEL_ATOM_AIRMONT, {
7979
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
8080
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
8181
}),
@@ -84,18 +84,18 @@ static const struct override_status_id override_status_ids[] = {
8484
* The INT0002 device is necessary to clear wakeup interrupt sources
8585
* on Cherry Trail devices, without it we get nobody cared IRQ msgs.
8686
*/
87-
PRESENT_ENTRY_HID("INT0002", "1", ATOM_AIRMONT, {}),
87+
PRESENT_ENTRY_HID("INT0002", "1", INTEL_ATOM_AIRMONT, {}),
8888
/*
8989
* On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides
9090
* the touchscreen ACPI device until a certain time
9191
* after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed
9292
* *and* _STA has been called at least 3 times since.
9393
*/
94-
PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
94+
PRESENT_ENTRY_HID("SYNA7500", "1", INTEL_HASWELL_L, {
9595
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
9696
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"),
9797
}),
98-
PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, {
98+
PRESENT_ENTRY_HID("SYNA7500", "1", INTEL_HASWELL_L, {
9999
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
100100
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"),
101101
}),
@@ -104,7 +104,7 @@ static const struct override_status_id override_status_ids[] = {
104104
* The Dell XPS 15 9550 has a SMO8110 accelerometer /
105105
* HDD freefall sensor which is wrongly marked as not present.
106106
*/
107-
PRESENT_ENTRY_HID("SMO8810", "1", SKYLAKE, {
107+
PRESENT_ENTRY_HID("SMO8810", "1", INTEL_SKYLAKE, {
108108
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
109109
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9550"),
110110
}),
@@ -121,19 +121,19 @@ static const struct override_status_id override_status_ids[] = {
121121
* was copy-pasted from the GPD win, so it has a disabled KIOX000A
122122
* node which we should not enable, thus we also check the BIOS date.
123123
*/
124-
PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
124+
PRESENT_ENTRY_HID("KIOX000A", "1", INTEL_ATOM_AIRMONT, {
125125
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
126126
DMI_MATCH(DMI_BOARD_NAME, "Default string"),
127127
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
128128
DMI_MATCH(DMI_BIOS_DATE, "02/21/2017")
129129
}),
130-
PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
130+
PRESENT_ENTRY_HID("KIOX000A", "1", INTEL_ATOM_AIRMONT, {
131131
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
132132
DMI_MATCH(DMI_BOARD_NAME, "Default string"),
133133
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
134134
DMI_MATCH(DMI_BIOS_DATE, "03/20/2017")
135135
}),
136-
PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, {
136+
PRESENT_ENTRY_HID("KIOX000A", "1", INTEL_ATOM_AIRMONT, {
137137
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
138138
DMI_MATCH(DMI_BOARD_NAME, "Default string"),
139139
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
@@ -146,7 +146,7 @@ static const struct override_status_id override_status_ids[] = {
146146
* method sets a GPIO causing the PCI wifi card to turn off.
147147
* See above remark about uniqueness of the DMI match.
148148
*/
149-
NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", ATOM_AIRMONT, {
149+
NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", INTEL_ATOM_AIRMONT, {
150150
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
151151
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
152152
DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
@@ -158,7 +158,7 @@ static const struct override_status_id override_status_ids[] = {
158158
* as both ACCL0001 and MAGN0001. As we can only ever register an
159159
* i2c client for one of them, ignore MAGN0001.
160160
*/
161-
NOT_PRESENT_ENTRY_HID("MAGN0001", "1", ATOM_SILVERMONT, {
161+
NOT_PRESENT_ENTRY_HID("MAGN0001", "1", INTEL_ATOM_SILVERMONT, {
162162
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
163163
DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"),
164164
}),

0 commit comments

Comments
 (0)