Skip to content

Commit d4b671d

Browse files
committed
Merge tag 'acpi-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki: "These fix issues, add new quirks, rearrange the IRQ override quirk definitions, add new helpers and switch over code to using them, rework a couple of interfaces to be more flexible, eliminate strncpy() usage from PNP, extend the ACPI PCC mailbox driver and clean up code. This is based on ACPI thermal driver changes that are present in the thermal control updates for 6.7-rc1 pull request (they are depended on by the ACPI utilities updates). However, the ACPI thermal driver changes are not included in the list of specific ACPI changes below. Specifics: - Add symbol definitions related to CDAT to the ACPICA code (Dave Jiang) - Use the acpi_device_is_present() helper in more places and rename acpi_scan_device_not_present() to be about enumeration (James Morse) - Add __printf format attribute to acpi_os_vprintf() (Su Hui) - Clean up departures from kernel coding style in the low-level interface for ACPICA (Jonathan Bergh) - Replace strncpy() with strscpy() in acpi_osi_setup() (Justin Stitt) - Fail FPDT parsing on zero length records and add proper handling for fpdt_process_subtable() to acpi_init_fpdt() (Vasily Khoruzhick) - Rework acpi_handle_list handling so as to manage it dynamically, including size computation (Rafael Wysocki) - Clean up ACPI utilities code so as to make it follow the kernel coding style (Jonathan Bergh) - Consolidate IRQ trigger-type override DMI tables and drop .ident values from dmi_system_id tables used for ACPI resources management quirks (Hans de Goede) - Add ACPI IRQ override for TongFang GMxXGxx (Werner Sembach) - Allow _DSD buffer data only for byte accessors and document the _DSD data buffer GUID (Andy Shevchenko) - Drop BayTrail and Lynxpoint pinctrl device IDs from the ACPI LPSS driver, because it does not need them (Raag Jadav) - Add acpi_backlight=vendor quirk for Toshiba Portégé R100 (Ondrej Zary) - Add "vendor" backlight quirks for 3 Lenovo x86 Android tablets (Hans de Goede) - Move Xiaomi Mi Pad 2 backlight quirk to its own section (Hans de Goede) - Annotate struct prm_module_info with __counted_by (Kees Cook) - Fix AER info corruption in aer_recover_queue() when error status data has multiple sections (Shiju Jose) - Make APEI use ERST maximum execution time for slow devices (Jeshua Smith) - Add support for platform notification handling to the PCC mailbox driver and modify it to support shared interrupts for multiple subspaces (Huisong Li) - Define common macros to use when referring to various bitfields in the PCC generic communications channel command and status fields and use them in some drivers (Sudeep Holla) - Add EC GPE detection quirk for HP 250 G7 Notebook PC (Jonathan Denose) - Fix and clean up create_pnp_modalias() and create_of_modalias() (Christophe JAILLET) - Modify 2 pieces of code to use acpi_evaluate_dsm_typed() (Andy Shevchenko) - Define acpi_dev_uid_match() for matching _UID and use it in several places (Raag Jadav) - Use acpi_device_uid() for fetching _UID in 2 places (Raag Jadav) - Add context argument to acpi_dev_install_notify_handler() (Rafael Wysocki) - Clarify ACPI bus concepts in the ACPI device enumeration documentation (Rafael Wysocki) - Switch over the ACPI AC and ACPI PAD drivers to using the platform driver interface which, is more logically consistent than binding a driver directly to an ACPI device object, and clean them up (Michal Wilczynski) - Replace strncpy() in the PNP code with either memcpy() or strscpy() as appropriate (Justin Stitt) - Clean up coding style in pnp.h (GuoHua Cheng)" * tag 'acpi-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (54 commits) ACPI: resource: Do IRQ override on TongFang GMxXGxx perf: arm_cspmu: use acpi_dev_hid_uid_match() for matching _HID and _UID ACPI: EC: Add quirk for HP 250 G7 Notebook PC ACPI: x86: use acpi_dev_uid_match() for matching _UID ACPI: utils: use acpi_dev_uid_match() for matching _UID pinctrl: intel: use acpi_dev_uid_match() for matching _UID ACPI: utils: Introduce acpi_dev_uid_match() for matching _UID ACPI: sysfs: Clean up create_pnp_modalias() and create_of_modalias() ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias() ACPI: acpi_pad: Rename ACPI device from device to adev ACPI: acpi_pad: Use dev groups for sysfs ACPI: acpi_pad: Replace acpi_driver with platform_driver ACPI: APEI: Use ERST timeout for slow devices ACPI: scan: Rename acpi_scan_device_not_present() to be about enumeration PNP: replace deprecated strncpy() with memcpy() PNP: ACPI: replace deprecated strncpy() with strscpy() perf: qcom: use acpi_device_uid() for fetching _UID ACPI: sysfs: use acpi_device_uid() for fetching _UID ACPI: scan: Use the acpi_device_is_present() helper in more places ACPI: AC: Rename ACPI device from device to adev ...
2 parents 4ac4677 + f4cb34a commit d4b671d

File tree

43 files changed

+681
-328
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+681
-328
lines changed

Documentation/firmware-guide/acpi/enumeration.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,49 @@ If the driver needs to perform more complex initialization like getting and
6464
configuring GPIOs it can get its ACPI handle and extract this information
6565
from ACPI tables.
6666

67+
ACPI device objects
68+
===================
69+
70+
Generally speaking, there are two categories of devices in a system in which
71+
ACPI is used as an interface between the platform firmware and the OS: Devices
72+
that can be discovered and enumerated natively, through a protocol defined for
73+
the specific bus that they are on (for example, configuration space in PCI),
74+
without the platform firmware assistance, and devices that need to be described
75+
by the platform firmware so that they can be discovered. Still, for any device
76+
known to the platform firmware, regardless of which category it falls into,
77+
there can be a corresponding ACPI device object in the ACPI Namespace in which
78+
case the Linux kernel will create a struct acpi_device object based on it for
79+
that device.
80+
81+
Those struct acpi_device objects are never used for binding drivers to natively
82+
discoverable devices, because they are represented by other types of device
83+
objects (for example, struct pci_dev for PCI devices) that are bound to by
84+
device drivers (the corresponding struct acpi_device object is then used as
85+
an additional source of information on the configuration of the given device).
86+
Moreover, the core ACPI device enumeration code creates struct platform_device
87+
objects for the majority of devices that are discovered and enumerated with the
88+
help of the platform firmware and those platform device objects can be bound to
89+
by platform drivers in direct analogy with the natively enumerable devices
90+
case. Therefore it is logically inconsistent and so generally invalid to bind
91+
drivers to struct acpi_device objects, including drivers for devices that are
92+
discovered with the help of the platform firmware.
93+
94+
Historically, ACPI drivers that bound directly to struct acpi_device objects
95+
were implemented for some devices enumerated with the help of the platform
96+
firmware, but this is not recommended for any new drivers. As explained above,
97+
platform device objects are created for those devices as a rule (with a few
98+
exceptions that are not relevant here) and so platform drivers should be used
99+
for handling them, even though the corresponding ACPI device objects are the
100+
only source of device configuration information in that case.
101+
102+
For every device having a corresponding struct acpi_device object, the pointer
103+
to it is returned by the ACPI_COMPANION() macro, so it is always possible to
104+
get to the device configuration information stored in the ACPI device object
105+
this way. Accordingly, struct acpi_device can be regarded as a part of the
106+
interface between the kernel and the ACPI Namespace, whereas device objects of
107+
other types (for example, struct pci_dev or struct platform_device) are used
108+
for interacting with the rest of the system.
109+
67110
DMA support
68111
===========
69112

drivers/acpi/ac.c

Lines changed: 41 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/delay.h>
1818
#include <linux/platform_device.h>
1919
#include <linux/power_supply.h>
20+
#include <linux/string_choices.h>
2021
#include <linux/acpi.h>
2122
#include <acpi/battery.h>
2223

@@ -32,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
3233
MODULE_DESCRIPTION("ACPI AC Adapter Driver");
3334
MODULE_LICENSE("GPL");
3435

35-
static int acpi_ac_add(struct acpi_device *device);
36-
static void acpi_ac_remove(struct acpi_device *device);
36+
static int acpi_ac_probe(struct platform_device *pdev);
37+
static void acpi_ac_remove(struct platform_device *pdev);
38+
3739
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
3840

3941
static const struct acpi_device_id ac_device_ids[] = {
@@ -50,17 +52,6 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
5052
static int ac_sleep_before_get_state_ms;
5153
static int ac_only;
5254

53-
static struct acpi_driver acpi_ac_driver = {
54-
.name = "ac",
55-
.class = ACPI_AC_CLASS,
56-
.ids = ac_device_ids,
57-
.ops = {
58-
.add = acpi_ac_add,
59-
.remove = acpi_ac_remove,
60-
},
61-
.drv.pm = &acpi_ac_pm,
62-
};
63-
6455
struct acpi_ac {
6556
struct power_supply *charger;
6657
struct power_supply_desc charger_desc;
@@ -128,15 +119,12 @@ static enum power_supply_property ac_props[] = {
128119
/* Driver Model */
129120
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
130121
{
131-
struct acpi_device *device = data;
132-
struct acpi_ac *ac = acpi_driver_data(device);
133-
134-
if (!ac)
135-
return;
122+
struct acpi_ac *ac = data;
123+
struct acpi_device *adev = ac->device;
136124

137125
switch (event) {
138126
default:
139-
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
127+
acpi_handle_debug(adev->handle, "Unsupported event [0x%x]\n",
140128
event);
141129
fallthrough;
142130
case ACPI_AC_NOTIFY_STATUS:
@@ -153,10 +141,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
153141
msleep(ac_sleep_before_get_state_ms);
154142

155143
acpi_ac_get_state(ac);
156-
acpi_bus_generate_netlink_event(device->pnp.device_class,
157-
dev_name(&device->dev), event,
144+
acpi_bus_generate_netlink_event(adev->pnp.device_class,
145+
dev_name(&adev->dev), event,
158146
(u32) ac->state);
159-
acpi_notifier_call_chain(device, event, (u32) ac->state);
147+
acpi_notifier_call_chain(adev, event, (u32) ac->state);
160148
kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
161149
}
162150
}
@@ -213,51 +201,49 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = {
213201
{},
214202
};
215203

216-
static int acpi_ac_add(struct acpi_device *device)
204+
static int acpi_ac_probe(struct platform_device *pdev)
217205
{
206+
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
218207
struct power_supply_config psy_cfg = {};
219-
int result = 0;
220-
struct acpi_ac *ac = NULL;
221-
222-
223-
if (!device)
224-
return -EINVAL;
208+
struct acpi_ac *ac;
209+
int result;
225210

226211
ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
227212
if (!ac)
228213
return -ENOMEM;
229214

230-
ac->device = device;
231-
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
232-
strcpy(acpi_device_class(device), ACPI_AC_CLASS);
233-
device->driver_data = ac;
215+
ac->device = adev;
216+
strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
217+
strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
218+
219+
platform_set_drvdata(pdev, ac);
234220

235221
result = acpi_ac_get_state(ac);
236222
if (result)
237223
goto err_release_ac;
238224

239225
psy_cfg.drv_data = ac;
240226

241-
ac->charger_desc.name = acpi_device_bid(device);
227+
ac->charger_desc.name = acpi_device_bid(adev);
242228
ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
243229
ac->charger_desc.properties = ac_props;
244230
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
245231
ac->charger_desc.get_property = get_ac_property;
246-
ac->charger = power_supply_register(&ac->device->dev,
232+
ac->charger = power_supply_register(&pdev->dev,
247233
&ac->charger_desc, &psy_cfg);
248234
if (IS_ERR(ac->charger)) {
249235
result = PTR_ERR(ac->charger);
250236
goto err_release_ac;
251237
}
252238

253-
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
254-
acpi_device_bid(device), ac->state ? "on-line" : "off-line");
239+
pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
240+
acpi_device_bid(adev), str_on_off(ac->state));
255241

256242
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
257243
register_acpi_notifier(&ac->battery_nb);
258244

259-
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
260-
acpi_ac_notify);
245+
result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
246+
acpi_ac_notify, ac);
261247
if (result)
262248
goto err_unregister;
263249

@@ -275,16 +261,9 @@ static int acpi_ac_add(struct acpi_device *device)
275261
#ifdef CONFIG_PM_SLEEP
276262
static int acpi_ac_resume(struct device *dev)
277263
{
278-
struct acpi_ac *ac;
264+
struct acpi_ac *ac = dev_get_drvdata(dev);
279265
unsigned int old_state;
280266

281-
if (!dev)
282-
return -EINVAL;
283-
284-
ac = acpi_driver_data(to_acpi_device(dev));
285-
if (!ac)
286-
return -EINVAL;
287-
288267
old_state = ac->state;
289268
if (acpi_ac_get_state(ac))
290269
return 0;
@@ -297,23 +276,28 @@ static int acpi_ac_resume(struct device *dev)
297276
#define acpi_ac_resume NULL
298277
#endif
299278

300-
static void acpi_ac_remove(struct acpi_device *device)
279+
static void acpi_ac_remove(struct platform_device *pdev)
301280
{
302-
struct acpi_ac *ac = NULL;
281+
struct acpi_ac *ac = platform_get_drvdata(pdev);
303282

304-
if (!device || !acpi_driver_data(device))
305-
return;
306-
307-
ac = acpi_driver_data(device);
308-
309-
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
283+
acpi_dev_remove_notify_handler(ac->device, ACPI_ALL_NOTIFY,
310284
acpi_ac_notify);
311285
power_supply_unregister(ac->charger);
312286
unregister_acpi_notifier(&ac->battery_nb);
313287

314288
kfree(ac);
315289
}
316290

291+
static struct platform_driver acpi_ac_driver = {
292+
.probe = acpi_ac_probe,
293+
.remove_new = acpi_ac_remove,
294+
.driver = {
295+
.name = "ac",
296+
.acpi_match_table = ac_device_ids,
297+
.pm = &acpi_ac_pm,
298+
},
299+
};
300+
317301
static int __init acpi_ac_init(void)
318302
{
319303
int result;
@@ -326,7 +310,7 @@ static int __init acpi_ac_init(void)
326310

327311
dmi_check_system(ac_dmi_table);
328312

329-
result = acpi_bus_register_driver(&acpi_ac_driver);
313+
result = platform_driver_register(&acpi_ac_driver);
330314
if (result < 0)
331315
return -ENODEV;
332316

@@ -335,7 +319,7 @@ static int __init acpi_ac_init(void)
335319

336320
static void __exit acpi_ac_exit(void)
337321
{
338-
acpi_bus_unregister_driver(&acpi_ac_driver);
322+
platform_driver_unregister(&acpi_ac_driver);
339323
}
340324
module_init(acpi_ac_init);
341325
module_exit(acpi_ac_exit);

drivers/acpi/acpi_fpdt.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
194194
record_header = (void *)subtable_header + offset;
195195
offset += record_header->length;
196196

197+
if (!record_header->length) {
198+
pr_err(FW_BUG "Zero-length record found in FPTD.\n");
199+
result = -EINVAL;
200+
goto err;
201+
}
202+
197203
switch (record_header->type) {
198204
case RECORD_S3_RESUME:
199205
if (subtable_type != SUBTABLE_S3PT) {
200206
pr_err(FW_BUG "Invalid record %d for subtable %s\n",
201207
record_header->type, signature);
202-
return -EINVAL;
208+
result = -EINVAL;
209+
goto err;
203210
}
204211
if (record_resume) {
205212
pr_err("Duplicate resume performance record found.\n");
@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
208215
record_resume = (struct resume_performance_record *)record_header;
209216
result = sysfs_create_group(fpdt_kobj, &resume_attr_group);
210217
if (result)
211-
return result;
218+
goto err;
212219
break;
213220
case RECORD_S3_SUSPEND:
214221
if (subtable_type != SUBTABLE_S3PT) {
@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
223230
record_suspend = (struct suspend_performance_record *)record_header;
224231
result = sysfs_create_group(fpdt_kobj, &suspend_attr_group);
225232
if (result)
226-
return result;
233+
goto err;
227234
break;
228235
case RECORD_BOOT:
229236
if (subtable_type != SUBTABLE_FBPT) {
230237
pr_err(FW_BUG "Invalid %d for subtable %s\n",
231238
record_header->type, signature);
232-
return -EINVAL;
239+
result = -EINVAL;
240+
goto err;
233241
}
234242
if (record_boot) {
235243
pr_err("Duplicate boot performance record found.\n");
@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
238246
record_boot = (struct boot_performance_record *)record_header;
239247
result = sysfs_create_group(fpdt_kobj, &boot_attr_group);
240248
if (result)
241-
return result;
249+
goto err;
242250
break;
243251

244252
default:
@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
247255
}
248256
}
249257
return 0;
258+
259+
err:
260+
if (record_boot)
261+
sysfs_remove_group(fpdt_kobj, &boot_attr_group);
262+
263+
if (record_suspend)
264+
sysfs_remove_group(fpdt_kobj, &suspend_attr_group);
265+
266+
if (record_resume)
267+
sysfs_remove_group(fpdt_kobj, &resume_attr_group);
268+
269+
return result;
250270
}
251271

252272
static int __init acpi_init_fpdt(void)
@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void)
255275
struct acpi_table_header *header;
256276
struct fpdt_subtable_entry *subtable;
257277
u32 offset = sizeof(*header);
278+
int result;
258279

259280
status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);
260281

@@ -263,17 +284,19 @@ static int __init acpi_init_fpdt(void)
263284

264285
fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
265286
if (!fpdt_kobj) {
266-
acpi_put_table(header);
267-
return -ENOMEM;
287+
result = -ENOMEM;
288+
goto err_nomem;
268289
}
269290

270291
while (offset < header->length) {
271292
subtable = (void *)header + offset;
272293
switch (subtable->type) {
273294
case SUBTABLE_FBPT:
274295
case SUBTABLE_S3PT:
275-
fpdt_process_subtable(subtable->address,
296+
result = fpdt_process_subtable(subtable->address,
276297
subtable->type);
298+
if (result)
299+
goto err_subtable;
277300
break;
278301
default:
279302
/* Other types are reserved in ACPI 6.4 spec. */
@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void)
282305
offset += sizeof(*subtable);
283306
}
284307
return 0;
308+
err_subtable:
309+
kobject_put(fpdt_kobj);
310+
311+
err_nomem:
312+
acpi_put_table(header);
313+
return result;
285314
}
286315

287316
fs_initcall(acpi_init_fpdt);

0 commit comments

Comments
 (0)