Skip to content

Commit

Permalink
Merge branches 'acpi-scan', 'acpi-bus', 'acpi-tables' and 'acpi-sysfs'
Browse files Browse the repository at this point in the history
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()
  • Loading branch information
Rafael J. Wysocki committed Dec 12, 2022
5 parents 888bc86 + 9256dac + 3223417 + 062c0e3 + 82d08d6 commit 45494d7
Show file tree
Hide file tree
Showing 57 changed files with 291 additions and 156 deletions.
106 changes: 106 additions & 0 deletions arch/arm64/kernel/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define pr_fmt(fmt) "ACPI: " fmt

#include <linux/acpi.h>
#include <linux/arm-smccc.h>
#include <linux/cpumask.h>
#include <linux/efi.h>
#include <linux/efi-bgrt.h>
Expand Down Expand Up @@ -411,3 +412,108 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
{
memblock_mark_nomap(addr, size);
}

#ifdef CONFIG_ACPI_FFH
/*
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
* specified in https://developer.arm.com/docs/den0048/latest
*/
struct acpi_ffh_data {
struct acpi_ffh_info info;
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3,
unsigned long a4, unsigned long a5,
unsigned long a6, unsigned long a7,
struct arm_smccc_res *args,
struct arm_smccc_quirk *res);
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
};

int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
{
enum arm_smccc_conduit conduit;
struct acpi_ffh_data *ffh_ctxt;

ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
if (!ffh_ctxt)
return -ENOMEM;

if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
return -EOPNOTSUPP;

conduit = arm_smccc_1_1_get_conduit();
if (conduit == SMCCC_CONDUIT_NONE) {
pr_err("%s: invalid SMCCC conduit\n", __func__);
return -EOPNOTSUPP;
}

if (conduit == SMCCC_CONDUIT_SMC) {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
} else {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
}

memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));

*region_ctxt = ffh_ctxt;
return AE_OK;
}

static bool acpi_ffh_smccc_owner_allowed(u32 fid)
{
int owner = ARM_SMCCC_OWNER_NUM(fid);

if (owner == ARM_SMCCC_OWNER_STANDARD ||
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
return true;

return false;
}

int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
{
int ret = 0;
struct acpi_ffh_data *ffh_ctxt = region_context;

if (ffh_ctxt->info.offset == 0) {
/* SMC/HVC 32bit call */
struct arm_smccc_res res;
u32 a[8] = { 0 }, *ptr = (u32 *)value;

if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
!acpi_ffh_smccc_owner_allowed(*ptr) ||
ffh_ctxt->info.length > 32) {
ret = AE_ERROR;
} else {
int idx, len = ffh_ctxt->info.length >> 2;

for (idx = 0; idx < len; idx++)
a[idx] = *(ptr + idx);

ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
a[5], a[6], a[7], &res, NULL);
memcpy(value, &res, sizeof(res));
}

} else if (ffh_ctxt->info.offset == 1) {
/* SMC/HVC 64bit call */
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;

if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
!acpi_ffh_smccc_owner_allowed(r->a0) ||
ffh_ctxt->info.length > sizeof(*r)) {
ret = AE_ERROR;
} else {
ffh_ctxt->invoke_ffh64_fn(r, r);
memcpy(value, r, ffh_ctxt->info.length);
}
} else {
ret = AE_ERROR;
}

return ret;
}
#endif /* CONFIG_ACPI_FFH */
4 changes: 2 additions & 2 deletions arch/ia64/hp/common/aml_nfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ static int aml_nfw_add(struct acpi_device *device)
return aml_nfw_add_global_handler();
}

static int aml_nfw_remove(struct acpi_device *device)
static void aml_nfw_remove(struct acpi_device *device)
{
return aml_nfw_remove_global_handler();
aml_nfw_remove_global_handler();
}

static const struct acpi_device_id aml_nfw_ids[] = {
Expand Down
3 changes: 1 addition & 2 deletions arch/x86/platform/olpc/olpc-xo15-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,12 @@ static int xo15_sci_add(struct acpi_device *device)
return r;
}

static int xo15_sci_remove(struct acpi_device *device)
static void xo15_sci_remove(struct acpi_device *device)
{
acpi_disable_gpe(NULL, xo15_sci_gpe);
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
cancel_work_sync(&sci_work);
sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
return 0;
}

#ifdef CONFIG_PM_SLEEP
Expand Down
10 changes: 10 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,16 @@ config ACPI_PCC
Enable this feature if you want to set up and install the PCC Address
Space handler to handle PCC OpRegion in the firmware.

config ACPI_FFH
bool "ACPI FFH Address Space"
default n
help
The FFH(Fixed Function Hardware) Address Space also referred as FFH
Operation Region allows to define platform specific opregion.

Enable this feature if you want to set up and install the FFH Address
Space handler to handle FFH OpRegion in the firmware.

source "drivers/acpi/pmic/Kconfig"

config ACPI_VIOT
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
acpi-$(CONFIG_ACPI_PRMT) += prmt.o
acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o
acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o

# Address translation
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o
Expand Down
8 changes: 3 additions & 5 deletions drivers/acpi/ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ MODULE_DESCRIPTION("ACPI AC Adapter Driver");
MODULE_LICENSE("GPL");

static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device);
static void acpi_ac_remove(struct acpi_device *device);
static void acpi_ac_notify(struct acpi_device *device, u32 event);

static const struct acpi_device_id ac_device_ids[] = {
Expand Down Expand Up @@ -288,21 +288,19 @@ static int acpi_ac_resume(struct device *dev)
#define acpi_ac_resume NULL
#endif

static int acpi_ac_remove(struct acpi_device *device)
static void acpi_ac_remove(struct acpi_device *device)
{
struct acpi_ac *ac = NULL;

if (!device || !acpi_driver_data(device))
return -EINVAL;
return;

ac = acpi_driver_data(device);

power_supply_unregister(ac->charger);
unregister_acpi_notifier(&ac->battery_nb);

kfree(ac);

return 0;
}

static int __init acpi_ac_init(void)
Expand Down
55 changes: 55 additions & 0 deletions drivers/acpi/acpi_ffh.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Author: Sudeep Holla <sudeep.holla@arm.com>
* Copyright 2022 Arm Limited
*/
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/io.h>

#include <linux/arm-smccc.h>

static struct acpi_ffh_info ffh_ctx;

int __weak acpi_ffh_address_space_arch_setup(void *handler_ctxt,
void **region_ctxt)
{
return -EOPNOTSUPP;
}

int __weak acpi_ffh_address_space_arch_handler(acpi_integer *value,
void *region_context)
{
return -EOPNOTSUPP;
}

static acpi_status
acpi_ffh_address_space_setup(acpi_handle region_handle, u32 function,
void *handler_context, void **region_context)
{
return acpi_ffh_address_space_arch_setup(handler_context,
region_context);
}

static acpi_status
acpi_ffh_address_space_handler(u32 function, acpi_physical_address addr,
u32 bits, acpi_integer *value,
void *handler_context, void *region_context)
{
return acpi_ffh_address_space_arch_handler(value, region_context);
}

void __init acpi_init_ffh(void)
{
acpi_status status;

status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_FIXED_HARDWARE,
&acpi_ffh_address_space_handler,
&acpi_ffh_address_space_setup,
&ffh_ctx);
if (ACPI_FAILURE(status))
pr_alert("OperationRegion handler could not be installed\n");
}
3 changes: 1 addition & 2 deletions drivers/acpi/acpi_pad.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ static int acpi_pad_add(struct acpi_device *device)
return 0;
}

static int acpi_pad_remove(struct acpi_device *device)
static void acpi_pad_remove(struct acpi_device *device)
{
mutex_lock(&isolated_cpus_lock);
acpi_pad_idle_cpus(0);
Expand All @@ -458,7 +458,6 @@ static int acpi_pad_remove(struct acpi_device *device)
acpi_remove_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY, acpi_pad_notify);
acpi_pad_remove_sysfs(device);
return 0;
}

static const struct acpi_device_id pad_device_ids[] = {
Expand Down
8 changes: 3 additions & 5 deletions drivers/acpi/acpi_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static DEFINE_MUTEX(register_count_mutex);
static DEFINE_MUTEX(video_list_lock);
static LIST_HEAD(video_bus_head);
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device);
static void acpi_video_bus_remove(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
Expand Down Expand Up @@ -2067,13 +2067,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
return error;
}

static int acpi_video_bus_remove(struct acpi_device *device)
static void acpi_video_bus_remove(struct acpi_device *device)
{
struct acpi_video_bus *video = NULL;


if (!device || !acpi_driver_data(device))
return -EINVAL;
return;

video = acpi_driver_data(device);

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

kfree(video->attached_array);
kfree(video);

return 0;
}

static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)
Expand Down
5 changes: 2 additions & 3 deletions drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -1208,20 +1208,19 @@ static int acpi_battery_add(struct acpi_device *device)
return result;
}

static int acpi_battery_remove(struct acpi_device *device)
static void acpi_battery_remove(struct acpi_device *device)
{
struct acpi_battery *battery = NULL;

if (!device || !acpi_driver_data(device))
return -EINVAL;
return;
device_init_wakeup(&device->dev, 0);
battery = acpi_driver_data(device);
unregister_pm_notifier(&battery->pm_nb);
sysfs_remove_battery(battery);
mutex_destroy(&battery->lock);
mutex_destroy(&battery->sysfs_lock);
kfree(battery);
return 0;
}

#ifdef CONFIG_PM_SLEEP
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ static void acpi_bus_osc_negotiate_platform_control(void)
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
if (IS_ENABLED(CONFIG_ACPI_PRMT))
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
if (IS_ENABLED(CONFIG_ACPI_FFH))
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FFH_OPR_SUPPORT;

#ifdef CONFIG_ARM64
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
Expand Down Expand Up @@ -1408,6 +1410,7 @@ static int __init acpi_init(void)
disable_acpi();
return result;
}
acpi_init_ffh();

pci_mmcfg_late_init();
acpi_iort_init();
Expand Down
5 changes: 2 additions & 3 deletions drivers/acpi/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
};

static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);

#ifdef CONFIG_PM_SLEEP
Expand Down Expand Up @@ -580,14 +580,13 @@ static int acpi_button_add(struct acpi_device *device)
return error;
}

static int acpi_button_remove(struct acpi_device *device)
static void acpi_button_remove(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);

acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
return 0;
}

static int param_set_lid_init_state(const char *val,
Expand Down
5 changes: 2 additions & 3 deletions drivers/acpi/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1663,12 +1663,12 @@ static int acpi_ec_add(struct acpi_device *device)
return ret;
}

static int acpi_ec_remove(struct acpi_device *device)
static void acpi_ec_remove(struct acpi_device *device)
{
struct acpi_ec *ec;

if (!device)
return -EINVAL;
return;

ec = acpi_driver_data(device);
release_region(ec->data_addr, 1);
Expand All @@ -1678,7 +1678,6 @@ static int acpi_ec_remove(struct acpi_device *device)
ec_remove_handlers(ec);
acpi_ec_free(ec);
}
return 0;
}

static acpi_status
Expand Down
Loading

0 comments on commit 45494d7

Please sign in to comment.