Skip to content

Commit 45494d7

Browse files
committed
Merge branches 'acpi-scan', 'acpi-bus', 'acpi-tables' and 'acpi-sysfs'
Merge ACPI changes related to device enumeration, device object managenet, operation region handling, table parsing and sysfs interface: - Use ZERO_PAGE(0) instead of empty_zero_page in the ACPI device enumeration code (Giulio Benetti). - Change the return type of the ACPI driver remove callback to void and update its users accordingly (Dawei Li). - Add general support for FFH address space type and implement the low- level part of it for ARM64 (Sudeep Holla). - Fix stale comments in the ACPI tables parsing code and make it print more messages related to MADT (Hanjun Guo, Huacai Chen). - Replace invocations of generic library functions with more kernel- specific counterparts in the ACPI sysfs interface (Christophe JAILLET, Xu Panda). * acpi-scan: ACPI: scan: substitute empty_zero_page with helper ZERO_PAGE(0) * acpi-bus: ACPI: FFH: Silence missing prototype warnings ACPI: make remove callback of ACPI driver void ACPI: bus: Fix the _OSC capability check for FFH OpRegion arm64: Add architecture specific ACPI FFH Opregion callbacks ACPI: Implement a generic FFH Opregion handler * acpi-tables: ACPI: tables: Fix the stale comments for acpi_locate_initial_tables() ACPI: tables: Print CORE_PIC information when MADT is parsed * acpi-sysfs: ACPI: sysfs: use sysfs_emit() to instead of scnprintf() ACPI: sysfs: Use kstrtobool() instead of strtobool()
5 parents 888bc86 + 9256dac + 3223417 + 062c0e3 + 82d08d6 commit 45494d7

Some content is hidden

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

57 files changed

+291
-156
lines changed

arch/arm64/kernel/acpi.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define pr_fmt(fmt) "ACPI: " fmt
1414

1515
#include <linux/acpi.h>
16+
#include <linux/arm-smccc.h>
1617
#include <linux/cpumask.h>
1718
#include <linux/efi.h>
1819
#include <linux/efi-bgrt.h>
@@ -411,3 +412,108 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
411412
{
412413
memblock_mark_nomap(addr, size);
413414
}
415+
416+
#ifdef CONFIG_ACPI_FFH
417+
/*
418+
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
419+
* specified in https://developer.arm.com/docs/den0048/latest
420+
*/
421+
struct acpi_ffh_data {
422+
struct acpi_ffh_info info;
423+
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
424+
unsigned long a2, unsigned long a3,
425+
unsigned long a4, unsigned long a5,
426+
unsigned long a6, unsigned long a7,
427+
struct arm_smccc_res *args,
428+
struct arm_smccc_quirk *res);
429+
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
430+
struct arm_smccc_1_2_regs *res);
431+
};
432+
433+
int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
434+
{
435+
enum arm_smccc_conduit conduit;
436+
struct acpi_ffh_data *ffh_ctxt;
437+
438+
ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
439+
if (!ffh_ctxt)
440+
return -ENOMEM;
441+
442+
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
443+
return -EOPNOTSUPP;
444+
445+
conduit = arm_smccc_1_1_get_conduit();
446+
if (conduit == SMCCC_CONDUIT_NONE) {
447+
pr_err("%s: invalid SMCCC conduit\n", __func__);
448+
return -EOPNOTSUPP;
449+
}
450+
451+
if (conduit == SMCCC_CONDUIT_SMC) {
452+
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
453+
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
454+
} else {
455+
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
456+
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
457+
}
458+
459+
memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
460+
461+
*region_ctxt = ffh_ctxt;
462+
return AE_OK;
463+
}
464+
465+
static bool acpi_ffh_smccc_owner_allowed(u32 fid)
466+
{
467+
int owner = ARM_SMCCC_OWNER_NUM(fid);
468+
469+
if (owner == ARM_SMCCC_OWNER_STANDARD ||
470+
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
471+
return true;
472+
473+
return false;
474+
}
475+
476+
int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
477+
{
478+
int ret = 0;
479+
struct acpi_ffh_data *ffh_ctxt = region_context;
480+
481+
if (ffh_ctxt->info.offset == 0) {
482+
/* SMC/HVC 32bit call */
483+
struct arm_smccc_res res;
484+
u32 a[8] = { 0 }, *ptr = (u32 *)value;
485+
486+
if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
487+
!acpi_ffh_smccc_owner_allowed(*ptr) ||
488+
ffh_ctxt->info.length > 32) {
489+
ret = AE_ERROR;
490+
} else {
491+
int idx, len = ffh_ctxt->info.length >> 2;
492+
493+
for (idx = 0; idx < len; idx++)
494+
a[idx] = *(ptr + idx);
495+
496+
ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
497+
a[5], a[6], a[7], &res, NULL);
498+
memcpy(value, &res, sizeof(res));
499+
}
500+
501+
} else if (ffh_ctxt->info.offset == 1) {
502+
/* SMC/HVC 64bit call */
503+
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
504+
505+
if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
506+
!acpi_ffh_smccc_owner_allowed(r->a0) ||
507+
ffh_ctxt->info.length > sizeof(*r)) {
508+
ret = AE_ERROR;
509+
} else {
510+
ffh_ctxt->invoke_ffh64_fn(r, r);
511+
memcpy(value, r, ffh_ctxt->info.length);
512+
}
513+
} else {
514+
ret = AE_ERROR;
515+
}
516+
517+
return ret;
518+
}
519+
#endif /* CONFIG_ACPI_FFH */

arch/ia64/hp/common/aml_nfw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ static int aml_nfw_add(struct acpi_device *device)
187187
return aml_nfw_add_global_handler();
188188
}
189189

190-
static int aml_nfw_remove(struct acpi_device *device)
190+
static void aml_nfw_remove(struct acpi_device *device)
191191
{
192-
return aml_nfw_remove_global_handler();
192+
aml_nfw_remove_global_handler();
193193
}
194194

195195
static const struct acpi_device_id aml_nfw_ids[] = {

arch/x86/platform/olpc/olpc-xo15-sci.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,12 @@ static int xo15_sci_add(struct acpi_device *device)
183183
return r;
184184
}
185185

186-
static int xo15_sci_remove(struct acpi_device *device)
186+
static void xo15_sci_remove(struct acpi_device *device)
187187
{
188188
acpi_disable_gpe(NULL, xo15_sci_gpe);
189189
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
190190
cancel_work_sync(&sci_work);
191191
sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
192-
return 0;
193192
}
194193

195194
#ifdef CONFIG_PM_SLEEP

drivers/acpi/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,16 @@ config ACPI_PCC
564564
Enable this feature if you want to set up and install the PCC Address
565565
Space handler to handle PCC OpRegion in the firmware.
566566

567+
config ACPI_FFH
568+
bool "ACPI FFH Address Space"
569+
default n
570+
help
571+
The FFH(Fixed Function Hardware) Address Space also referred as FFH
572+
Operation Region allows to define platform specific opregion.
573+
574+
Enable this feature if you want to set up and install the FFH Address
575+
Space handler to handle FFH OpRegion in the firmware.
576+
567577
source "drivers/acpi/pmic/Kconfig"
568578

569579
config ACPI_VIOT

drivers/acpi/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
6868
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
6969
acpi-$(CONFIG_ACPI_PRMT) += prmt.o
7070
acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o
71+
acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o
7172

7273
# Address translation
7374
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o

drivers/acpi/ac.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("ACPI AC Adapter Driver");
3333
MODULE_LICENSE("GPL");
3434

3535
static int acpi_ac_add(struct acpi_device *device);
36-
static int acpi_ac_remove(struct acpi_device *device);
36+
static void acpi_ac_remove(struct acpi_device *device);
3737
static void acpi_ac_notify(struct acpi_device *device, u32 event);
3838

3939
static const struct acpi_device_id ac_device_ids[] = {
@@ -288,21 +288,19 @@ static int acpi_ac_resume(struct device *dev)
288288
#define acpi_ac_resume NULL
289289
#endif
290290

291-
static int acpi_ac_remove(struct acpi_device *device)
291+
static void acpi_ac_remove(struct acpi_device *device)
292292
{
293293
struct acpi_ac *ac = NULL;
294294

295295
if (!device || !acpi_driver_data(device))
296-
return -EINVAL;
296+
return;
297297

298298
ac = acpi_driver_data(device);
299299

300300
power_supply_unregister(ac->charger);
301301
unregister_acpi_notifier(&ac->battery_nb);
302302

303303
kfree(ac);
304-
305-
return 0;
306304
}
307305

308306
static int __init acpi_ac_init(void)

drivers/acpi/acpi_ffh.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Author: Sudeep Holla <[email protected]>
4+
* Copyright 2022 Arm Limited
5+
*/
6+
#include <linux/kernel.h>
7+
#include <linux/acpi.h>
8+
#include <linux/completion.h>
9+
#include <linux/idr.h>
10+
#include <linux/io.h>
11+
12+
#include <linux/arm-smccc.h>
13+
14+
static struct acpi_ffh_info ffh_ctx;
15+
16+
int __weak acpi_ffh_address_space_arch_setup(void *handler_ctxt,
17+
void **region_ctxt)
18+
{
19+
return -EOPNOTSUPP;
20+
}
21+
22+
int __weak acpi_ffh_address_space_arch_handler(acpi_integer *value,
23+
void *region_context)
24+
{
25+
return -EOPNOTSUPP;
26+
}
27+
28+
static acpi_status
29+
acpi_ffh_address_space_setup(acpi_handle region_handle, u32 function,
30+
void *handler_context, void **region_context)
31+
{
32+
return acpi_ffh_address_space_arch_setup(handler_context,
33+
region_context);
34+
}
35+
36+
static acpi_status
37+
acpi_ffh_address_space_handler(u32 function, acpi_physical_address addr,
38+
u32 bits, acpi_integer *value,
39+
void *handler_context, void *region_context)
40+
{
41+
return acpi_ffh_address_space_arch_handler(value, region_context);
42+
}
43+
44+
void __init acpi_init_ffh(void)
45+
{
46+
acpi_status status;
47+
48+
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
49+
ACPI_ADR_SPACE_FIXED_HARDWARE,
50+
&acpi_ffh_address_space_handler,
51+
&acpi_ffh_address_space_setup,
52+
&ffh_ctx);
53+
if (ACPI_FAILURE(status))
54+
pr_alert("OperationRegion handler could not be installed\n");
55+
}

drivers/acpi/acpi_pad.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ static int acpi_pad_add(struct acpi_device *device)
449449
return 0;
450450
}
451451

452-
static int acpi_pad_remove(struct acpi_device *device)
452+
static void acpi_pad_remove(struct acpi_device *device)
453453
{
454454
mutex_lock(&isolated_cpus_lock);
455455
acpi_pad_idle_cpus(0);
@@ -458,7 +458,6 @@ static int acpi_pad_remove(struct acpi_device *device)
458458
acpi_remove_notify_handler(device->handle,
459459
ACPI_DEVICE_NOTIFY, acpi_pad_notify);
460460
acpi_pad_remove_sysfs(device);
461-
return 0;
462461
}
463462

464463
static const struct acpi_device_id pad_device_ids[] = {

drivers/acpi/acpi_video.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static DEFINE_MUTEX(register_count_mutex);
8686
static DEFINE_MUTEX(video_list_lock);
8787
static LIST_HEAD(video_bus_head);
8888
static int acpi_video_bus_add(struct acpi_device *device);
89-
static int acpi_video_bus_remove(struct acpi_device *device);
89+
static void acpi_video_bus_remove(struct acpi_device *device);
9090
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
9191
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
9292
static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
@@ -2067,13 +2067,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
20672067
return error;
20682068
}
20692069

2070-
static int acpi_video_bus_remove(struct acpi_device *device)
2070+
static void acpi_video_bus_remove(struct acpi_device *device)
20712071
{
20722072
struct acpi_video_bus *video = NULL;
20732073

20742074

20752075
if (!device || !acpi_driver_data(device))
2076-
return -EINVAL;
2076+
return;
20772077

20782078
video = acpi_driver_data(device);
20792079

@@ -2087,8 +2087,6 @@ static int acpi_video_bus_remove(struct acpi_device *device)
20872087

20882088
kfree(video->attached_array);
20892089
kfree(video);
2090-
2091-
return 0;
20922090
}
20932091

20942092
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)

drivers/acpi/battery.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,20 +1208,19 @@ static int acpi_battery_add(struct acpi_device *device)
12081208
return result;
12091209
}
12101210

1211-
static int acpi_battery_remove(struct acpi_device *device)
1211+
static void acpi_battery_remove(struct acpi_device *device)
12121212
{
12131213
struct acpi_battery *battery = NULL;
12141214

12151215
if (!device || !acpi_driver_data(device))
1216-
return -EINVAL;
1216+
return;
12171217
device_init_wakeup(&device->dev, 0);
12181218
battery = acpi_driver_data(device);
12191219
unregister_pm_notifier(&battery->pm_nb);
12201220
sysfs_remove_battery(battery);
12211221
mutex_destroy(&battery->lock);
12221222
mutex_destroy(&battery->sysfs_lock);
12231223
kfree(battery);
1224-
return 0;
12251224
}
12261225

12271226
#ifdef CONFIG_PM_SLEEP

0 commit comments

Comments
 (0)