Commit 5e692824 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'acpi-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI updates from Rafael Wysocki:
 "These update the ACPICA code in the kernel to the 20210604 upstream
  revision, add preliminary support for the Platform Runtime Mechanism
  (PRM), address issues related to the handling of device dependencies
  in the ACPI device eunmeration code, improve the tracking of ACPI
  power resource states, improve the ACPI support for suspend-to-idle on
  AMD systems, continue the unification of message printing in the ACPI
  code, address assorted issues and clean up the code in a number of
  places.

  Specifics:

   - Update ACPICA code in the kernel to upstrea revision 20210604
     including the following changes:

      - Add defines for the CXL Host Bridge Structureand and add the
        CFMWS structure definition to CEDT (Alison Schofield).
      - iASL: Finish support for the IVRS ACPI table (Bob Moore).
      - iASL: Add support for the SVKL table (Bob Moore).
      - iASL: Add full support for RGRT ACPI table (Bob Moore).
      - iASL: Add support for the BDAT ACPI table (Bob Moore).
      - iASL: add disassembler support for PRMT (Erik Kaneda).
      - Fix memory leak caused by _CID repair function (Erik Kaneda).
      - Add support for PlatformRtMechanism OpRegion (Erik Kaneda).
      - Add PRMT module header to facilitate parsing (Erik Kaneda).
      - Add _PLD panel positions (Fabian Wüthrich).
      - MADT: add Multiprocessor Wakeup Mailbox Structure and the SVKL
        table headers (Kuppuswamy Sathyanarayanan).
      - Use ACPI_FALLTHROUGH (Wei Ming Chen).

   - Add preliminary support for the Platform Runtime Mechanism (PRM) to
     allow the AML interpreter to call PRM functions (Erik Kaneda).

   - Address some issues related to the handling of device dependencies
     reported by _DEP in the ACPI device enumeration code and clean up
     some related pieces of it (Rafael Wysocki).

   - Improve the tracking of states of ACPI power resources (Rafael
     Wysocki).

   - Improve ACPI support for suspend-to-idle on AMD systems (Alex
     Deucher, Mario Limonciello, Pratik Vishwakarma).

   - Continue the unification and cleanup of message printing in the
     ACPI code (Hanjun Guo, Heiner Kallweit).

   - Fix possible buffer overrun issue with the description_show() sysfs
     attribute method (Krzysztof Wilczyński).

   - Improve the acpi_mask_gpe kernel command line parameter handling
     and clean up the core ACPI code related to sysfs (Andy Shevchenko,
     Baokun Li, Clayton Casciato).

   - Postpone bringing devices in the general ACPI PM domain to D0
     during resume from system-wide suspend until they are really needed
     (Dmitry Torokhov).

   - Make the ACPI processor driver fix up C-state latency if not
     ordered (Mario Limonciello).

   - Add support for identifying devices depening on the given one that
     are not its direct descendants with the help of _DEP (Daniel
     Scally).

   - Extend the checks related to ACPI IRQ overrides on x86 in order to
     avoid false-positives (Hui Wang).

   - Add battery DPTF participant for Intel SoCs (Sumeet Pawnikar).

   - Rearrange the ACPI fan driver and device power management code to
     use a common list of device IDs (Rafael Wysocki).

   - Fix clang CFI violation in the ACPI BGRT table parsing code and
     clean it up (Nathan Chancellor).

   - Add GPE-related quirks for some laptops to the EC driver (Chris
     Chiu, Zhang Rui).

   - Make the ACPI PPTT table parsing code populate the cache-id value
     if present in the firmware (James Morse).

   - Remove redundant clearing of context->ret.pointer from
     acpi_run_osc() (Hans de Goede).

   - Add missing acpi_put_table() in acpi_init_fpdt() (Jing Xiangfeng).

   - Make ACPI APEI handle ARM Processor Error CPER records like Memory
     Error ones to avoid user space task lockups (Xiaofei Tan).

   - Stop warning about disabled ACPI in APEI (Jon Hunter).

   - Fix fall-through warning for Clang in the SBSHC driver (Gustavo A.
     R. Silva).

   - Add custom DSDT file as Makefile prerequisite (Richard Fitzgerald).

   - Initialize local variable to avoid garbage being returned (Colin
     Ian King).

   - Simplify assorted pieces of code, address assorted coding style and
     documentation issues and comment typos (Baokun Li, Christophe
     JAILLET, Clayton Casciato, Liu Shixin, Shaokun Zhang, Wei Yongjun,
     Yang Li, Zhen Lei)"

* tag 'acpi-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (97 commits)
  ACPI: PM: postpone bringing devices to D0 unless we need them
  ACPI: tables: Add custom DSDT file as makefile prerequisite
  ACPI: bgrt: Use sysfs_emit
  ACPI: bgrt: Fix CFI violation
  ACPI: EC: trust DSDT GPE for certain HP laptop
  ACPI: scan: Simplify acpi_table_events_fn()
  ACPI: PM: Adjust behavior for field problems on AMD systems
  ACPI: PM: s2idle: Add support for new Microsoft UUID
  ACPI: PM: s2idle: Add support for multiple func mask
  ACPI: PM: s2idle: Refactor common code
  ACPI: PM: s2idle: Use correct revision id
  ACPI: sysfs: Remove tailing return statement in void function
  ACPI: sysfs: Use __ATTR_RO() and __ATTR_RW() macros
  ACPI: sysfs: Sort headers alphabetically
  ACPI: sysfs: Refactor param_get_trace_state() to drop dead code
  ACPI: sysfs: Unify pattern of memory allocations
  ACPI: sysfs: Allow bitmap list to be supplied to acpi_mask_gpe
  ACPI: sysfs: Make sparse happy about address space in use
  ACPI: scan: Fix race related to dropping dependencies
  ACPI: scan: Reorganize acpi_device_add()
  ...
parents 3563f55c 64f9111d
......@@ -113,7 +113,7 @@
the GPE dispatcher.
This facility can be used to prevent such uncontrolled
GPE floodings.
Format: <byte>
Format: <byte> or <bitmap-list>
acpi_no_auto_serialize [HW,ACPI]
Disable auto-serialization of AML methods
......
This diff is collapsed.
......@@ -543,3 +543,8 @@ config X86_PM_TIMER
You should nearly always say Y here because many modern
systems require this timer.
config ACPI_PRMT
bool "Platform Runtime Mechanism Support"
depends on EFI && X86_64
default y
......@@ -8,6 +8,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
#
# ACPI Boot-Time Table Parsing
#
ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y)
tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ;
endif
obj-$(CONFIG_ACPI) += tables.o
obj-$(CONFIG_X86) += blacklist.o
......@@ -61,6 +66,7 @@ acpi-$(CONFIG_ACPI_FPDT) += acpi_fpdt.o
acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o
acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
acpi-$(CONFIG_ACPI_PRMT) += prmt.o
# Address translation
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o
......
......@@ -6,6 +6,8 @@
* Authors: Lan Tianyu <tianyu.lan@intel.com>
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/err.h>
......@@ -59,7 +61,7 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
&acpi_cmos_rtc_space_handler,
NULL, NULL);
if (ACPI_FAILURE(status)) {
pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
pr_err("Error installing CMOS-RTC region handler\n");
return -ENODEV;
}
......@@ -70,7 +72,7 @@ static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
{
if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
pr_err("Error removing CMOS-RTC region handler\n");
}
static struct acpi_scan_handler cmos_rtc_handler = {
......
......@@ -13,9 +13,6 @@
#include <linux/acpi.h>
#include <linux/security.h>
#include "acpica/accommon.h"
#include "acpica/actables.h"
static struct config_group *acpi_table_group;
struct acpi_table {
......@@ -226,7 +223,7 @@ static void acpi_table_drop_item(struct config_group *group,
{
struct acpi_table *table = container_of(cfg, struct acpi_table, cfg);
ACPI_INFO(("Host-directed Dynamic ACPI Table Unload"));
pr_debug("Host-directed Dynamic ACPI Table Unload\n");
acpi_unload_table(table->index);
config_item_put(cfg);
}
......
......@@ -240,8 +240,10 @@ static int __init acpi_init_fpdt(void)
return 0;
fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
if (!fpdt_kobj)
if (!fpdt_kobj) {
acpi_put_table(header);
return -ENOMEM;
}
while (offset < header->length) {
subtable = (void *)header + offset;
......
......@@ -597,9 +597,14 @@ static int __init acpi_ipmi_init(void)
pr_warn("Can't register IPMI opregion space handle\n");
return -EINVAL;
}
result = ipmi_smi_watcher_register(&driver_data.bmc_events);
if (result)
if (result) {
acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_IPMI,
&acpi_ipmi_space_handler);
pr_err("Can't register IPMI system interface watcher\n");
}
return result;
}
......
......@@ -186,13 +186,12 @@ static void byt_i2c_setup(struct lpss_private_data *pdata)
long uid = 0;
/* Expected to always be true, but better safe then sorry */
if (uid_str)
uid = simple_strtol(uid_str, NULL, 10);
if (uid_str && !kstrtol(uid_str, 10, &uid) && uid) {
/* Detect I2C bus shared with PUNIT and ignore its d3 status */
status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
if (ACPI_SUCCESS(status) && shared_host && uid)
if (ACPI_SUCCESS(status) && shared_host)
pmc_atom_d3_mask &= ~(BIT_LPSS2_F1_I2C1 << (uid - 1));
}
lpss_deassert_reset(pdata);
......
......@@ -1619,8 +1619,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
input_report_key(input, keycode, 0);
input_sync(input);
}
return;
}
static void brightness_switch_event(struct acpi_video_device *video_device,
......@@ -1690,8 +1688,6 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
input_report_key(input, keycode, 0);
input_sync(input);
}
return;
}
static int acpi_video_resume(struct notifier_block *nb,
......@@ -2308,8 +2304,6 @@ static void __exit acpi_video_exit(void)
{
acpi_video_detect_exit();
acpi_video_unregister();
return;
}
module_init(acpi_video_init);
......
......@@ -737,6 +737,8 @@ const char *acpi_ah_match_uuid(u8 *data);
*/
#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP)
void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer);
acpi_status acpi_ut_convert_uuid_to_string(char *uuid_buffer, char *out_string);
#endif
#endif /* _ACUTILS_H */
......@@ -139,7 +139,9 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI)) {
ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) {
/* SMBus, GSBus, IPMI serial */
......@@ -301,7 +303,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI)) {
ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) {
/* SMBus, GSBus, IPMI serial */
......
......@@ -195,6 +195,12 @@ acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc,
function = ACPI_READ | (accessor_type << 16);
break;
case ACPI_ADR_SPACE_PLATFORM_RT:
buffer_length = ACPI_PRM_INPUT_BUFFER_SIZE;
function = ACPI_READ;
break;
default:
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
}
......@@ -311,6 +317,12 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
function = ACPI_WRITE | (accessor_type << 16);
break;
case ACPI_ADR_SPACE_PLATFORM_RT:
buffer_length = ACPI_PRM_INPUT_BUFFER_SIZE;
function = ACPI_WRITE;
break;
default:
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
}
......
......@@ -379,6 +379,13 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info,
(*element_ptr)->common.reference_count =
original_ref_count;
/*
* The original_element holds a reference from the package object
* that represents _HID. Since a new element was created by _HID,
* remove the reference from the _CID package.
*/
acpi_ut_remove_reference(original_element);
}
element_ptr++;
......
......@@ -475,7 +475,7 @@ int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
case 'X':
type |= ACPI_FORMAT_UPPER;
/* FALLTHROUGH */
ACPI_FALLTHROUGH;
case 'x':
......
......@@ -61,4 +61,45 @@ void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer)
1]);
}
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_convert_uuid_to_string
*
* PARAMETERS: uuid_buffer - 16-byte UUID buffer
* out_string - 36-byte formatted UUID string
*
* RETURN: Status
*
* DESCRIPTION: Convert 16-byte UUID buffer to 36-byte formatted UUID string
* out_string must be 37 bytes to include null terminator.
*
******************************************************************************/
acpi_status acpi_ut_convert_uuid_to_string(char *uuid_buffer, char *out_string)
{
u32 i;
if (!uuid_buffer || !out_string) {
return (AE_BAD_PARAMETER);
}
for (i = 0; i < UUID_BUFFER_LENGTH; i++) {
out_string[acpi_gbl_map_to_uuid_offset[i]] =
acpi_ut_hex_to_ascii_char(uuid_buffer[i], 4);
out_string[acpi_gbl_map_to_uuid_offset[i] + 1] =
acpi_ut_hex_to_ascii_char(uuid_buffer[i], 0);
}
/* Insert required hyphens (dashes) */
out_string[UUID_HYPHEN1_OFFSET] =
out_string[UUID_HYPHEN2_OFFSET] =
out_string[UUID_HYPHEN3_OFFSET] =
out_string[UUID_HYPHEN4_OFFSET] = '-';
out_string[UUID_STRING_LENGTH] = 0; /* Null terminate */
return (AE_OK);
}
#endif
......@@ -673,7 +673,7 @@ static int __init einj_init(void)
struct apei_exec_context ctx;
if (acpi_disabled) {
pr_warn("ACPI disabled.\n");
pr_info("ACPI disabled.\n");
return -ENODEV;
}
......
......@@ -441,28 +441,35 @@ static void ghes_kick_task_work(struct callback_head *head)
gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
}
static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
int sev)
static bool ghes_do_memory_failure(u64 physical_addr, int flags)
{
unsigned long pfn;
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity);
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
return false;
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return false;
pfn = mem_err->physical_addr >> PAGE_SHIFT;
pfn = PHYS_PFN(physical_addr);
if (!pfn_valid(pfn)) {
pr_warn_ratelimited(FW_WARN GHES_PFX
"Invalid address in generic error data: %#llx\n",
mem_err->physical_addr);
physical_addr);
return false;
}
memory_failure_queue(pfn, flags);
return true;
}
static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
int sev)
{
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity);
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return false;
/* iff following two events can be handled properly by now */
if (sec_sev == GHES_SEV_CORRECTED &&
(gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
......@@ -470,14 +477,56 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
flags = 0;
if (flags != -1) {
memory_failure_queue(pfn, flags);
return true;
}
if (flags != -1)
return ghes_do_memory_failure(mem_err->physical_addr, flags);
return false;
}
static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
{
struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
bool queued = false;
int sec_sev, i;
char *p;
log_arm_hw_error(err);
sec_sev = ghes_severity(gdata->error_severity);
if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE)
return false;
p = (char *)(err + 1);
for (i = 0; i < err->err_info_num; i++) {
struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p;
bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR);
bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR);
const char *error_type = "unknown error";
/*
* The field (err_info->error_info & BIT(26)) is fixed to set to
* 1 in some old firmware of HiSilicon Kunpeng920. We assume that
* firmware won't mix corrected errors in an uncorrected section,
* and don't filter out 'corrected' error here.
*/
if (is_cache && has_pa) {
queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0);
p += err_info->length;
continue;
}
if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs))
error_type = cper_proc_error_type_strs[err_info->type];
pr_warn_ratelimited(FW_WARN GHES_PFX
"Unhandled processor error type: %s\n",
error_type);
p += err_info->length;
}
return queued;
}
/*
* PCIe AER errors need to be sent to the AER driver for reporting and
* recovery. The GHES severities map to the following AER severities and
......@@ -605,9 +654,7 @@ static bool ghes_do_proc(struct ghes *ghes,
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
log_arm_hw_error(err);
queued = ghes_handle_arm_hw_error(gdata, sev);
} else {
void *err = acpi_hest_get_payload(gdata);
......
......@@ -15,40 +15,19 @@
static void *bgrt_image;
static struct kobject *bgrt_kobj;
static ssize_t version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version);
}
static DEVICE_ATTR_RO(version);
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status);
}
static DEVICE_ATTR_RO(status);
static ssize_t type_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type);
}
static DEVICE_ATTR_RO(type);
static ssize_t xoffset_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x);
}
static DEVICE_ATTR_RO(xoffset);
static ssize_t yoffset_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y);
}
static DEVICE_ATTR_RO(yoffset);
#define BGRT_SHOW(_name, _member) \
static ssize_t _name##_show(struct kobject *kobj, \
struct kobj_attribute *attr, char *buf) \
{ \
return sysfs_emit(buf, "%d\n", bgrt_tab._member); \
} \
struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
BGRT_SHOW(version, version);
BGRT_SHOW(status, status);
BGRT_SHOW(type, image_type);
BGRT_SHOW(xoffset, image_offset_x);
BGRT_SHOW(yoffset, image_offset_y);
static ssize_t image_read(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t off, size_t count)
......@@ -60,11 +39,11 @@ static ssize_t image_read(struct file *file, struct kobject *kobj,
static BIN_ATTR_RO(image, 0); /* size gets filled in later */
static struct attribute *bgrt_attributes[] = {
&dev_attr_version.attr,
&dev_attr_status.attr,
&dev_attr_type.attr,
&dev_attr_xoffset.attr,
&dev_attr_yoffset.attr,
&bgrt_attr_version.attr,
&bgrt_attr_status.attr,
&bgrt_attr_type.attr,
&bgrt_attr_xoffset.attr,
&bgrt_attr_yoffset.attr,
NULL,
};
......
......@@ -10,6 +10,8 @@
* Copyright (C) 2002 Andy Grover <andrew.grover@intel.com>
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/acpi.h>
......@@ -49,12 +51,12 @@ int __init acpi_blacklisted(void)
i = acpi_match_platform_list(acpi_blacklist);
if (i >= 0) {
pr_err(PREFIX "Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n",
pr_err("Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n",
acpi_blacklist[i].oem_id,
acpi_blacklist[i].oem_table_id,
acpi_blacklist[i].oem_revision);
pr_err(PREFIX "Reason: %s. This is a %s error\n",
pr_err("Reason: %s. This is a %s error\n",
acpi_blacklist[i].reason,
(acpi_blacklist[i].data ?
"non-recoverable" : "recoverable"));
......@@ -73,8 +75,7 @@ int __init acpi_blacklisted(void)
#ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
{
printk(KERN_NOTICE PREFIX "DMI detected: %s (force ACPI _REV to 5)\n",
d->ident);
pr_notice("DMI detected: %s (force ACPI _REV to 5)\n", d->ident);
acpi_rev_override_setup(NULL);
return 0;
}
......
......@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <acpi/apei.h>
#include <linux/suspend.h>
#include <linux/prmt.h>
#include "internal.h"
......@@ -262,8 +263,6 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
out_kfree:
kfree(output.pointer);
if (status != AE_OK)
context->ret.pointer = NULL;
return status;
}
EXPORT_SYMBOL(acpi_run_osc);
......@@ -304,6 +303,7 @@ static void acpi_bus_osc_negotiate_platform_control(void)
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
#ifdef CONFIG_ARM64
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
......@@ -359,7 +359,7 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_control);
static void acpi_bus_decode_usb_osc(const char *msg, u32 bits)
{
printk(KERN_INFO PREFIX "%s USB3%c DisplayPort%c PCIe%c XDomain%c\n", msg,
pr_info("%s USB3%c DisplayPort%c PCIe%c XDomain%c\n", msg,
(bits & OSC_USB_USB3_TUNNELING) ? '+' : '-',
(bits & OSC_USB_DP_TUNNELING) ? '+' : '-',
(bits & OSC_USB_PCIE_TUNNELING) ? '+' : '-',
......@@ -398,7 +398,7 @@ static void acpi_bus_osc_negotiate_usb_control(void)
return;
if (context.ret.length != sizeof(capbuf)) {
printk(KERN_INFO PREFIX "USB4 _OSC: returned invalid length buffer\n");
pr_info("USB4 _OSC: returned invalid length buffer\n");
goto out_free;
}
......@@ -1195,7 +1195,8 @@ void __init acpi_subsystem_init(void)
static acpi_status acpi_bus_table_handler(u32 event, void *table, void *context)
{
acpi_scan_table_handler(event, table, context);
if (event == ACPI_TABLE_EVENT_LOAD)
acpi_scan_table_notify();
return acpi_sysfs_table_handler(event, table, context);
}
......@@ -1314,13 +1315,13 @@ static int __init acpi_init(void)
}
acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
if (!acpi_kobj) {
if (!acpi_kobj)
pr_debug("%s: kset create error\n", __func__);
acpi_kobj = NULL;
}
init_prmt();
result = acpi_bus_init();
if (result) {
kobject_put(acpi_kobj);
disable_acpi();
return result;
}
......
......@@ -20,6 +20,7 @@
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include "fan.h"
#include "internal.h"
/**
......@@ -1133,19 +1134,48 @@ static int acpi_subsys_resume_noirq(struct device *dev)
*
* Use ACPI to put the given device into the full-power state and carry out the
* generic early resume procedure for it during system transition into the
* working state.
* working state, but only do that if device either defines early resume
* handler, or does not define power operations at all. Otherwise powering up
* of the device is postponed to the normal resume phase.
*/
static int acpi_subsys_resume_early(struct device *dev)
{
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret;
if (dev_pm_skip_resume(dev))
return 0;
if (pm && !pm->resume_early) {
dev_dbg(dev, "postponing D0 transition to normal resume stage\n");
return 0;
}
ret = acpi_dev_resume(dev);
return ret ? ret : pm_generic_resume_early(dev);
}
/**
* acpi_subsys_resume - Resume device using ACPI.
* @dev: Device to Resume.
*
* Use ACPI to put the given device into the full-power state if it has not been
* powered up during early resume phase, and carry out the generic resume
* procedure for it during system transition into the working state.
*/
static int acpi_subsys_resume(struct device *dev)
{
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret = 0;
if (!dev_pm_skip_resume(dev) && pm && !pm->resume_early) {
dev_dbg(dev, "executing postponed D0 transition\n");
ret = acpi_dev_resume(dev);
}
return ret ? ret : pm_generic_resume(dev);
}
/**
* acpi_subsys_freeze - Run the device driver's freeze callback.
* @dev: Device to handle.
......@@ -1239,6 +1269,7 @@ static struct dev_pm_domain acpi_general_pm_domain = {
.prepare = acpi_subsys_prepare,
.complete = acpi_subsys_complete,
.suspend = acpi_subsys_suspend,
.resume = acpi_subsys_resume,
.suspend_late = acpi_subsys_suspend_late,
.suspend_noirq = acpi_subsys_suspend_noirq,
.resume_noirq = acpi_subsys_resume_noirq,
......@@ -1310,10 +1341,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
* with the generic ACPI PM domain.
*/
static const struct acpi_device_id special_pm_ids[] = {
{"PNP0C0B", }, /* Generic ACPI fan */
{"INT3404", }, /* Fan */
{"INTC1044", }, /* Fan for Tiger Lake generation */
{"INTC1048", }, /* Fan for Alder Lake generation */
ACPI_FAN_DEVICE_IDS,
{}
};
struct acpi_device *adev = ACPI_COMPANION(dev);
......
......@@ -268,6 +268,8 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev,
/**
* acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices.
* @dev: Struct device to get ACPI device node.
* @env: Environment variables of the kobject uevent.
*
* Create the uevent modalias field for ACPI-enumerated devices.
*
......@@ -313,6 +315,9 @@ static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size)
/**
* acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices.
* @dev: Struct device to get ACPI device node.
* @buf: The buffer to save pnp_modalias and of_modalias.
* @size: Size of buffer.
*
* Create the modalias sysfs attribute for ACPI-enumerated devices.
*
......@@ -448,7 +453,7 @@ static ssize_t description_show(struct device *dev,
(wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
acpi_dev->pnp.str_obj->buffer.length,
UTF16_LITTLE_ENDIAN, buf,
PAGE_SIZE);
PAGE_SIZE - 1);
buf[result++] = '\n';
......
......@@ -24,6 +24,7 @@ static const struct acpi_device_id int340x_thermal_device_ids[] = {
{"INT3409"},
{"INT340A"},
{"INT340B"},
{"INT3532"},
{"INTC1040"},
{"INTC1041"},
{"INTC1043"},
......@@ -33,6 +34,7 @@ static const struct acpi_device_id int340x_thermal_device_ids[] = {
{"INTC1047"},
{"INTC1048"},
{"INTC1049"},
{"INTC1050"},
{"INTC1060"},
{"INTC1061"},
{""},
......
......@@ -183,6 +183,7 @@ static struct workqueue_struct *ec_query_wq;
static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
/* --------------------------------------------------------------------------
......@@ -1593,7 +1594,8 @@ static int acpi_ec_add(struct acpi_device *device)
}
if (boot_ec && ec->command_addr == boot_ec->command_addr &&
ec->data_addr == boot_ec->data_addr) {
ec->data_addr == boot_ec->data_addr &&
!EC_FLAGS_TRUST_DSDT_GPE) {
/*
* Trust PNP0C09 namespace location rather than
* ECDT ID. But trust ECDT GPE rather than _GPE
......@@ -1627,7 +1629,7 @@ static int acpi_ec_add(struct acpi_device *device)
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
/* Reprobe devices depending on the EC */
acpi_walk_dep_device_list(ec->handle);
acpi_dev_clear_dependencies(device);
acpi_handle_debug(ec->handle, "enumerated.\n");
return 0;
......@@ -1816,6 +1818,18 @@ static int ec_correct_ecdt(const struct dmi_system_id *id)
return 0;
}
/*
* Some ECDTs contain wrong GPE setting, but they share the same port addresses
* with DSDT EC, don't duplicate the DSDT EC with ECDT EC in this case.
* https://bugzilla.kernel.org/show_bug.cgi?id=209989
*/
static int ec_honor_dsdt_gpe(const struct dmi_system_id *id)
{
pr_debug("Detected system needing DSDT GPE setting.\n");
EC_FLAGS_TRUST_DSDT_GPE = 1;
return 0;
}
/*
* Some DSDTs contain wrong GPE setting.
* Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
......@@ -1846,6 +1860,22 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
{
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL},
{
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL},
{
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL},
{
ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL},
{
ec_honor_ecdt_gpe, "ASUS X550VXK", {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
......@@ -1854,6 +1884,11 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
{
/* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */
ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL},
{
ec_clear_on_resume, "Samsung hardware", {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
{},
......
......@@ -7,6 +7,8 @@
*
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/proc_fs.h>
......@@ -165,7 +167,7 @@ static int acpi_event_genetlink_init(void)
static int __init acpi_event_init(void)
{
int error = 0;
int error;
if (acpi_disabled)
return 0;
......@@ -173,8 +175,8 @@ static int __init acpi_event_init(void)
/* create genetlink for acpi event */
error = acpi_event_genetlink_init();
if (error)
printk(KERN_WARNING PREFIX
"Failed to create genetlink family for ACPI event\n");
pr_warn("Failed to create genetlink family for ACPI event\n");
return 0;
}
......
......@@ -16,6 +16,8 @@
#include <linux/platform_device.h>
#include <linux/sort.h>
#include "fan.h"
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Fan Driver");
MODULE_LICENSE("GPL");
......@@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev);
static int acpi_fan_remove(struct platform_device *pdev);
static const struct acpi_device_id fan_device_ids[] = {
{"PNP0C0B", 0},
{"INT3404", 0},
{"INTC1044", 0},
{"INTC1048", 0},
ACPI_FAN_DEVICE_IDS,
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, fan_device_ids);
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ACPI fan device IDs are shared between the fan driver and the device power
* management code.
*
* Add new device IDs before the generic ACPI fan one.
*/
#define ACPI_FAN_DEVICE_IDS \
{"INT3404", }, /* Fan */ \
{"INTC1044", }, /* Fan for Tiger Lake generation */ \
{"INTC1048", }, /* Fan for Alder Lake generation */ \
{"PNP0C0B", } /* Generic ACPI fan */
......@@ -6,6 +6,8 @@
* Copyright (c) 2005 Intel Corp.
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi_iort.h>
#include <linux/export.h>
#include <linux/init.h>
......@@ -19,17 +21,6 @@
#include "internal.h"
#define ACPI_GLUE_DEBUG 0
#if ACPI_GLUE_DEBUG
#define DBG(fmt, ...) \
printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...) \
do { \
if (0) \
printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__); \
} while (0)
#endif
static LIST_HEAD(bus_type_list);
static DECLARE_RWSEM(bus_type_sem);
......@@ -44,7 +35,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
down_write(&bus_type_sem);
list_add_tail(&type->list, &bus_type_list);
up_write(&bus_type_sem);
printk(KERN_INFO PREFIX "bus type %s registered\n", type->name);
pr_info("bus type %s registered\n", type->name);
return 0;
}
return -ENODEV;
......@@ -59,8 +50,7 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
down_write(&bus_type_sem);
list_del_init(&type->list);
up_write(&bus_type_sem);
printk(KERN_INFO PREFIX "bus type %s unregistered\n",
type->name);
pr_info("bus type %s unregistered\n", type->name);
return 0;
}
return -ENODEV;
......@@ -307,7 +297,7 @@ static int acpi_device_notify(struct device *dev)
adev = type->find_companion(dev);
if (!adev) {
DBG("Unable to get handle for %s\n", dev_name(dev));
pr_debug("Unable to get handle for %s\n", dev_name(dev));
ret = -ENODEV;
goto out;
}
......@@ -328,16 +318,15 @@ static int acpi_device_notify(struct device *dev)
adev->handler->bind(dev);
out:
#if ACPI_GLUE_DEBUG
if (!ret) {
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer);
DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
pr_debug("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer);
} else
DBG("Device %s -> No ACPI support\n", dev_name(dev));
#endif
} else {
pr_debug("Device %s -> No ACPI support\n", dev_name(dev));
}
return ret;
}
......
......@@ -11,8 +11,6 @@
#include <linux/idr.h>
#define PREFIX "ACPI: "
int early_acpi_osi_init(void);
int acpi_osi_init(void);
acpi_status acpi_os_initialize1(void);
......@@ -88,7 +86,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src);
bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context);
void acpi_scan_table_handler(u32 event, void *table, void *context);
void acpi_scan_table_notify(void);
/* --------------------------------------------------------------------------
Device Node Initialization / Removal
......@@ -142,7 +140,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
int acpi_power_on_resources(struct acpi_device *device, int state);
int acpi_power_transition(struct acpi_device *device, int state);
void acpi_turn_off_unused_power_resources(bool init);
void acpi_turn_off_unused_power_resources(void);
/* --------------------------------------------------------------------------
Device Power Management
......
......@@ -5,6 +5,8 @@
* Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*/
#define pr_fmt(fmt) "ACPI: PM: " fmt
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
......@@ -83,8 +85,8 @@ static LIST_HEAD(nvs_list);
/**
* suspend_nvs_register - register platform NVS memory region to save
* @start - physical address of the region
* @size - size of the region
* @start: Physical address of the region.
* @size: Size of the region.
*
* The NVS region need not be page-aligned (both ends) and we arrange
* things so that the data from page-aligned addresses in this region will
......@@ -94,7 +96,7 @@ static int suspend_nvs_register(unsigned long start, unsigned long size)
{
struct nvs_page *entry, *next;
pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n",
pr_info("Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n",
start, start + size - 1, size);
while (size > 0) {
......@@ -170,7 +172,7 @@ int suspend_nvs_save(void)
{
struct nvs_page *entry;
printk(KERN_INFO "PM: Saving platform NVS memory\n");
pr_info("Saving platform NVS memory\n");
list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
......@@ -202,7 +204,7 @@ void suspend_nvs_restore(void)
{
struct nvs_page *entry;
printk(KERN_INFO "PM: Restoring platform NVS memory\n");
pr_info("Restoring platform NVS memory\n");
list_for_each_entry(entry, &nvs_list, node)
if (entry->data)
......
......@@ -212,7 +212,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
return efi.acpi20;
if (efi.acpi != EFI_INVALID_TABLE_ADDR)
return efi.acpi;
pr_err(PREFIX "System description tables not found\n");
pr_err("System description tables not found\n");
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
acpi_find_root_pointer(&pa);
}
......@@ -430,7 +430,7 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
map = acpi_map_lookup_virt(virt, size);
if (!map) {
mutex_unlock(&acpi_ioremap_lock);
WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
WARN(true, "ACPI: %s: bad address %p\n", __func__, virt);
return;
}
acpi_os_drop_map_ref(map);
......@@ -1487,12 +1487,7 @@ EXPORT_SYMBOL(acpi_check_resource_conflict);
int acpi_check_region(resource_size_t start, resource_size_t n,
const char *name)
{
struct resource res = {
.start = start,
.end = start + n - 1,
.name = name,
.flags = IORESOURCE_IO,
};
struct resource res = DEFINE_RES_IO_NAMED(start, n, name);
return acpi_check_resource_conflict(&res);
}
......
......@@ -6,6 +6,8 @@
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
......@@ -574,7 +576,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
goto end;
}
pr_info(PREFIX "%s [%s] (domain %04x %pR)\n",
pr_info("%s [%s] (domain %04x %pR)\n",
acpi_device_name(device), acpi_device_bid(device),
root->segment, &root->secondary);
......
......@@ -117,7 +117,7 @@ static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev)
return err;
/* Re-enumerate devices depending on PMIC */
acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent));
acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent));
return 0;
}
......
......@@ -52,7 +52,7 @@ struct acpi_power_resource {
u32 system_level;
u32 order;
unsigned int ref_count;
unsigned int users;
u8 state;
bool wakeup_enabled;
struct mutex resource_lock;
struct list_head dependents;
......@@ -173,8 +173,6 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
err = acpi_power_resources_list_add(rhandle, list);
if (err)
break;
to_power_resource(rdev)->users++;
}
if (err)
acpi_power_resources_list_free(list);
......@@ -182,44 +180,54 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
return err;
}
static int acpi_power_get_state(acpi_handle handle, int *state)
static int __get_state(acpi_handle handle, u8 *state)
{
acpi_status status = AE_OK;
unsigned long long sta = 0;
if (!handle || !state)
return -EINVAL;
u8 cur_state;
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status))
return -ENODEV;
*state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
ACPI_POWER_RESOURCE_STATE_OFF;
cur_state = sta & ACPI_POWER_RESOURCE_STATE_ON;
acpi_handle_debug(handle, "Power resource is %s\n",
*state ? "on" : "off");
cur_state ? "on" : "off");
*state = cur_state;
return 0;
}
static int acpi_power_get_state(struct acpi_power_resource *resource, u8 *state)
{
if (resource->state == ACPI_POWER_RESOURCE_STATE_UNKNOWN) {
int ret;
ret = __get_state(resource->device.handle, &resource->state);
if (ret)
return ret;
}
*state = resource->state;
return 0;
}
static int acpi_power_get_list_state(struct list_head *list, int *state)
static int acpi_power_get_list_state(struct list_head *list, u8 *state)
{
struct acpi_power_resource_entry *entry;
int cur_state;
u8 cur_state = ACPI_POWER_RESOURCE_STATE_OFF;
if (!list || !state)
return -EINVAL;
/* The state of the list is 'on' IFF all resources are 'on'. */
cur_state = 0;
list_for_each_entry(entry, list, node) {
struct acpi_power_resource *resource = entry->resource;
acpi_handle handle = resource->device.handle;
int result;
mutex_lock(&resource->resource_lock);
result = acpi_power_get_state(handle, &cur_state);
result = acpi_power_get_state(resource, &cur_state);
mutex_unlock(&resource->resource_lock);
if (result)
return result;
......@@ -352,8 +360,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
acpi_status status = AE_OK;
status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL);
if (ACPI_FAILURE(status))
if (ACPI_FAILURE(status)) {
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
return -ENODEV;
}
resource->state = ACPI_POWER_RESOURCE_STATE_ON;
pr_debug("Power resource [%s] turned on\n", resource->name);
......@@ -405,8 +417,12 @@ static int __acpi_power_off(struct acpi_power_resource *resource)
status = acpi_evaluate_object(resource->device.handle, "_OFF",
NULL, NULL);
if (ACPI_FAILURE(status))
if (ACPI_FAILURE(status)) {
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
return -ENODEV;
}
resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
pr_debug("Power resource [%s] turned off\n", resource->name);
......@@ -590,13 +606,12 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
list_for_each_entry(entry, list, node) {
struct acpi_power_resource *resource = entry->resource;
acpi_handle handle = resource->device.handle;
int result;
int state;
u8 state;
mutex_lock(&resource->resource_lock);
result = acpi_power_get_state(handle, &state);
result = acpi_power_get_state(resource, &state);
if (result) {
mutex_unlock(&resource->resource_lock);
return result;
......@@ -789,8 +804,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
{
u8 list_state = ACPI_POWER_RESOURCE_STATE_OFF;
int result = 0;
int list_state = 0;
int i = 0;
if (!device || !state)
......@@ -919,7 +934,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
union acpi_object acpi_object;
struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
acpi_status status;
int state, result = -ENODEV;
int result;
acpi_bus_get_device(handle, &device);
if (device)
......@@ -946,13 +961,9 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
resource->system_level = acpi_object.power_resource.system_level;
resource->order = acpi_object.power_resource.resource_order;
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
result = acpi_power_get_state(handle, &state);
if (result)
goto err;
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
acpi_device_bid(device), state ? "on" : "off");
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
device->flags.match_driver = true;
result = acpi_device_add(device, acpi_release_power_resource);
......@@ -979,11 +990,13 @@ void acpi_resume_power_resources(void)
mutex_lock(&power_resource_list_lock);
list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
int result, state;
int result;
u8 state;
mutex_lock(&resource->resource_lock);
result = acpi_power_get_state(resource->device.handle, &state);
resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN;
result = acpi_power_get_state(resource, &state);
if (result) {
mutex_unlock(&resource->resource_lock);
continue;
......@@ -991,7 +1004,7 @@ void acpi_resume_power_resources(void)
if (state == ACPI_POWER_RESOURCE_STATE_OFF
&& resource->ref_count) {
dev_info(&resource->device.dev, "Turning ON\n");
dev_dbg(&resource->device.dev, "Turning ON\n");
__acpi_power_on(resource);
}
......@@ -1002,38 +1015,10 @@ void acpi_resume_power_resources(void)
}
#endif
static void acpi_power_turn_off_if_unused(struct acpi_power_resource *resource,
bool init)
{
if (resource->ref_count > 0)
return;
if (init) {
if (resource->users > 0)
return;
} else {
int result, state;
result = acpi_power_get_state(resource->device.handle, &state);
if (result || state == ACPI_POWER_RESOURCE_STATE_OFF)
return;
}
dev_info(&resource->device.dev, "Turning OFF\n");
__acpi_power_off(resource);
}
/**
* acpi_turn_off_unused_power_resources - Turn off power resources not in use.
* @init: Control switch.
*
* If @ainit is set, unconditionally turn off all of the ACPI power resources
* without any users.
*
* Otherwise, turn off all ACPI power resources without active references (that
* is, the ones that should be "off" at the moment) that are "on".
*/
void acpi_turn_off_unused_power_resources(bool init)
void acpi_turn_off_unused_power_resources(void)
{
struct acpi_power_resource *resource;
......@@ -1042,7 +1027,16 @@ void acpi_turn_off_unused_power_resources(bool init)
list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) {
mutex_lock(&resource->resource_lock);
acpi_power_turn_off_if_unused(resource, init);
/*
* Turn off power resources in an unknown state too, because the
* platform firmware on some system expects the OS to turn off
* power resources without any users unconditionally.
*/
if (!resource->ref_count &&
resource->state != ACPI_POWER_RESOURCE_STATE_OFF) {
dev_dbg(&resource->device.dev, "Turning OFF\n");
__acpi_power_off(resource);
}
mutex_unlock(&resource->resource_lock);
}
......
......@@ -347,6 +347,7 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
* @this_leaf: Kernel cache info structure being updated
* @found_cache: The PPTT node describing this cache instance
* @cpu_node: A unique reference to describe this cache instance
* @revision: The revision of the PPTT table
*
* The ACPI spec implies that the fields in the cache structures are used to
* extend and correct the information probed from the hardware. Lets only
......@@ -356,8 +357,11 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
*/
static void update_cache_properties(struct cacheinfo *this_leaf,
struct acpi_pptt_cache *found_cache,
struct acpi_pptt_processor *cpu_node)
struct acpi_pptt_processor *cpu_node,
u8 revision)
{
struct acpi_pptt_cache_v1* found_cache_v1;
this_leaf->fw_token = cpu_node;
if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID)
this_leaf->size = found_cache->size;
......@@ -405,6 +409,13 @@ static void update_cache_properties(struct cacheinfo *this_leaf,
if (this_leaf->type == CACHE_TYPE_NOCACHE &&
found_cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)
this_leaf->type = CACHE_TYPE_UNIFIED;
if (revision >= 3 && (found_cache->flags & ACPI_PPTT_CACHE_ID_VALID)) {
found_cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1,
found_cache, sizeof(struct acpi_pptt_cache));
this_leaf->id = found_cache_v1->cache_id;
this_leaf->attributes |= CACHE_ID;
}
}
static void cache_setup_acpi_cpu(struct acpi_table_header *table,
......@@ -425,9 +436,8 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table,
&cpu_node);
pr_debug("found = %p %p\n", found_cache, cpu_node);
if (found_cache)
update_cache_properties(this_leaf,
found_cache,
cpu_node);
update_cache_properties(this_leaf, found_cache,
cpu_node, table->revision);
index++;
}
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Author: Erik Kaneda <erik.kaneda@intel.com>
* Copyright 2020 Intel Corporation
*
* prmt.c
*
* Each PRM service is an executable that is run in a restricted environment
* that is invoked by writing to the PlatformRtMechanism OperationRegion from
* AML bytecode.
*
* init_prmt initializes the Platform Runtime Mechanism (PRM) services by
* processing data in the PRMT as well as registering an ACPI OperationRegion
* handler for the PlatformRtMechanism subtype.
*
*/
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/acpi.h>
#include <linux/prmt.h>
#include <asm/efi.h>
#pragma pack(1)
struct prm_mmio_addr_range {
u64 phys_addr;
u64 virt_addr;
u32 length;
};
struct prm_mmio_info {
u64 mmio_count;
struct prm_mmio_addr_range addr_ranges[];
};
struct prm_buffer {
u8 prm_status;
u64 efi_status;
u8 prm_cmd;
guid_t handler_guid;
};
struct prm_context_buffer {
char signature[ACPI_NAMESEG_SIZE];
u16 revision;
u16 reserved;
guid_t identifier;
u64 static_data_buffer;
struct prm_mmio_info *mmio_ranges;
};
#pragma pack()
static LIST_HEAD(prm_module_list);
struct prm_handler_info {
guid_t guid;
u64 handler_addr;
u64 static_data_buffer_addr;
u64 acpi_param_buffer_addr;
struct list_head handler_list;
};
struct prm_module_info {
guid_t guid;
u16 major_rev;
u16 minor_rev;
u16 handler_count;
struct prm_mmio_info *mmio_info;
bool updatable;
struct list_head module_list;
struct prm_handler_info handlers[];
};
static u64 efi_pa_va_lookup(u64 pa)
{
efi_memory_desc_t *md;
u64 pa_offset = pa & ~PAGE_MASK;
u64 page = pa & PAGE_MASK;
for_each_efi_memory_desc(md) {
if (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)
return pa_offset + md->virt_addr + page - md->phys_addr;
}
return 0;
}
#define get_first_handler(a) ((struct acpi_prmt_handler_info *) ((char *) (a) + a->handler_info_offset))
#define get_next_handler(a) ((struct acpi_prmt_handler_info *) (sizeof(struct acpi_prmt_handler_info) + (char *) a))
static int __init
acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
{
struct acpi_prmt_module_info *module_info;
struct acpi_prmt_handler_info *handler_info;
struct prm_handler_info *th;
struct prm_module_info *tm;
u64 mmio_count = 0;
u64 cur_handler = 0;
u32 module_info_size = 0;
u64 mmio_range_size = 0;
void *temp_mmio;
module_info = (struct acpi_prmt_module_info *) header;
module_info_size = struct_size(tm, handlers, module_info->handler_info_count);
tm = kmalloc(module_info_size, GFP_KERNEL);
guid_copy(&tm->guid, (guid_t *) module_info->module_guid);
tm->major_rev = module_info->major_rev;
tm->minor_rev = module_info->minor_rev;
tm->handler_count = module_info->handler_info_count;
tm->updatable = true;
if (module_info->mmio_list_pointer) {
/*
* Each module is associated with a list of addr
* ranges that it can use during the service
*/
mmio_count = *(u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB);
mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count);
tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL);
temp_mmio = memremap(module_info->mmio_list_pointer, mmio_range_size, MEMREMAP_WB);
memmove(tm->mmio_info, temp_mmio, mmio_range_size);
} else {
mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count);
tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL);
tm->mmio_info->mmio_count = 0;
}
INIT_LIST_HEAD(&tm->module_list);
list_add(&tm->module_list, &prm_module_list);
handler_info = get_first_handler(module_info);
do {
th = &tm->handlers[cur_handler];
guid_copy(&th->guid, (guid_t *)handler_info->handler_guid);
th->handler_addr = efi_pa_va_lookup(handler_info->handler_address);
th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address);
th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_address);
} while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info)));
return 0;
}
#define GET_MODULE 0
#define GET_HANDLER 1
static void *find_guid_info(const guid_t *guid, u8 mode)
{
struct prm_handler_info *cur_handler;
struct prm_module_info *cur_module;
int i = 0;
list_for_each_entry(cur_module, &prm_module_list, module_list) {
for (i = 0; i < cur_module->handler_count; ++i) {
cur_handler = &cur_module->handlers[i];
if (guid_equal(guid, &cur_handler->guid)) {
if (mode == GET_MODULE)
return (void *)cur_module;
else
return (void *)cur_handler;
}
}
}
return NULL;
}
static struct prm_module_info *find_prm_module(const guid_t *guid)
{
return (struct prm_module_info *)find_guid_info(guid, GET_MODULE);
}
static struct prm_handler_info *find_prm_handler(const guid_t *guid)
{
return (struct prm_handler_info *) find_guid_info(guid, GET_HANDLER);
}
/* In-coming PRM commands */
#define PRM_CMD_RUN_SERVICE 0
#define PRM_CMD_START_TRANSACTION 1
#define PRM_CMD_END_TRANSACTION 2
/* statuses that can be passed back to ASL */
#define PRM_HANDLER_SUCCESS 0
#define PRM_HANDLER_ERROR 1
#define INVALID_PRM_COMMAND 2
#define PRM_HANDLER_GUID_NOT_FOUND 3
#define UPDATE_LOCK_ALREADY_HELD 4
#define UPDATE_UNLOCK_WITHOUT_LOCK 5
/*
* This is the PlatformRtMechanism opregion space handler.
* @function: indicates the read/write. In fact as the PlatformRtMechanism
* message is driven by command, only write is meaningful.
*
* @addr : not used
* @bits : not used.
* @value : it is an in/out parameter. It points to the PRM message buffer.
* @handler_context: not used
*/
static acpi_status acpi_platformrt_space_handler(u32 function,
acpi_physical_address addr,
u32 bits, acpi_integer *value,
void *handler_context,
void *region_context)
{
struct prm_buffer *buffer = ACPI_CAST_PTR(struct prm_buffer, value);
struct prm_handler_info *handler;
struct prm_module_info *module;
efi_status_t status;
struct prm_context_buffer context;
/*
* The returned acpi_status will always be AE_OK. Error values will be
* saved in the first byte of the PRM message buffer to be used by ASL.
*/
switch (buffer->prm_cmd) {
case PRM_CMD_RUN_SERVICE:
handler = find_prm_handler(&buffer->handler_guid);
module = find_prm_module(&buffer->handler_guid);
if (!handler || !module)
goto invalid_guid;
ACPI_COPY_NAMESEG(context.signature, "PRMC");
context.revision = 0x0;
context.reserved = 0x0;
context.identifier = handler->guid;
context.static_data_buffer = handler->static_data_buffer_addr;
context.mmio_ranges = module->mmio_info;
status = efi_call_virt_pointer(handler, handler_addr,
handler->acpi_param_buffer_addr,
&context);
if (status == EFI_SUCCESS) {
buffer->prm_status = PRM_HANDLER_SUCCESS;
} else {
buffer->prm_status = PRM_HANDLER_ERROR;
buffer->efi_status = status;
}
break;
case PRM_CMD_START_TRANSACTION:
module = find_prm_module(&buffer->handler_guid);
if (!module)
goto invalid_guid;
if (module->updatable)
module->updatable = false;
else
buffer->prm_status = UPDATE_LOCK_ALREADY_HELD;
break;
case PRM_CMD_END_TRANSACTION:
module = find_prm_module(&buffer->handler_guid);
if (!module)
goto invalid_guid;
if (module->updatable)
buffer->prm_status = UPDATE_UNLOCK_WITHOUT_LOCK;
else
module->updatable = true;
break;
default:
buffer->prm_status = INVALID_PRM_COMMAND;
break;
}
return AE_OK;
invalid_guid:
buffer->prm_status = PRM_HANDLER_GUID_NOT_FOUND;
return AE_OK;
}
void __init init_prmt(void)
{
acpi_status status;
int mc = acpi_table_parse_entries(ACPI_SIG_PRMT, sizeof(struct acpi_table_prmt) +
sizeof (struct acpi_table_prmt_header),
0, acpi_parse_prmt, 0);
pr_info("PRM: found %u modules\n", mc);
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_PLATFORM_RT,
&acpi_platformrt_space_handler,
NULL, NULL);
if (ACPI_FAILURE(status))
pr_alert("PRM: OperationRegion handler could not be installed\n");
}
......@@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/sched.h> /* need_resched() */
#include <linux/sort.h>
#include <linux/tick.h>
#include <linux/cpuidle.h>
#include <linux/cpu.h>
......@@ -384,10 +385,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
return;
}
static int acpi_cst_latency_cmp(const void *a, const void *b)
{
const struct acpi_processor_cx *x = a, *y = b;
if (!(x->valid && y->valid))
return 0;
if (x->latency > y->latency)
return 1;
if (x->latency < y->latency)
return -1;
return 0;
}
static void acpi_cst_latency_swap(void *a, void *b, int n)
{
struct acpi_processor_cx *x = a, *y = b;
u32 tmp;
if (!(x->valid && y->valid))
return;
tmp = x->latency;
x->latency = y->latency;
y->latency = tmp;
}
static int acpi_processor_power_verify(struct acpi_processor *pr)
{
unsigned int i;
unsigned int working = 0;
unsigned int last_latency = 0;
unsigned int last_type = 0;
bool buggy_latency = false;
pr->power.timer_broadcast_on_state = INT_MAX;
......@@ -411,12 +439,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
}
if (!cx->valid)
continue;
if (cx->type >= last_type && cx->latency < last_latency)
buggy_latency = true;
last_latency = cx->latency;
last_type = cx->type;
lapic_timer_check_state(i, pr, cx);
tsc_check_state(cx->type);
working++;
}
if (buggy_latency) {
pr_notice("FW issue: working around C-state latencies out of order\n");
sort(&pr->power.states[1], max_cstate,
sizeof(struct acpi_processor_cx),
acpi_cst_latency_cmp,
acpi_cst_latency_swap);
}
lapic_timer_propagate_broadcast(pr);
return (working);
......
......@@ -9,6 +9,8 @@
* - Added processor hotplug support
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
......@@ -20,8 +22,6 @@
#include <asm/cpufeature.h>
#endif
#define PREFIX "ACPI: "
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
static DEFINE_MUTEX(performance_mutex);
......@@ -194,7 +194,6 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
union acpi_object *pct = NULL;
union acpi_object obj = { 0 };
status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
if (ACPI_FAILURE(status)) {
acpi_evaluation_failure_warn(pr->handle, "_PCT", status);
......@@ -204,7 +203,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
pct = (union acpi_object *)buffer.pointer;
if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
|| (pct->package.count != 2)) {
printk(KERN_ERR PREFIX "Invalid _PCT data\n");
pr_err("Invalid _PCT data\n");
result = -EFAULT;
goto end;
}
......@@ -218,7 +217,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
if ((obj.type != ACPI_TYPE_BUFFER)
|| (obj.buffer.length < sizeof(struct acpi_pct_register))
|| (obj.buffer.pointer == NULL)) {
printk(KERN_ERR PREFIX "Invalid _PCT data (control_register)\n");
pr_err("Invalid _PCT data (control_register)\n");
result = -EFAULT;
goto end;
}
......@@ -234,7 +233,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
if ((obj.type != ACPI_TYPE_BUFFER)
|| (obj.buffer.length < sizeof(struct acpi_pct_register))
|| (obj.buffer.pointer == NULL)) {
printk(KERN_ERR PREFIX "Invalid _PCT data (status_register)\n");
pr_err("Invalid _PCT data (status_register)\n");
result = -EFAULT;
goto end;
}
......@@ -242,7 +241,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
memcpy(&pr->performance->status_register, obj.buffer.pointer,
sizeof(struct acpi_pct_register));
end:
end:
kfree(buffer.pointer);
return result;
......@@ -294,7 +293,6 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
int i;
int last_invalid = -1;
status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
if (ACPI_FAILURE(status)) {
acpi_evaluation_failure_warn(pr->handle, "_PSS", status);
......@@ -303,7 +301,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
pss = buffer.pointer;
if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_ERR PREFIX "Invalid _PSS data\n");
pr_err("Invalid _PSS data\n");
result = -EFAULT;
goto end;
}
......@@ -357,7 +355,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
if (!px->core_frequency ||
((u32)(px->core_frequency * 1000) !=
(px->core_frequency * 1000))) {
printk(KERN_ERR FW_BUG PREFIX
pr_err(FW_BUG
"Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
pr->id, px->core_frequency);
if (last_invalid == -1)
......@@ -375,7 +373,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
}
if (last_invalid == 0) {
printk(KERN_ERR FW_BUG PREFIX
pr_err(FW_BUG
"No valid BIOS _PSS frequency found for processor %d\n", pr->id);
result = -EFAULT;
kfree(pr->performance->states);
......@@ -385,7 +383,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
if (last_invalid > 0)
pr->performance->state_count = last_invalid;
end:
end:
kfree(buffer.pointer);
return result;
......@@ -426,7 +424,7 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr)
#ifdef CONFIG_X86
if (acpi_has_method(pr->handle, "_PPC")) {
if(boot_cpu_has(X86_FEATURE_EST))
printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
pr_warn(FW_BUG "BIOS needs update for CPU "
"frequency support\n");
}
#endif
......@@ -520,13 +518,13 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
psd = buffer.pointer;
if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_ERR PREFIX "Invalid _PSD data\n");
pr_err("Invalid _PSD data\n");
result = -EFAULT;
goto end;
}
if (psd->package.count != 1) {
printk(KERN_ERR PREFIX "Invalid _PSD data\n");
pr_err("Invalid _PSD data\n");
result = -EFAULT;
goto end;
}
......@@ -537,19 +535,19 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
status = acpi_extract_package(&(psd->package.elements[0]),
&format, &state);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Invalid _PSD data\n");
pr_err("Invalid _PSD data\n");
result = -EFAULT;
goto end;
}
if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
pr_err("Unknown _PSD:num_entries\n");
result = -EFAULT;
goto end;
}
if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
pr_err("Unknown _PSD:revision\n");
result = -EFAULT;
goto end;
}
......@@ -557,7 +555,7 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
pr_err("Invalid _PSD:coord_type\n");
result = -EFAULT;
goto end;
}
......
......@@ -17,8 +17,6 @@
#include <acpi/processor.h>
#include <linux/uaccess.h>
#define PREFIX "ACPI: "
#ifdef CONFIG_CPU_FREQ
/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
......
......@@ -9,6 +9,8 @@
* - Added processor hotplug support
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
......@@ -20,8 +22,6 @@
#include <asm/io.h>
#include <linux/uaccess.h>
#define PREFIX "ACPI: "
/* ignore_tpc:
* 0 -> acpi processor driver doesn't ignore _TPC values
* 1 -> acpi processor driver ignores _TPC values
......@@ -195,15 +195,13 @@ void acpi_processor_throttling_init(void)
{
if (acpi_processor_update_tsd_coord())
pr_debug("Assume no T-state coordination\n");
return;
}
static int acpi_processor_throttling_notifier(unsigned long event, void *data)
{
struct throttling_tstate *p_tstate = data;
struct acpi_processor *pr;
unsigned int cpu ;
unsigned int cpu;
int target_state;
struct acpi_processor_limit *p_limit;
struct acpi_processor_throttling *p_throttling;
......@@ -236,8 +234,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
if (pr->throttling_platform_limit > target_state)
target_state = pr->throttling_platform_limit;
if (target_state >= p_throttling->state_count) {
printk(KERN_WARNING
"Exceed the limit of T-state \n");
pr_warn("Exceed the limit of T-state \n");
target_state = p_throttling->state_count - 1;
}
p_tstate->target_state = target_state;
......@@ -256,8 +253,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
cpu, target_state);
break;
default:
printk(KERN_WARNING
"Unsupported Throttling notifier event\n");
pr_warn("Unsupported Throttling notifier event\n");
break;
}
......@@ -408,7 +404,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *ptc = NULL;
union acpi_object obj = { 0 };
union acpi_object obj;
struct acpi_processor_throttling *throttling;
status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
......@@ -422,7 +418,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
ptc = (union acpi_object *)buffer.pointer;
if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE)
|| (ptc->package.count != 2)) {
printk(KERN_ERR PREFIX "Invalid _PTC data\n");
pr_err("Invalid _PTC data\n");
result = -EFAULT;
goto end;
}
......@@ -436,8 +432,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
if ((obj.type != ACPI_TYPE_BUFFER)
|| (obj.buffer.length < sizeof(struct acpi_ptc_register))
|| (obj.buffer.pointer == NULL)) {
printk(KERN_ERR PREFIX
"Invalid _PTC data (control_register)\n");
pr_err("Invalid _PTC data (control_register)\n");
result = -EFAULT;
goto end;
}
......@@ -453,7 +448,7 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
if ((obj.type != ACPI_TYPE_BUFFER)
|| (obj.buffer.length < sizeof(struct acpi_ptc_register))
|| (obj.buffer.pointer == NULL)) {
printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n");
pr_err("Invalid _PTC data (status_register)\n");
result = -EFAULT;
goto end;
}
......@@ -465,19 +460,19 @@ static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
if ((throttling->control_register.bit_width +
throttling->control_register.bit_offset) > 32) {
printk(KERN_ERR PREFIX "Invalid _PTC control register\n");
pr_err("Invalid _PTC control register\n");
result = -EFAULT;
goto end;
}
if ((throttling->status_register.bit_width +
throttling->status_register.bit_offset) > 32) {
printk(KERN_ERR PREFIX "Invalid _PTC status register\n");
pr_err("Invalid _PTC status register\n");
result = -EFAULT;
goto end;
}
end:
end:
kfree(buffer.pointer);
return result;
......@@ -506,7 +501,7 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
tss = buffer.pointer;
if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_ERR PREFIX "Invalid _TSS data\n");
pr_err("Invalid _TSS data\n");
result = -EFAULT;
goto end;
}
......@@ -546,15 +541,14 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
}
if (!tx->freqpercentage) {
printk(KERN_ERR PREFIX
"Invalid _TSS data: freq is zero\n");
pr_err("Invalid _TSS data: freq is zero\n");
result = -EFAULT;
kfree(pr->throttling.states_tss);
goto end;
}
}
end:
end:
kfree(buffer.pointer);
return result;
......@@ -587,13 +581,13 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
tsd = buffer.pointer;
if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_ERR PREFIX "Invalid _TSD data\n");
pr_err("Invalid _TSD data\n");
result = -EFAULT;
goto end;
}
if (tsd->package.count != 1) {
printk(KERN_ERR PREFIX "Invalid _TSD data\n");
pr_err("Invalid _TSD data\n");
result = -EFAULT;
goto end;
}
......@@ -606,19 +600,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
status = acpi_extract_package(&(tsd->package.elements[0]),
&format, &state);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Invalid _TSD data\n");
pr_err("Invalid _TSD data\n");
result = -EFAULT;
goto end;
}
if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n");
pr_err("Unknown _TSD:num_entries\n");
result = -EFAULT;
goto end;
}
if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
printk(KERN_ERR PREFIX "Unknown _TSD:revision\n");
pr_err("Unknown _TSD:revision\n");
result = -EFAULT;
goto end;
}
......@@ -639,7 +633,7 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
pthrottling->shared_type = DOMAIN_COORD_TYPE_SW_ALL;
}
end:
end:
kfree(buffer.pointer);
return result;
}
......@@ -711,13 +705,12 @@ static int acpi_throttling_rdmsr(u64 *value)
if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
!this_cpu_has(X86_FEATURE_ACPI)) {
printk(KERN_ERR PREFIX
"HARDWARE addr space,NOT supported yet\n");
pr_err("HARDWARE addr space,NOT supported yet\n");
} else {
msr_low = 0;
msr_high = 0;
rdmsr_safe(MSR_IA32_THERM_CONTROL,
(u32 *)&msr_low , (u32 *) &msr_high);
(u32 *)&msr_low, (u32 *) &msr_high);
msr = (msr_high << 32) | msr_low;
*value = (u64) msr;
ret = 0;
......@@ -732,8 +725,7 @@ static int acpi_throttling_wrmsr(u64 value)
if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
!this_cpu_has(X86_FEATURE_ACPI)) {
printk(KERN_ERR PREFIX
"HARDWARE addr space,NOT supported yet\n");
pr_err("HARDWARE addr space,NOT supported yet\n");
} else {
msr = value;
wrmsr_safe(MSR_IA32_THERM_CONTROL,
......@@ -745,15 +737,13 @@ static int acpi_throttling_wrmsr(u64 value)
#else
static int acpi_throttling_rdmsr(u64 *value)
{
printk(KERN_ERR PREFIX
"HARDWARE addr space,NOT supported yet\n");
pr_err("HARDWARE addr space,NOT supported yet\n");
return -1;
}
static int acpi_throttling_wrmsr(u64 value)
{
printk(KERN_ERR PREFIX
"HARDWARE addr space,NOT supported yet\n");
pr_err("HARDWARE addr space,NOT supported yet\n");
return -1;
}
#endif
......@@ -784,7 +774,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
ret = acpi_throttling_rdmsr(value);
break;
default:
printk(KERN_ERR PREFIX "Unknown addr space %d\n",
pr_err("Unknown addr space %d\n",
(u32) (throttling->status_register.space_id));
}
return ret;
......@@ -817,7 +807,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr,
ret = acpi_throttling_wrmsr(value);
break;
default:
printk(KERN_ERR PREFIX "Unknown addr space %d\n",
pr_err("Unknown addr space %d\n",
(u32) (throttling->control_register.space_id));
}
return ret;
......@@ -926,7 +916,7 @@ static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
}
/* TBD: Support duty_cycle values that span bit 4. */
else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
pr_warn("duty_cycle spans bit 4\n");
return -EINVAL;
}
......@@ -1185,8 +1175,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
*/
if (acpi_processor_get_throttling_control(pr) ||
acpi_processor_get_throttling_states(pr) ||
acpi_processor_get_platform_limit(pr))
{
acpi_processor_get_platform_limit(pr)) {
pr->throttling.acpi_processor_get_throttling =
&acpi_processor_get_throttling_fadt;
pr->throttling.acpi_processor_set_throttling =
......@@ -1246,7 +1235,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
goto end;
}
end:
end:
if (result)
pr->flags.throttling = 0;
......
// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/pci.h>
#include <linux/acpi.h>
#include <acpi/reboot.h>
......@@ -63,7 +65,7 @@ void acpi_reboot(void)
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
case ACPI_ADR_SPACE_SYSTEM_IO:
printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n");
pr_debug("ACPI MEMORY or I/O RESET_REG.\n");
acpi_reset();
break;
}
......
......@@ -423,6 +423,13 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
}
}
static bool irq_is_legacy(struct acpi_resource_irq *irq)
{
return irq->triggering == ACPI_EDGE_SENSITIVE &&
irq->polarity == ACPI_ACTIVE_HIGH &&
irq->shareable == ACPI_EXCLUSIVE;
}
/**
* acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
* @ares: Input ACPI resource object.
......@@ -461,7 +468,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
}
acpi_dev_get_irqresource(res, irq->interrupts[index],
irq->triggering, irq->polarity,
irq->shareable, true);
irq->shareable, irq_is_legacy(irq));
break;
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
ext_irq = &ares->data.extended_irq;
......
......@@ -7,6 +7,8 @@
* Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
......@@ -23,8 +25,6 @@
#include "sbshc.h"
#define PREFIX "ACPI: "
#define ACPI_SBS_CLASS "sbs"
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_SBS_DEVICE_NAME "Smart Battery System"
......@@ -544,7 +544,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
goto end;
battery->have_sysfs_alarm = 1;
end:
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
battery->name, battery->present ? "present" : "absent");
return result;
......@@ -577,10 +577,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
result = PTR_ERR(sbs->charger);
sbs->charger = NULL;
}
printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
pr_info("%s [%s]: AC Adapter [%s] (%s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
end:
end:
return result;
}
......@@ -658,7 +658,7 @@ static int acpi_sbs_add(struct acpi_device *device)
acpi_battery_add(sbs, 0);
acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end:
end:
if (result)
acpi_sbs_remove(device);
return result;
......
......@@ -5,6 +5,8 @@
* Copyright (c) 2007 Alexey Starikovskiy
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi.h>
#include <linux/wait.h>
#include <linux/slab.h>
......@@ -13,8 +15,6 @@
#include <linux/interrupt.h>
#include "sbshc.h"
#define PREFIX "ACPI: "
#define ACPI_SMB_HC_CLASS "smbus_host_ctl"
#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
......@@ -109,7 +109,7 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
u8 temp, sz = 0;
if (!hc) {
printk(KERN_ERR PREFIX "host controller is not configured\n");
pr_err("host controller is not configured\n");
return ret;
}
......@@ -231,7 +231,6 @@ static int smbus_alarm(void *context)
case ACPI_SBS_BATTERY:
acpi_os_execute(OSL_NOTIFY_HANDLER,
acpi_smbus_callback, hc);
default:;
}
mutex_unlock(&hc->lock);
return 0;
......@@ -254,7 +253,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "error obtaining _EC.\n");
pr_err("error obtaining _EC.\n");
return -EIO;
}
......
This diff is collapsed.
......@@ -8,6 +8,8 @@
* Copyright (c) 2003 Open Source Development Lab
*/
#define pr_fmt(fmt) "ACPI: PM: " fmt
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/dmi.h>
......@@ -41,7 +43,7 @@ static void acpi_sleep_tts_switch(u32 acpi_state)
* OS can't evaluate the _TTS object correctly. Some warning
* message will be printed. But it won't break anything.
*/
printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
pr_notice("Failure in evaluating _TTS object\n");
}
}
......@@ -73,8 +75,7 @@ static int acpi_sleep_prepare(u32 acpi_state)
}
ACPI_FLUSH_CPU_CACHE();
#endif
printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
acpi_state);
pr_info("Preparing to enter system sleep state S%d\n", acpi_state);
acpi_enable_wakeup_devices(acpi_state);
acpi_enter_sleep_state_prep(acpi_state);
return 0;
......@@ -406,7 +407,7 @@ static int acpi_pm_freeze(void)
}
/**
* acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.
* acpi_pm_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.
*/
static int acpi_pm_pre_suspend(void)
{
......@@ -459,8 +460,7 @@ static void acpi_pm_finish(void)
if (acpi_state == ACPI_STATE_S0)
return;
printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n",
acpi_state);
pr_info("Waking up from system sleep state S%d\n", acpi_state);
acpi_disable_wakeup_devices(acpi_state);
acpi_leave_sleep_state(acpi_state);
......@@ -504,7 +504,7 @@ static void acpi_pm_start(u32 acpi_state)
*/
static void acpi_pm_end(void)
{
acpi_turn_off_unused_power_resources(false);
acpi_turn_off_unused_power_resources();
acpi_scan_lock_release();
/*
* This is necessary in case acpi_pm_finish() is not called during a
......@@ -581,7 +581,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
error = acpi_suspend_lowlevel();
if (error)
return error;
pr_info(PREFIX "Low-level resume complete\n");
pr_info("Low-level resume complete\n");
pm_set_resume_via_firmware();
break;
}
......@@ -921,7 +921,7 @@ static void acpi_hibernation_leave(void)
acpi_leave_sleep_state_prep(ACPI_STATE_S4);
/* Check the hardware signature */
if (facs && s4_hardware_signature != facs->hardware_signature)
pr_crit("ACPI: Hardware changed while hibernated, success doubtful!\n");
pr_crit("Hardware changed while hibernated, success doubtful!\n");
/* Restore the NVS memory area */
suspend_nvs_restore();
/* Allow EC transactions to happen. */
......@@ -1027,7 +1027,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
printk(KERN_DEBUG "%s called\n", __func__);
pr_debug("%s called\n", __func__);
local_irq_disable();
acpi_enter_sleep_state(ACPI_STATE_S5);
}
......@@ -1059,7 +1059,7 @@ int __init acpi_sleep_init(void)
if (sleep_states[i])
pos += sprintf(pos, " S%d", i);
}
pr_info(PREFIX "(supports%s)\n", supported);
pr_info("(supports%s)\n", supported);
/*
* Register the tts_notifier to reboot notifier list so that the _TTS
......
......@@ -5,10 +5,11 @@
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/acpi.h>
#include "internal.h"
......@@ -254,16 +255,12 @@ static int param_get_trace_state(char *buffer, const struct kernel_param *kp)
{
if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED))
return sprintf(buffer, "disable\n");
else {
if (acpi_gbl_trace_method_name) {
if (!acpi_gbl_trace_method_name)
return sprintf(buffer, "enable\n");
if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT)
return sprintf(buffer, "method-once\n");
else
return sprintf(buffer, "method\n");
} else
return sprintf(buffer, "enable\n");
}
return 0;
}
module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
......@@ -359,8 +356,7 @@ static int acpi_table_attr_init(struct kobject *tables_obj,
}
table_attr->instance++;
if (table_attr->instance > ACPI_MAX_TABLE_INSTANCES) {
pr_warn("%4.4s: too many table instances\n",
table_attr->name);
pr_warn("%4.4s: too many table instances\n", table_attr->name);
return -ERANGE;
}
......@@ -388,8 +384,7 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
switch (event) {
case ACPI_TABLE_EVENT_INSTALL:
table_attr =
kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
if (!table_attr)
return AE_NO_MEMORY;
......@@ -420,7 +415,7 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
loff_t offset, size_t count)
{
struct acpi_data_attr *data_attr;
void __iomem *base;
void *base;
ssize_t rc;
data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
......@@ -582,8 +577,6 @@ static void delete_gpe_attr_array(void)
kfree(counter_attrs);
}
kfree(all_attrs);
return;
}
static void gpe_count(u32 gpe_number)
......@@ -598,8 +591,6 @@ static void gpe_count(u32 gpe_number)
else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
COUNT_ERROR].count++;
return;
}
static void fixed_event_count(u32 event_number)
......@@ -612,8 +603,6 @@ static void fixed_event_count(u32 event_number)
else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
COUNT_ERROR].count++;
return;
}
static void acpi_global_event_handler(u32 event_type, acpi_handle device,
......@@ -737,8 +726,7 @@ static ssize_t counter_set(struct kobject *kobj,
goto end;
if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) {
printk(KERN_WARNING PREFIX
"Can not change Invalid GPE/Fixed Event status\n");
pr_warn("Can not change Invalid GPE/Fixed Event status\n");
return -EINVAL;
}
......@@ -796,6 +784,7 @@ static ssize_t counter_set(struct kobject *kobj,
* the GPE flooding for GPE 00, they need to specify the following boot
* parameter:
* acpi_mask_gpe=0x00
* Note, the parameter can be a list (see bitmap_parselist() for the details).
* The masking status can be modified by the following runtime controlling
* interface:
* echo unmask > /sys/firmware/acpi/interrupts/gpe00
......@@ -805,10 +794,15 @@ static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata;
static int __init acpi_gpe_set_masked_gpes(char *val)
{
int ret;
u8 gpe;
if (kstrtou8(val, 0, &gpe))
return -EINVAL;
ret = kstrtou8(val, 0, &gpe);
if (ret) {
ret = bitmap_parselist(val, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX);
if (ret)
return ret;
} else
set_bit(gpe, acpi_masked_gpes_map);
return 1;
......@@ -841,13 +835,11 @@ void acpi_irq_stats_init(void)
num_gpes = acpi_current_gpe_count;
num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA;
all_attrs = kcalloc(num_counters + 1, sizeof(struct attribute *),
GFP_KERNEL);
all_attrs = kcalloc(num_counters + 1, sizeof(*all_attrs), GFP_KERNEL);
if (all_attrs == NULL)
return;
all_counters = kcalloc(num_counters, sizeof(struct event_counter),
GFP_KERNEL);
all_counters = kcalloc(num_counters, sizeof(*all_counters), GFP_KERNEL);
if (all_counters == NULL)
goto fail;
......@@ -855,8 +847,7 @@ void acpi_irq_stats_init(void)
if (ACPI_FAILURE(status))
goto fail;
counter_attrs = kcalloc(num_counters, sizeof(struct kobj_attribute),
GFP_KERNEL);
counter_attrs = kcalloc(num_counters, sizeof(*counter_attrs), GFP_KERNEL);
if (counter_attrs == NULL)
goto fail;
......@@ -906,7 +897,6 @@ void acpi_irq_stats_init(void)
fail:
delete_gpe_attr_array();
return;
}
static void __exit interrupt_stats_exit(void)
......@@ -914,30 +904,23 @@ static void __exit interrupt_stats_exit(void)
sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group);
delete_gpe_attr_array();
return;
}
static ssize_t
acpi_show_profile(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
static ssize_t pm_profile_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile);
}
static const struct kobj_attribute pm_profile_attr =
__ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL);
static const struct kobj_attribute pm_profile_attr = __ATTR_RO(pm_profile);
static ssize_t hotplug_enabled_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
static ssize_t enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
return sprintf(buf, "%d\n", hotplug->enabled);
}
static ssize_t hotplug_enabled_store(struct kobject *kobj,
struct kobj_attribute *attr,
static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t size)
{
struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
......@@ -950,9 +933,7 @@ static ssize_t hotplug_enabled_store(struct kobject *kobj,
return size;
}
static struct kobj_attribute hotplug_enabled_attr =
__ATTR(enabled, S_IRUGO | S_IWUSR, hotplug_enabled_show,
hotplug_enabled_store);
static struct kobj_attribute hotplug_enabled_attr = __ATTR_RW(enabled);
static struct attribute *hotplug_profile_attrs[] = {
&hotplug_enabled_attr.attr,
......@@ -983,7 +964,7 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
return;
err_out:
pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name);
pr_err("Unable to add hotplug profile '%s'\n", name);
}
static ssize_t force_remove_show(struct kobject *kobj,
......@@ -1010,9 +991,7 @@ static ssize_t force_remove_store(struct kobject *kobj,
return size;
}
static const struct kobj_attribute force_remove_attr =
__ATTR(force_remove, S_IRUGO | S_IWUSR, force_remove_show,
force_remove_store);
static const struct kobj_attribute force_remove_attr = __ATTR_RW(force_remove);
int __init acpi_sysfs_init(void)
{
......
......@@ -39,6 +39,7 @@ static int acpi_apic_instance __initdata;
enum acpi_subtable_type {
ACPI_SUBTABLE_COMMON,
ACPI_SUBTABLE_HMAT,
ACPI_SUBTABLE_PRMT,
};
struct acpi_subtable_entry {
......@@ -222,6 +223,8 @@ acpi_get_entry_type(struct acpi_subtable_entry *entry)
return entry->hdr->common.type;
case ACPI_SUBTABLE_HMAT:
return entry->hdr->hmat.type;
case ACPI_SUBTABLE_PRMT:
return 0;
}
return 0;
}
......@@ -234,6 +237,8 @@ acpi_get_entry_length(struct acpi_subtable_entry *entry)
return entry->hdr->common.length;
case ACPI_SUBTABLE_HMAT:
return entry->hdr->hmat.length;
case ACPI_SUBTABLE_PRMT:
return entry->hdr->prmt.length;
}
return 0;
}
......@@ -246,6 +251,8 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
return sizeof(entry->hdr->common);
case ACPI_SUBTABLE_HMAT:
return sizeof(entry->hdr->hmat);
case ACPI_SUBTABLE_PRMT:
return sizeof(entry->hdr->prmt);
}
return 0;
}
......@@ -255,6 +262,8 @@ acpi_get_subtable_type(char *id)
{
if (strncmp(id, ACPI_SIG_HMAT, 4) == 0)
return ACPI_SUBTABLE_HMAT;
if (strncmp(id, ACPI_SIG_PRMT, 4) == 0)
return ACPI_SUBTABLE_PRMT;
return ACPI_SUBTABLE_COMMON;
}
......
......@@ -32,6 +32,9 @@ static const struct acpi_device_id lps0_device_ids[] = {
{"", },
};
/* Microsoft platform agnostic UUID */
#define ACPI_LPS0_DSM_UUID_MICROSOFT "11e00d56-ce64-47ce-837b-1f898f9aa461"
#define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66"
#define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1
......@@ -39,15 +42,22 @@ static const struct acpi_device_id lps0_device_ids[] = {
#define ACPI_LPS0_SCREEN_ON 4
#define ACPI_LPS0_ENTRY 5
#define ACPI_LPS0_EXIT 6
#define ACPI_LPS0_MS_ENTRY 7
#define ACPI_LPS0_MS_EXIT 8
/* AMD */
#define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721"
#define ACPI_LPS0_ENTRY_AMD 2
#define ACPI_LPS0_EXIT_AMD 3
#define ACPI_LPS0_SCREEN_OFF_AMD 4
#define ACPI_LPS0_SCREEN_ON_AMD 5
static acpi_handle lps0_device_handle;
static guid_t lps0_dsm_guid;
static char lps0_dsm_func_mask;
static int lps0_dsm_func_mask;
static guid_t lps0_dsm_guid_microsoft;
static int lps0_dsm_func_mask_microsoft;
/* Device constraint entry structure */
struct lpi_device_info {
......@@ -68,15 +78,7 @@ struct lpi_constraints {
int min_dstate;
};
/* AMD */
/* Device constraint entry structure */
struct lpi_device_info_amd {
int revision;
int count;
union acpi_object *package;
};
/* Constraint package structure */
/* AMD Constraint package structure */
struct lpi_device_constraint_amd {
char *name;
int enabled;
......@@ -94,15 +96,15 @@ static void lpi_device_get_constraints_amd(void)
int i, j, k;
out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
rev_id, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
NULL, ACPI_TYPE_PACKAGE);
if (!out_obj)
return;
acpi_handle_debug(lps0_device_handle, "_DSM function 1 eval %s\n",
out_obj ? "successful" : "failed");
if (!out_obj)
return;
for (i = 0; i < out_obj->package.count; i++) {
union acpi_object *package = &out_obj->package.elements[i];
......@@ -315,14 +317,15 @@ static void lpi_check_constraints(void)
}
}
static void acpi_sleep_run_lps0_dsm(unsigned int func)
static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, guid_t dsm_guid)
{
union acpi_object *out_obj;
if (!(lps0_dsm_func_mask & (1 << func)))
if (!(func_mask & (1 << func)))
return;
out_obj = acpi_evaluate_dsm(lps0_device_handle, &lps0_dsm_guid, rev_id, func, NULL);
out_obj = acpi_evaluate_dsm(lps0_device_handle, &dsm_guid,
rev_id, func, NULL);
ACPI_FREE(out_obj);
acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n",
......@@ -334,11 +337,33 @@ static bool acpi_s2idle_vendor_amd(void)
return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
}
static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *dsm_guid)
{
union acpi_object *obj;
int ret = -EINVAL;
guid_parse(uuid, dsm_guid);
obj = acpi_evaluate_dsm(handle, dsm_guid, rev, 0, NULL);
/* Check if the _DSM is present and as expected. */
if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length == 0 ||
obj->buffer.length > sizeof(u32)) {
acpi_handle_debug(handle,
"_DSM UUID %s rev %d function 0 evaluation failed\n", uuid, rev);
goto out;
}
ret = *(int *)obj->buffer.pointer;
acpi_handle_debug(handle, "_DSM UUID %s rev %d function mask: 0x%x\n", uuid, rev, ret);
out:
ACPI_FREE(obj);
return ret;
}
static int lps0_device_attach(struct acpi_device *adev,
const struct acpi_device_id *not_used)
{
union acpi_object *out_obj;
if (lps0_device_handle)
return 0;
......@@ -346,28 +371,36 @@ static int lps0_device_attach(struct acpi_device *adev,
return 0;
if (acpi_s2idle_vendor_amd()) {
guid_parse(ACPI_LPS0_DSM_UUID_AMD, &lps0_dsm_guid);
out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 0, 0, NULL);
/* AMD0004, AMDI0005:
* - Should use rev_id 0x0
* - function mask > 0x3: Should use AMD method, but has off by one bug
* - function mask = 0x3: Should use Microsoft method
* AMDI0006:
* - should use rev_id 0x0
* - function mask = 0x3: Should use Microsoft method
*/
const char *hid = acpi_device_hid(adev);
rev_id = 0;
lps0_dsm_func_mask = validate_dsm(adev->handle,
ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
ACPI_LPS0_DSM_UUID_MICROSOFT, rev_id,
&lps0_dsm_guid_microsoft);
if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
!strcmp(hid, "AMDI0005"))) {
lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
}
} else {
guid_parse(ACPI_LPS0_DSM_UUID, &lps0_dsm_guid);
out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 1, 0, NULL);
rev_id = 1;
lps0_dsm_func_mask = validate_dsm(adev->handle,
ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
lps0_dsm_func_mask_microsoft = -EINVAL;
}
/* Check if the _DSM is present and as expected. */
if (!out_obj || out_obj->type != ACPI_TYPE_BUFFER) {
acpi_handle_debug(adev->handle,
"_DSM function 0 evaluation failed\n");
return 0;
}
lps0_dsm_func_mask = *(char *)out_obj->buffer.pointer;
ACPI_FREE(out_obj);
acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n",
lps0_dsm_func_mask);
if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
return 0; //function evaluation failed
lps0_device_handle = adev->handle;
......@@ -406,11 +439,23 @@ int acpi_s2idle_prepare_late(void)
if (pm_debug_messages_on)
lpi_check_constraints();
if (acpi_s2idle_vendor_amd()) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD);
if (lps0_dsm_func_mask_microsoft > 0) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
} else if (acpi_s2idle_vendor_amd()) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD,
lps0_dsm_func_mask, lps0_dsm_guid);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
lps0_dsm_func_mask, lps0_dsm_guid);
} else {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
lps0_dsm_func_mask, lps0_dsm_guid);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
lps0_dsm_func_mask, lps0_dsm_guid);
}
return 0;
......@@ -421,11 +466,23 @@ void acpi_s2idle_restore_early(void)
if (!lps0_device_handle || sleep_no_lps0)
return;
if (acpi_s2idle_vendor_amd()) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD);
if (lps0_dsm_func_mask_microsoft > 0) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
} else if (acpi_s2idle_vendor_amd()) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD,
lps0_dsm_func_mask, lps0_dsm_guid);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD,
lps0_dsm_func_mask, lps0_dsm_guid);
} else {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
lps0_dsm_func_mask, lps0_dsm_guid);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
lps0_dsm_func_mask, lps0_dsm_guid);
}
}
......
......@@ -1233,14 +1233,14 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip)
void acpi_gpiochip_add(struct gpio_chip *chip)
{
struct acpi_gpio_chip *acpi_gpio;
acpi_handle handle;
struct acpi_device *adev;
acpi_status status;
if (!chip || !chip->parent)
return;
handle = ACPI_HANDLE(chip->parent);
if (!handle)
adev = ACPI_COMPANION(chip->parent);
if (!adev)
return;
acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
......@@ -1254,7 +1254,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
INIT_LIST_HEAD(&acpi_gpio->events);
INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry);
status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio);
if (ACPI_FAILURE(status)) {
dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n");
kfree(acpi_gpio);
......@@ -1263,7 +1263,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
acpi_gpiochip_request_regions(acpi_gpio);
acpi_gpiochip_scan_gpios(acpi_gpio);
acpi_walk_dep_device_list(handle);
acpi_dev_clear_dependencies(adev);
}
void acpi_gpiochip_remove(struct gpio_chip *chip)
......
......@@ -259,8 +259,8 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
*/
void i2c_acpi_register_devices(struct i2c_adapter *adap)
{
struct acpi_device *adev;
acpi_status status;
acpi_handle handle;
if (!has_acpi_companion(&adap->dev))
return;
......@@ -275,11 +275,11 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
if (!adap->dev.parent)
return;
handle = ACPI_HANDLE(adap->dev.parent);
if (!handle)
adev = ACPI_COMPANION(adap->dev.parent);
if (!adev)
return;
acpi_walk_dep_device_list(handle);
acpi_dev_clear_dependencies(adev);
}
static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
......
......@@ -621,8 +621,8 @@ static const struct acpi_gpio_mapping ssam_acpi_gpios[] = {
static int ssam_serial_hub_probe(struct serdev_device *serdev)
{
struct acpi_device *ssh = ACPI_COMPANION(&serdev->dev);
struct ssam_controller *ctrl;
acpi_handle *ssh = ACPI_HANDLE(&serdev->dev);
acpi_status astatus;
int status;
......@@ -652,7 +652,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
if (status)
goto err_devopen;
astatus = ssam_serdev_setup_via_acpi(ssh, serdev);
astatus = ssam_serdev_setup_via_acpi(ssh->handle, serdev);
if (ACPI_FAILURE(astatus)) {
status = -ENXIO;
goto err_devinit;
......@@ -706,7 +706,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev)
* For now let's thus default power/wakeup to false.
*/
device_set_wakeup_capable(&serdev->dev, true);
acpi_walk_dep_device_list(ssh);
acpi_dev_clear_dependencies(ssh);
return 0;
......
......@@ -446,12 +446,12 @@ mshw0011_space_handler(u32 function, acpi_physical_address command,
static int mshw0011_install_space_handler(struct i2c_client *client)
{
acpi_handle handle;
struct acpi_device *adev;
struct mshw0011_handler_data *data;
acpi_status status;
handle = ACPI_HANDLE(&client->dev);
if (!handle)
adev = ACPI_COMPANION(&client->dev);
if (!adev)
return -ENODEV;
data = kzalloc(sizeof(struct mshw0011_handler_data),
......@@ -460,25 +460,25 @@ static int mshw0011_install_space_handler(struct i2c_client *client)
return -ENOMEM;
data->client = client;
status = acpi_bus_attach_private_data(handle, (void *)data);
status = acpi_bus_attach_private_data(adev->handle, (void *)data);
if (ACPI_FAILURE(status)) {
kfree(data);
return -ENOMEM;
}
status = acpi_install_address_space_handler(handle,
status = acpi_install_address_space_handler(adev->handle,
ACPI_ADR_SPACE_GSBUS,
&mshw0011_space_handler,
NULL,
data);
if (ACPI_FAILURE(status)) {
dev_err(&client->dev, "Error installing i2c space handler\n");
acpi_bus_detach_private_data(handle);
acpi_bus_detach_private_data(adev->handle);
kfree(data);
return -ENOMEM;
}
acpi_walk_dep_device_list(handle);
acpi_dev_clear_dependencies(adev);
return 0;
}
......
......@@ -798,7 +798,7 @@ static int san_consumer_links_setup(struct platform_device *pdev)
static int san_probe(struct platform_device *pdev)
{
acpi_handle san = ACPI_HANDLE(&pdev->dev);
struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
struct ssam_controller *ctrl;
struct san_data *data;
acpi_status astatus;
......@@ -821,7 +821,8 @@ static int san_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
astatus = acpi_install_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
astatus = acpi_install_address_space_handler(san->handle,
ACPI_ADR_SPACE_GSBUS,
&san_opreg_handler, NULL,
&data->info);
if (ACPI_FAILURE(astatus))
......@@ -835,7 +836,7 @@ static int san_probe(struct platform_device *pdev)
if (status)
goto err_install_dev;
acpi_walk_dep_device_list(san);
acpi_dev_clear_dependencies(san);
return 0;
err_install_dev:
......
......@@ -207,4 +207,14 @@ struct acpi_pld_info {
#define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */
/* Panel position defined in _PLD section of ACPI Specification 6.3 */
#define ACPI_PLD_PANEL_TOP 0
#define ACPI_PLD_PANEL_BOTTOM 1
#define ACPI_PLD_PANEL_LEFT 2
#define ACPI_PLD_PANEL_RIGHT 3
#define ACPI_PLD_PANEL_FRONT 4
#define ACPI_PLD_PANEL_BACK 5
#define ACPI_PLD_PANEL_UNKNOWN 6
#endif /* ACBUFFER_H */
......@@ -188,6 +188,8 @@
#define ACPI_MAX_GSBUS_DATA_SIZE 255
#define ACPI_MAX_GSBUS_BUFFER_SIZE ACPI_SERIAL_HEADER_SIZE + ACPI_MAX_GSBUS_DATA_SIZE
#define ACPI_PRM_INPUT_BUFFER_SIZE 26
/* _sx_d and _sx_w control methods */
#define ACPI_NUM_sx_d_METHODS 4
......
......@@ -280,6 +280,12 @@ struct acpi_device_power {
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
};
struct acpi_dep_data {
struct list_head node;
acpi_handle supplier;
acpi_handle consumer;
};
/* Performance Management */
struct acpi_device_perf_flags {
......@@ -498,8 +504,6 @@ extern int unregister_acpi_notifier(struct notifier_block *);
*/
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
void acpi_bus_put_acpi_device(struct acpi_device *adev);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
......@@ -685,6 +689,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
struct acpi_device *
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
struct acpi_device *
......@@ -718,6 +724,13 @@ static inline void acpi_dev_put(struct acpi_device *adev)
{
put_device(&adev->dev);
}
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
static inline void acpi_bus_put_acpi_device(struct acpi_device *adev)
{
acpi_dev_put(adev);
}
#else /* CONFIG_ACPI */
static inline int register_acpi_bus_type(void *bus) { return 0; }
......
......@@ -43,4 +43,4 @@ static inline void disable_hmat(void)
{
}
#endif /* CONFIG_ACPI_HMAT */
#endif /* __ACP_NUMA_H */
#endif /* __ACPI_NUMA_H */
......@@ -12,7 +12,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20210331
#define ACPI_CA_VERSION 0x20210604
#include <acpi/acconfig.h>
#include <acpi/actypes.h>
......
......@@ -327,9 +327,20 @@ struct acpi_cedt_header {
enum acpi_cedt_type {
ACPI_CEDT_TYPE_CHBS = 0,
ACPI_CEDT_TYPE_RESERVED = 1
ACPI_CEDT_TYPE_CFMWS = 1,
ACPI_CEDT_TYPE_RESERVED = 2,
};
/* Values for version field above */
#define ACPI_CEDT_CHBS_VERSION_CXL11 (0)
#define ACPI_CEDT_CHBS_VERSION_CXL20 (1)
/* Values for length field above */
#define ACPI_CEDT_CHBS_LENGTH_CXL11 (0x2000)
#define ACPI_CEDT_CHBS_LENGTH_CXL20 (0x10000)
/*
* CEDT subtables
*/
......@@ -345,6 +356,34 @@ struct acpi_cedt_chbs {
u64 length;
};
/* 1: CXL Fixed Memory Window Structure */
struct acpi_cedt_cfmws {
struct acpi_cedt_header header;
u32 reserved1;
u64 base_hpa;
u64 window_size;
u8 interleave_ways;
u8 interleave_arithmetic;
u16 reserved2;
u32 granularity;
u16 restrictions;
u16 qtg_id;
u32 interleave_targets[];
};
/* Values for Interleave Arithmetic field above */
#define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0)
/* Values for Restrictions field above */
#define ACPI_CEDT_CFMWS_RESTRICT_TYPE2 (1)
#define ACPI_CEDT_CFMWS_RESTRICT_TYPE3 (1<<1)
#define ACPI_CEDT_CFMWS_RESTRICT_VOLATILE (1<<2)
#define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3)
#define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4)
/*******************************************************************************
*
* CPEP - Corrected Platform Error Polling table (ACPI 4.0)
......
......@@ -24,6 +24,7 @@
* file. Useful because they make it more difficult to inadvertently type in
* the wrong signature.
*/
#define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */
#define ACPI_SIG_IORT "IORT" /* IO Remapping Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
#define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */
......@@ -39,11 +40,14 @@
#define ACPI_SIG_PHAT "PHAT" /* Platform Health Assessment Table */
#define ACPI_SIG_PMTT "PMTT" /* Platform Memory Topology Table */
#define ACPI_SIG_PPTT "PPTT" /* Processor Properties Topology Table */
#define ACPI_SIG_PRMT "PRMT" /* Platform Runtime Mechanism Table */
#define ACPI_SIG_RASF "RASF" /* RAS Feature table */
#define ACPI_SIG_RGRT "RGRT" /* Regulatory Graphics Resource Table */
#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */
#define ACPI_SIG_SDEI "SDEI" /* Software Delegated Exception Interface Table */
#define ACPI_SIG_SDEV "SDEV" /* Secure Devices table */
#define ACPI_SIG_NHLT "NHLT" /* Non-HDAudio Link Table */
#define ACPI_SIG_SVKL "SVKL" /* Storage Volume Key Location Table */
/*
* All tables must be byte-packed to match the ACPI specification, since
......@@ -63,6 +67,20 @@
* See http://stackoverflow.com/a/1053662/41661
*/
/*******************************************************************************
*
* BDAT - BIOS Data ACPI Table
*
* Conforms to "BIOS Data ACPI Table", Interface Specification v4.0 Draft 5
* Nov 2020
*
******************************************************************************/
struct acpi_table_bdat {
struct acpi_table_header header;
struct acpi_generic_address gas;
};
/*******************************************************************************
*
* IORT - IO Remapping Table
......@@ -446,6 +464,12 @@ struct acpi_ivrs_device_hid {
u8 uid_length;
};
/* Values for uid_type above */
#define ACPI_IVRS_UID_NOT_PRESENT 0
#define ACPI_IVRS_UID_IS_INTEGER 1
#define ACPI_IVRS_UID_IS_STRING 2
/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition Block (IVMD) */
struct acpi_ivrs_memory {
......@@ -763,6 +787,20 @@ struct acpi_madt_multiproc_wakeup {
u64 base_address;
};
#define ACPI_MULTIPROC_WAKEUP_MB_OS_SIZE 2032
#define ACPI_MULTIPROC_WAKEUP_MB_FIRMWARE_SIZE 2048
struct acpi_madt_multiproc_wakeup_mailbox {
u16 command;
u16 reserved; /* reserved - must be zero */
u32 apic_id;
u64 wakeup_vector;
u8 reserved_os[ACPI_MULTIPROC_WAKEUP_MB_OS_SIZE]; /* reserved for OS use */
u8 reserved_firmware[ACPI_MULTIPROC_WAKEUP_MB_FIRMWARE_SIZE]; /* reserved for firmware use */
};
#define ACPI_MP_WAKE_COMMAND_WAKEUP 1
/*
* Common flags fields for MADT subtables
*/
......@@ -1673,6 +1711,48 @@ struct acpi_pptt_id {
u16 spin_rev;
};
/*******************************************************************************
*
* PRMT - Platform Runtime Mechanism Table
* Version 1
*
******************************************************************************/
struct acpi_table_prmt {
struct acpi_table_header header; /* Common ACPI table header */
};
struct acpi_table_prmt_header {
u8 platform_guid[16];
u32 module_info_offset;
u32 module_info_count;
};
struct acpi_prmt_module_header {
u16 revision;
u16 length;
};
struct acpi_prmt_module_info {
u16 revision;
u16 length;
u8 module_guid[16];
u16 major_rev;
u16 minor_rev;
u16 handler_info_count;
u32 handler_info_offset;
u64 mmio_list_pointer;
};
struct acpi_prmt_handler_info {
u16 revision;
u16 length;
u8 handler_guid[16];
u64 handler_address;
u64 static_data_buffer_address;
u64 acpi_param_buffer_address;
};
/*******************************************************************************
*
* RASF - RAS Feature Table (ACPI 5.0)
......@@ -1769,6 +1849,32 @@ enum acpi_rasf_status {
#define ACPI_RASF_ERROR (1<<2)
#define ACPI_RASF_STATUS (0x1F<<3)
/*******************************************************************************
*
* RGRT - Regulatory Graphics Resource Table
* Version 1
*
* Conforms to "ACPI RGRT" available at:
* https://microsoft.github.io/mu/dyn/mu_plus/ms_core_pkg/acpi_RGRT/feature_acpi_rgrt/
*
******************************************************************************/
struct acpi_table_rgrt {
struct acpi_table_header header; /* Common ACPI table header */
u16 version;
u8 image_type;
u8 reserved;
u8 image[0];
};
/* image_type values */
enum acpi_rgrt_image_type {
ACPI_RGRT_TYPE_RESERVED0 = 0,
ACPI_RGRT_IMAGE_TYPE_PNG = 1,
ACPI_RGRT_TYPE_RESERVED = 2 /* 2 and greater are reserved */
};
/*******************************************************************************
*
* SBST - Smart Battery Specification Table
......@@ -1899,6 +2005,37 @@ struct acpi_sdev_pcie_path {
u8 function;
};
/*******************************************************************************
*
* SVKL - Storage Volume Key Location Table (ACPI 6.4)
* From: "Guest-Host-Communication Interface (GHCI) for Intel
* Trust Domain Extensions (Intel TDX)".
* Version 1
*
******************************************************************************/
struct acpi_table_svkl {
struct acpi_table_header header; /* Common ACPI table header */
u32 count;
};
struct acpi_svkl_key {
u16 type;
u16 format;
u32 size;
u64 address;
};
enum acpi_svkl_type {
ACPI_SVKL_TYPE_MAIN_STORAGE = 0,
ACPI_SVKL_TYPE_RESERVED = 1 /* 1 and greater are reserved */
};
enum acpi_svkl_format {
ACPI_SVKL_FORMAT_RAW_BINARY = 0,
ACPI_SVKL_FORMAT_RESERVED = 1 /* 1 and greater are reserved */
};
/* Reset to default packing */
#pragma pack()
......
......@@ -132,6 +132,7 @@ enum acpi_address_range_id {
union acpi_subtable_headers {
struct acpi_subtable_header common;
struct acpi_hmat_structure hmat;
struct acpi_prmt_module_header prmt;
};
typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);
......@@ -550,6 +551,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
#define OSC_SB_OSLPI_SUPPORT 0x00000100
#define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT 0x00001000
#define OSC_SB_GENERIC_INITIATOR_SUPPORT 0x00002000
#define OSC_SB_PRM_SUPPORT 0x00020000
#define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000
extern bool osc_sb_apei_support_acked;
......@@ -666,7 +668,6 @@ extern bool acpi_driver_match_device(struct device *dev,
const struct device_driver *drv);
int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
int acpi_device_modalias(struct device *, char *, int);
void acpi_walk_dep_device_list(acpi_handle handle);
struct platform_device *acpi_create_platform_device(struct acpi_device *,
struct property_entry *);
......
/* SPDX-License-Identifier: GPL-2.0-only */
#ifdef CONFIG_ACPI_PRMT
void init_prmt(void);
#else
static inline void init_prmt(void) { }
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment