ACPI updates for 6.6-rc1
- Update the ACPICA code in the kernel to upstream revision 20230628 including the following changes: * Suppress a GCC 12 dangling-pointer warning (Philip Prindeville). * Reformat the ACPI_STATE_COMMON macro and its users (George Guo). * Replace the ternary operator with ACPI_MIN() (Jiangshan Yi). * Add support for _DSC as per ACPI 6.5 (Saket Dumbre). * Remove a duplicate macro from zephyr header (Najumon B.A). * Add data structures for GED and _EVT tracking (Jose Marinho). * Fix misspelled CDAT DSMAS define (Dave Jiang). * Simplify an error message in acpi_ds_result_push() (Christophe Jaillet). * Add a struct size macro related to SRAT (Dave Jiang). * Add AML_NO_OPERAND_RESOLVE flag to Timer (Abhishek Mainkar). * Add support for RISC-V external interrupt controllers in MADT (Sunil V L). * Add RHCT flags, CMO and MMU nodes (Sunil V L). * Change ACPICA version to 20230628 (Bob Moore). - Introduce new wrappers for ACPICA notify handler install/remove and convert multiple drivers to using their own Notify() handlers instead of the ACPI bus type .notify() slated for removal (Michal Wilczynski). - Add backlight=native DMI quirk for Apple iMac12,1 and iMac12,2 (Hans de Goede). - Put ACPI video and its child devices explicitly into D0 on boot to avoid platform firmware confusion (Kai-Heng Feng). - Add backlight=native DMI quirk for Lenovo Ideapad Z470 (Jiri Slaby). - Support obtaining physical CPU ID from MADT on LoongArch (Bibo Mao). - Convert ACPI CPU initialization to using _OSC instead of _PDC that has been depreceted since 2018 and dropped from the specification in ACPI 6.5 (Michal Wilczynski, Rafael Wysocki). - Drop non-functional nocrt parameter from ACPI thermal (Mario Limonciello). - Clean up the ACPI thermal driver, rework the handling of firmware notifications in it and make it provide a table of generic trip point structures to the core during initialization (Rafael Wysocki). - Defer enumeration of devices with _DEP pointing to IVSC (Wentong Wu). - Install SystemCMOS address space handler for ACPI000E (TAD) to meet platform firmware expectations on some platforms (Zhang Rui). - Fix finding the generic error data in the ACPi extlog driver for compatibility with old and new firmware interface versions (Xiaochun Lee). - Remove assorted unused declarations of functions (Yue Haibing). - Move AMBA bus scan handling into arm64 specific directory (Sudeep Holla). - Fix and clean up suspend-to-idle interface for AMD systems (Mario Limonciello, Andy Shevchenko). - Fix string truncation warning in pnpacpi_add_device() (Sunil V L). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmTslAkSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxtvgQAIsYAHXgalMFCLTqxeRZ8IMMLh/oxVfp RDbZ7lsBNzhYKXNv0jczjDApvfOctplh+qVuRIyFPrVrD+xzPgI9eFaZx41B3UPy 3UG/KphjtF+sAu8rSFM2qcL2P+NGWe1Okr2G8Mbvu6bkGjfHShX6HGR7YgIyrZVO VMVLWqLvjvvg/jkraozArTtlvMwTrpBFxgWQVPK9TLRwx+JfB7WV6Z1XkgbllpR5 8Q+O9wyVWfAIrLk/HZJdYNkdwREi46d226ePs6tJkwzE8KCUna0U4WbVVPRjbSfI Mkpy7Bnn91EZdN43/3ZzPBNO6NJi7UsD46EwRMzf1v7KyfsttnKw/v/SMke6gKQW 43gi0trdbVxEdnN33CmBb2k82YQ5tjVuNOwKNy4xvFZ4vTE+WTz2imXMdW28biLT sU1eYJXPzBUQ4Ja2x56a1DOp2C1uOcSHbTKNzmtFsmT2FIWOKN+9PrOjaFEn7cyU FwWSzcONLE/QC0cSr7cWYym06aY8INtAlCm0hrlpwBDyiVDACz/QZ3NQAmbXKr5z 5JIDQ+8v6YvpIx48yDlTYaQPMEskkZ2udkmwZCh6Vs0fMGyo3DDWvAIltPmHuIoj KekfDK5pkJjftK67IlHioAkS3KGHy4VTybi4Sx8KjYy9Q4GPQ4TL2h18kInXGu4f tv7U9J6zx9mJ =aXc6 -----END PGP SIGNATURE----- Merge tag 'acpi-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: "These include new ACPICA material, a rework of the ACPI thermal driver, a switch-over of the ACPI processor driver to using _OSC instead of (long deprecated) _PDC for CPU initialization, a rework of firmware notifications handling in several drivers, fixes and cleanups for suspend-to-idle handling on AMD systems, ACPI backlight driver updates and more. Specifics: - Update the ACPICA code in the kernel to upstream revision 20230628 including the following changes: - Suppress a GCC 12 dangling-pointer warning (Philip Prindeville) - Reformat the ACPI_STATE_COMMON macro and its users (George Guo) - Replace the ternary operator with ACPI_MIN() (Jiangshan Yi) - Add support for _DSC as per ACPI 6.5 (Saket Dumbre) - Remove a duplicate macro from zephyr header (Najumon B.A) - Add data structures for GED and _EVT tracking (Jose Marinho) - Fix misspelled CDAT DSMAS define (Dave Jiang) - Simplify an error message in acpi_ds_result_push() (Christophe Jaillet) - Add a struct size macro related to SRAT (Dave Jiang) - Add AML_NO_OPERAND_RESOLVE flag to Timer (Abhishek Mainkar) - Add support for RISC-V external interrupt controllers in MADT (Sunil V L) - Add RHCT flags, CMO and MMU nodes (Sunil V L) - Change ACPICA version to 20230628 (Bob Moore) - Introduce new wrappers for ACPICA notify handler install/remove and convert multiple drivers to using their own Notify() handlers instead of the ACPI bus type .notify() slated for removal (Michal Wilczynski) - Add backlight=native DMI quirk for Apple iMac12,1 and iMac12,2 (Hans de Goede) - Put ACPI video and its child devices explicitly into D0 on boot to avoid platform firmware confusion (Kai-Heng Feng) - Add backlight=native DMI quirk for Lenovo Ideapad Z470 (Jiri Slaby) - Support obtaining physical CPU ID from MADT on LoongArch (Bibo Mao) - Convert ACPI CPU initialization to using _OSC instead of _PDC that has been depreceted since 2018 and dropped from the specification in ACPI 6.5 (Michal Wilczynski, Rafael Wysocki) - Drop non-functional nocrt parameter from ACPI thermal (Mario Limonciello) - Clean up the ACPI thermal driver, rework the handling of firmware notifications in it and make it provide a table of generic trip point structures to the core during initialization (Rafael Wysocki) - Defer enumeration of devices with _DEP pointing to IVSC (Wentong Wu) - Install SystemCMOS address space handler for ACPI000E (TAD) to meet platform firmware expectations on some platforms (Zhang Rui) - Fix finding the generic error data in the ACPi extlog driver for compatibility with old and new firmware interface versions (Xiaochun Lee) - Remove assorted unused declarations of functions (Yue Haibing) - Move AMBA bus scan handling into arm64 specific directory (Sudeep Holla) - Fix and clean up suspend-to-idle interface for AMD systems (Mario Limonciello, Andy Shevchenko) - Fix string truncation warning in pnpacpi_add_device() (Sunil V L)" * tag 'acpi-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (66 commits) ACPI: x86: s2idle: Add a function to get LPS0 constraint for a device ACPI: x86: s2idle: Add for_each_lpi_constraint() helper ACPI: x86: s2idle: Add more debugging for AMD constraints parsing ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table ACPI: x86: s2idle: Catch multiple ACPI_TYPE_PACKAGE objects ACPI: x86: s2idle: Post-increment variables when getting constraints ACPI: Adjust #ifdef for *_lps0_dev use ACPI: TAD: Install SystemCMOS address space handler for ACPI000E ACPI: Remove assorted unused declarations of functions ACPI: extlog: Fix finding the generic error data for v3 structure PNP: ACPI: Fix string truncation warning ACPI: Remove unused extern declaration acpi_paddr_to_node() ACPI: video: Add backlight=native DMI quirk for Apple iMac12,1 and iMac12,2 ACPI: video: Put ACPI video and its child devices into D0 on boot ACPI: processor: LoongArch: Get physical ID from MADT ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device ACPI: thermal: Eliminate code duplication from acpi_thermal_notify() ACPI: thermal: Drop unnecessary thermal zone callbacks ACPI: thermal: Rework thermal_get_trend() ACPI: thermal: Use trip point table to register thermal zones ...
This commit is contained in:
commit
330235e874
@ -6333,10 +6333,6 @@
|
||||
-1: disable all critical trip points in all thermal zones
|
||||
<degrees C>: override all critical trip points
|
||||
|
||||
thermal.nocrt= [HW,ACPI]
|
||||
Set to disable actions on ACPI thermal zone
|
||||
critical and hot trip points.
|
||||
|
||||
thermal.off= [HW,ACPI]
|
||||
1: disable ACPI thermal control
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <acpi/pdc_intel.h>
|
||||
#include <acpi/proc_cap_intel.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/numa.h>
|
||||
@ -69,9 +69,9 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
|
||||
#endif
|
||||
|
||||
static inline bool arch_has_acpi_pdc(void) { return true; }
|
||||
static inline void arch_acpi_set_pdc_bits(u32 *buf)
|
||||
static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
|
||||
{
|
||||
buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
*cap |= ACPI_PROC_CAP_EST_CAPABILITY_SMP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
|
||||
* Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
|
||||
*/
|
||||
#include <acpi/pdc_intel.h>
|
||||
#include <acpi/proc_cap_intel.h>
|
||||
|
||||
#include <asm/numa.h>
|
||||
#include <asm/fixmap.h>
|
||||
@ -102,23 +102,31 @@ static inline bool arch_has_acpi_pdc(void)
|
||||
c->x86_vendor == X86_VENDOR_CENTAUR);
|
||||
}
|
||||
|
||||
static inline void arch_acpi_set_pdc_bits(u32 *buf)
|
||||
static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
buf[2] |= ACPI_PDC_C_CAPABILITY_SMP;
|
||||
*cap |= ACPI_PROC_CAP_C_CAPABILITY_SMP;
|
||||
|
||||
/* Enable coordination with firmware's _TSD info */
|
||||
*cap |= ACPI_PROC_CAP_SMP_T_SWCOORD;
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_EST))
|
||||
buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
|
||||
*cap |= ACPI_PROC_CAP_EST_CAPABILITY_SWSMP;
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_ACPI))
|
||||
buf[2] |= ACPI_PDC_T_FFH;
|
||||
*cap |= ACPI_PROC_CAP_T_FFH;
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_HWP))
|
||||
*cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF;
|
||||
|
||||
/*
|
||||
* If mwait/monitor is unsupported, C2/C3_FFH will be disabled
|
||||
* If mwait/monitor is unsupported, C_C1_FFH and
|
||||
* C2/C3_FFH will be disabled.
|
||||
*/
|
||||
if (!cpu_has(c, X86_FEATURE_MWAIT))
|
||||
buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
|
||||
if (!cpu_has(c, X86_FEATURE_MWAIT) ||
|
||||
boot_option_idle_override == IDLE_NOMWAIT)
|
||||
*cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH);
|
||||
}
|
||||
|
||||
static inline bool acpi_has_cpu_in_madt(void)
|
||||
|
@ -79,7 +79,7 @@
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <acpi/pdc_intel.h>
|
||||
#include <acpi/proc_cap_intel.h>
|
||||
#include <acpi/processor.h>
|
||||
#include <xen/interface/platform.h>
|
||||
#endif
|
||||
@ -288,17 +288,17 @@ static bool __init xen_check_mwait(void)
|
||||
|
||||
native_cpuid(&ax, &bx, &cx, &dx);
|
||||
|
||||
/* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so,
|
||||
/* Ask the Hypervisor whether to clear ACPI_PROC_CAP_C_C2C3_FFH. If so,
|
||||
* don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3.
|
||||
*/
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP);
|
||||
buf[2] = (ACPI_PROC_CAP_C_CAPABILITY_SMP | ACPI_PROC_CAP_EST_CAPABILITY_SWSMP);
|
||||
|
||||
set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
|
||||
|
||||
if ((HYPERVISOR_platform_op(&op) == 0) &&
|
||||
(buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) {
|
||||
(buf[2] & (ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH))) {
|
||||
cpuid_leaf5_ecx_val = cx;
|
||||
cpuid_leaf5_edx_val = dx;
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ acpi-$(CONFIG_PCI) += acpi_lpss.o
|
||||
acpi-y += acpi_apd.o
|
||||
acpi-y += acpi_platform.o
|
||||
acpi-y += acpi_pnp.o
|
||||
acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o
|
||||
acpi-y += power.o
|
||||
acpi-y += event.o
|
||||
acpi-y += evged.o
|
||||
|
@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static int acpi_ac_add(struct acpi_device *device);
|
||||
static void acpi_ac_remove(struct acpi_device *device);
|
||||
static void acpi_ac_notify(struct acpi_device *device, u32 event);
|
||||
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
|
||||
|
||||
static const struct acpi_device_id ac_device_ids[] = {
|
||||
{"ACPI0003", 0},
|
||||
@ -54,11 +54,9 @@ static struct acpi_driver acpi_ac_driver = {
|
||||
.name = "ac",
|
||||
.class = ACPI_AC_CLASS,
|
||||
.ids = ac_device_ids,
|
||||
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
|
||||
.ops = {
|
||||
.add = acpi_ac_add,
|
||||
.remove = acpi_ac_remove,
|
||||
.notify = acpi_ac_notify,
|
||||
},
|
||||
.drv.pm = &acpi_ac_pm,
|
||||
};
|
||||
@ -128,8 +126,9 @@ static enum power_supply_property ac_props[] = {
|
||||
};
|
||||
|
||||
/* Driver Model */
|
||||
static void acpi_ac_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *device = data;
|
||||
struct acpi_ac *ac = acpi_driver_data(device);
|
||||
|
||||
if (!ac)
|
||||
@ -235,7 +234,7 @@ static int acpi_ac_add(struct acpi_device *device)
|
||||
|
||||
result = acpi_ac_get_state(ac);
|
||||
if (result)
|
||||
goto end;
|
||||
goto err_release_ac;
|
||||
|
||||
psy_cfg.drv_data = ac;
|
||||
|
||||
@ -248,7 +247,7 @@ static int acpi_ac_add(struct acpi_device *device)
|
||||
&ac->charger_desc, &psy_cfg);
|
||||
if (IS_ERR(ac->charger)) {
|
||||
result = PTR_ERR(ac->charger);
|
||||
goto end;
|
||||
goto err_release_ac;
|
||||
}
|
||||
|
||||
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
|
||||
@ -256,9 +255,19 @@ static int acpi_ac_add(struct acpi_device *device)
|
||||
|
||||
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
|
||||
register_acpi_notifier(&ac->battery_nb);
|
||||
end:
|
||||
|
||||
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
|
||||
acpi_ac_notify);
|
||||
if (result)
|
||||
kfree(ac);
|
||||
goto err_unregister;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
power_supply_unregister(ac->charger);
|
||||
unregister_acpi_notifier(&ac->battery_nb);
|
||||
err_release_ac:
|
||||
kfree(ac);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -297,6 +306,8 @@ static void acpi_ac_remove(struct acpi_device *device)
|
||||
|
||||
ac = acpi_driver_data(device);
|
||||
|
||||
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
|
||||
acpi_ac_notify);
|
||||
power_supply_unregister(ac->charger);
|
||||
unregister_acpi_notifier(&ac->battery_nb);
|
||||
|
||||
|
@ -51,12 +51,11 @@ acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_install_address_space_handler(adev->handle,
|
||||
status = acpi_install_address_space_handler(handle,
|
||||
ACPI_ADR_SPACE_CMOS,
|
||||
&acpi_cmos_rtc_space_handler,
|
||||
NULL, NULL);
|
||||
@ -67,18 +66,30 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler);
|
||||
|
||||
static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
|
||||
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
|
||||
{
|
||||
if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
|
||||
if (ACPI_FAILURE(acpi_remove_address_space_handler(handle,
|
||||
ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
|
||||
pr_err("Error removing CMOS-RTC region handler\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler);
|
||||
|
||||
static int acpi_cmos_rtc_attach_handler(struct acpi_device *adev, const struct acpi_device_id *id)
|
||||
{
|
||||
return acpi_install_cmos_rtc_space_handler(adev->handle);
|
||||
}
|
||||
|
||||
static void acpi_cmos_rtc_detach_handler(struct acpi_device *adev)
|
||||
{
|
||||
acpi_remove_cmos_rtc_space_handler(adev->handle);
|
||||
}
|
||||
|
||||
static struct acpi_scan_handler cmos_rtc_handler = {
|
||||
.ids = acpi_cmos_rtc_ids,
|
||||
.attach = acpi_install_cmos_rtc_space_handler,
|
||||
.detach = acpi_remove_cmos_rtc_space_handler,
|
||||
.attach = acpi_cmos_rtc_attach_handler,
|
||||
.detach = acpi_cmos_rtc_detach_handler,
|
||||
};
|
||||
|
||||
void __init acpi_cmos_rtc_init(void)
|
||||
|
@ -172,7 +172,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
|
||||
fru_text = "";
|
||||
sec_type = (guid_t *)gdata->section_type;
|
||||
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
|
||||
struct cper_sec_mem_err *mem = (void *)(gdata + 1);
|
||||
struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata);
|
||||
|
||||
if (gdata->error_data_length >= sizeof(*mem))
|
||||
trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
|
||||
|
@ -9,9 +9,11 @@
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*/
|
||||
#define pr_fmt(fmt) "ACPI: " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
@ -21,6 +23,8 @@
|
||||
|
||||
#include <asm/cpu.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
DEFINE_PER_CPU(struct acpi_processor *, processors);
|
||||
@ -508,54 +512,110 @@ static void acpi_processor_remove(struct acpi_device *device)
|
||||
}
|
||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
static bool acpi_hwp_native_thermal_lvt_set;
|
||||
static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
|
||||
u32 lvl,
|
||||
void *context,
|
||||
void **rv)
|
||||
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
|
||||
bool __init processor_physically_present(acpi_handle handle)
|
||||
{
|
||||
u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
|
||||
u32 capbuf[2];
|
||||
int cpuid, type;
|
||||
u32 acpi_id;
|
||||
acpi_status status;
|
||||
acpi_object_type acpi_type;
|
||||
unsigned long long tmp;
|
||||
union acpi_object object = {};
|
||||
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
|
||||
|
||||
status = acpi_get_type(handle, &acpi_type);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
switch (acpi_type) {
|
||||
case ACPI_TYPE_PROCESSOR:
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = object.processor.proc_id;
|
||||
break;
|
||||
case ACPI_TYPE_DEVICE:
|
||||
status = acpi_evaluate_integer(handle, METHOD_NAME__UID,
|
||||
NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = tmp;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xen_initial_domain())
|
||||
/*
|
||||
* When running as a Xen dom0 the number of processors Linux
|
||||
* sees can be different from the real number of processors on
|
||||
* the system, and we still need to execute _PDC or _OSC for
|
||||
* all of them.
|
||||
*/
|
||||
return xen_processor_present(acpi_id);
|
||||
|
||||
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
|
||||
cpuid = acpi_get_cpuid(handle, type, acpi_id);
|
||||
|
||||
return !invalid_logical_cpuid(cpuid);
|
||||
}
|
||||
|
||||
/* vendor specific UUID indicating an Intel platform */
|
||||
static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
|
||||
|
||||
static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl,
|
||||
void *context, void **rv)
|
||||
{
|
||||
u32 capbuf[2] = {};
|
||||
struct acpi_osc_context osc_context = {
|
||||
.uuid_str = sb_uuid_str,
|
||||
.rev = 1,
|
||||
.cap.length = 8,
|
||||
.cap.pointer = capbuf,
|
||||
};
|
||||
acpi_status status;
|
||||
|
||||
if (acpi_hwp_native_thermal_lvt_set)
|
||||
return AE_CTRL_TERMINATE;
|
||||
if (!processor_physically_present(handle))
|
||||
return AE_OK;
|
||||
|
||||
capbuf[0] = 0x0000;
|
||||
capbuf[1] = 0x1000; /* set bit 12 */
|
||||
arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]);
|
||||
|
||||
if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
|
||||
if (osc_context.ret.pointer && osc_context.ret.length > 1) {
|
||||
u32 *capbuf_ret = osc_context.ret.pointer;
|
||||
status = acpi_run_osc(handle, &osc_context);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
if (capbuf_ret[1] & 0x1000) {
|
||||
acpi_handle_info(handle,
|
||||
"_OSC native thermal LVT Acked\n");
|
||||
acpi_hwp_native_thermal_lvt_set = true;
|
||||
}
|
||||
}
|
||||
kfree(osc_context.ret.pointer);
|
||||
}
|
||||
kfree(osc_context.ret.pointer);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void __init acpi_early_processor_osc(void)
|
||||
static bool __init acpi_early_processor_osc(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_HWP)) {
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_hwp_native_thermal_lvt_osc,
|
||||
NULL, NULL, NULL);
|
||||
acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
|
||||
acpi_hwp_native_thermal_lvt_osc,
|
||||
NULL, NULL);
|
||||
acpi_status status;
|
||||
|
||||
acpi_proc_quirk_mwait_check();
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, acpi_processor_osc, NULL,
|
||||
NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
status = acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, acpi_processor_osc,
|
||||
NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void __init acpi_early_processor_control_setup(void)
|
||||
{
|
||||
if (acpi_early_processor_osc()) {
|
||||
pr_info("_OSC evaluated successfully for all CPUs\n");
|
||||
} else {
|
||||
pr_info("_OSC evaluation for CPUs failed, trying _PDC\n");
|
||||
acpi_early_processor_set_pdc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -557,6 +557,7 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
|
||||
static int acpi_tad_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
|
||||
|
||||
device_init_wakeup(dev, false);
|
||||
@ -577,6 +578,7 @@ static int acpi_tad_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
acpi_remove_cmos_rtc_space_handler(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -589,6 +591,11 @@ static int acpi_tad_probe(struct platform_device *pdev)
|
||||
unsigned long long caps;
|
||||
int ret;
|
||||
|
||||
ret = acpi_install_cmos_rtc_space_handler(handle);
|
||||
if (ret < 0) {
|
||||
dev_info(dev, "Unable to install space handler\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
/*
|
||||
* Initialization failure messages are mostly about firmware issues, so
|
||||
* print them at the "info" level.
|
||||
@ -596,22 +603,27 @@ static int acpi_tad_probe(struct platform_device *pdev)
|
||||
status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_info(dev, "Unable to get capabilities\n");
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto remove_handler;
|
||||
}
|
||||
|
||||
if (!(caps & ACPI_TAD_AC_WAKE)) {
|
||||
dev_info(dev, "Unsupported capabilities\n");
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto remove_handler;
|
||||
}
|
||||
|
||||
if (!acpi_has_method(handle, "_PRW")) {
|
||||
dev_info(dev, "Missing _PRW\n");
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto remove_handler;
|
||||
}
|
||||
|
||||
dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
|
||||
if (!dd)
|
||||
return -ENOMEM;
|
||||
if (!dd) {
|
||||
ret = -ENOMEM;
|
||||
goto remove_handler;
|
||||
}
|
||||
|
||||
dd->capabilities = caps;
|
||||
dev_set_drvdata(dev, dd);
|
||||
@ -653,6 +665,11 @@ static int acpi_tad_probe(struct platform_device *pdev)
|
||||
|
||||
fail:
|
||||
acpi_tad_remove(pdev);
|
||||
/* Don't fallthrough because cmos rtc space handler is removed in acpi_tad_remove() */
|
||||
return ret;
|
||||
|
||||
remove_handler:
|
||||
acpi_remove_cmos_rtc_space_handler(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ static DEFINE_MUTEX(video_list_lock);
|
||||
static LIST_HEAD(video_bus_head);
|
||||
static int acpi_video_bus_add(struct acpi_device *device);
|
||||
static void acpi_video_bus_remove(struct acpi_device *device);
|
||||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
|
||||
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
|
||||
|
||||
/*
|
||||
* Indices in the _BCL method response: the first two items are special,
|
||||
@ -104,7 +104,6 @@ static struct acpi_driver acpi_video_bus = {
|
||||
.ops = {
|
||||
.add = acpi_video_bus_add,
|
||||
.remove = acpi_video_bus_remove,
|
||||
.notify = acpi_video_bus_notify,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1527,8 +1526,9 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
|
||||
acpi_osi_is_win8() ? 0 : 1);
|
||||
}
|
||||
|
||||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *device = data;
|
||||
struct acpi_video_bus *video = acpi_driver_data(device);
|
||||
struct input_dev *input;
|
||||
int keycode = 0;
|
||||
@ -2027,6 +2027,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
if (error)
|
||||
goto err_put_video;
|
||||
|
||||
/*
|
||||
* HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0
|
||||
* evaluated to have functional panel brightness control.
|
||||
*/
|
||||
acpi_device_fix_up_power_extended(device);
|
||||
|
||||
pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",
|
||||
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
|
||||
video->flags.multihead ? "yes" : "no",
|
||||
@ -2053,8 +2059,19 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
|
||||
acpi_video_bus_add_notify_handler(video);
|
||||
|
||||
error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_bus_notify);
|
||||
if (error)
|
||||
goto err_remove;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove:
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
acpi_video_bus_remove_notify_handler(video);
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
err_put_video:
|
||||
acpi_video_bus_put_devices(video);
|
||||
kfree(video->attached_array);
|
||||
@ -2075,6 +2092,9 @@ static void acpi_video_bus_remove(struct acpi_device *device)
|
||||
|
||||
video = acpi_driver_data(device);
|
||||
|
||||
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_bus_notify);
|
||||
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
@ -287,4 +287,6 @@ struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name);
|
||||
|
||||
void acpi_db_uint32_to_hex_string(u32 value, char *buffer);
|
||||
|
||||
void acpi_db_generate_interrupt(char *gsiv_arg);
|
||||
|
||||
#endif /* __ACDEBUG_H__ */
|
||||
|
@ -129,6 +129,7 @@ ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler);
|
||||
ACPI_GLOBAL(void *, acpi_gbl_table_handler_context);
|
||||
ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler);
|
||||
ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list);
|
||||
ACPI_GLOBAL(struct acpi_ged_handler_info *, acpi_gbl_ged_handler_list);
|
||||
|
||||
/* Owner ID support */
|
||||
|
||||
|
@ -543,6 +543,14 @@ struct acpi_field_info {
|
||||
u32 pkg_length;
|
||||
};
|
||||
|
||||
/* Information about the interrupt ID and _EVT of a GED device */
|
||||
|
||||
struct acpi_ged_handler_info {
|
||||
struct acpi_ged_handler_info *next;
|
||||
u32 int_id; /* The interrupt ID that triggers the execution ofthe evt_method. */
|
||||
struct acpi_namespace_node *evt_method; /* The _EVT method to be executed when an interrupt with ID = int_ID is received */
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Generic "state" object for stacks
|
||||
@ -560,25 +568,28 @@ struct acpi_field_info {
|
||||
u8 descriptor_type; /* To differentiate various internal objs */\
|
||||
u8 flags; \
|
||||
u16 value; \
|
||||
u16 state;
|
||||
u16 state
|
||||
|
||||
/* There are 2 bytes available here until the next natural alignment boundary */
|
||||
|
||||
struct acpi_common_state {
|
||||
ACPI_STATE_COMMON};
|
||||
ACPI_STATE_COMMON;
|
||||
};
|
||||
|
||||
/*
|
||||
* Update state - used to traverse complex objects such as packages
|
||||
*/
|
||||
struct acpi_update_state {
|
||||
ACPI_STATE_COMMON union acpi_operand_object *object;
|
||||
ACPI_STATE_COMMON;
|
||||
union acpi_operand_object *object;
|
||||
};
|
||||
|
||||
/*
|
||||
* Pkg state - used to traverse nested package structures
|
||||
*/
|
||||
struct acpi_pkg_state {
|
||||
ACPI_STATE_COMMON u32 index;
|
||||
ACPI_STATE_COMMON;
|
||||
u32 index;
|
||||
union acpi_operand_object *source_object;
|
||||
union acpi_operand_object *dest_object;
|
||||
struct acpi_walk_state *walk_state;
|
||||
@ -591,7 +602,8 @@ struct acpi_pkg_state {
|
||||
* Allows nesting of these constructs
|
||||
*/
|
||||
struct acpi_control_state {
|
||||
ACPI_STATE_COMMON u16 opcode;
|
||||
ACPI_STATE_COMMON;
|
||||
u16 opcode;
|
||||
union acpi_parse_object *predicate_op;
|
||||
u8 *aml_predicate_start; /* Start of if/while predicate */
|
||||
u8 *package_end; /* End of if/while block */
|
||||
@ -602,11 +614,13 @@ struct acpi_control_state {
|
||||
* Scope state - current scope during namespace lookups
|
||||
*/
|
||||
struct acpi_scope_state {
|
||||
ACPI_STATE_COMMON struct acpi_namespace_node *node;
|
||||
ACPI_STATE_COMMON;
|
||||
struct acpi_namespace_node *node;
|
||||
};
|
||||
|
||||
struct acpi_pscope_state {
|
||||
ACPI_STATE_COMMON u32 arg_count; /* Number of fixed arguments */
|
||||
ACPI_STATE_COMMON;
|
||||
u32 arg_count; /* Number of fixed arguments */
|
||||
union acpi_parse_object *op; /* Current op being parsed */
|
||||
u8 *arg_end; /* Current argument end */
|
||||
u8 *pkg_end; /* Current package end */
|
||||
@ -618,7 +632,8 @@ struct acpi_pscope_state {
|
||||
* states are created when there are nested control methods executing.
|
||||
*/
|
||||
struct acpi_thread_state {
|
||||
ACPI_STATE_COMMON u8 current_sync_level; /* Mutex Sync (nested acquire) level */
|
||||
ACPI_STATE_COMMON;
|
||||
u8 current_sync_level; /* Mutex Sync (nested acquire) level */
|
||||
struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */
|
||||
union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */
|
||||
acpi_thread_id thread_id; /* Running thread ID */
|
||||
@ -629,8 +644,8 @@ struct acpi_thread_state {
|
||||
* AML arguments
|
||||
*/
|
||||
struct acpi_result_values {
|
||||
ACPI_STATE_COMMON
|
||||
union acpi_operand_object *obj_desc[ACPI_RESULTS_FRAME_OBJ_NUM];
|
||||
ACPI_STATE_COMMON;
|
||||
union acpi_operand_object *obj_desc[ACPI_RESULTS_FRAME_OBJ_NUM];
|
||||
};
|
||||
|
||||
typedef
|
||||
@ -652,7 +667,8 @@ struct acpi_global_notify_handler {
|
||||
* handler/dispatcher.
|
||||
*/
|
||||
struct acpi_notify_info {
|
||||
ACPI_STATE_COMMON u8 handler_list_id;
|
||||
ACPI_STATE_COMMON;
|
||||
u8 handler_list_id;
|
||||
struct acpi_namespace_node *node;
|
||||
union acpi_operand_object *handler_list_head;
|
||||
struct acpi_global_notify_handler *global;
|
||||
|
@ -440,6 +440,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
|
||||
{{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER),
|
||||
METHOD_NO_RETURN_VALUE}},
|
||||
|
||||
{{"_DSC", METHOD_0ARGS,
|
||||
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},
|
||||
|
||||
{{"_DSD", METHOD_0ARGS, /* ACPI 6.0 */
|
||||
METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */
|
||||
PACKAGE_INFO(ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1,
|
||||
|
@ -1010,6 +1010,64 @@ void acpi_db_display_resources(char *object_arg)
|
||||
acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_db_generate_ged
|
||||
*
|
||||
* PARAMETERS: ged_arg - Raw GED number, ascii string
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Simulate firing of a GED
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void acpi_db_generate_interrupt(char *gsiv_arg)
|
||||
{
|
||||
u32 gsiv_number;
|
||||
struct acpi_ged_handler_info *ged_info = acpi_gbl_ged_handler_list;
|
||||
|
||||
if (!ged_info) {
|
||||
acpi_os_printf("No GED handling present\n");
|
||||
}
|
||||
|
||||
gsiv_number = strtoul(gsiv_arg, NULL, 0);
|
||||
|
||||
while (ged_info) {
|
||||
|
||||
if (ged_info->int_id == gsiv_number) {
|
||||
struct acpi_object_list arg_list;
|
||||
union acpi_object arg0;
|
||||
acpi_handle evt_handle = ged_info->evt_method;
|
||||
acpi_status status;
|
||||
|
||||
acpi_os_printf("Evaluate GED _EVT (GSIV=%d)\n",
|
||||
gsiv_number);
|
||||
|
||||
if (!evt_handle) {
|
||||
acpi_os_printf("Undefined _EVT method\n");
|
||||
return;
|
||||
}
|
||||
|
||||
arg0.integer.type = ACPI_TYPE_INTEGER;
|
||||
arg0.integer.value = gsiv_number;
|
||||
|
||||
arg_list.count = 1;
|
||||
arg_list.pointer = &arg0;
|
||||
|
||||
status =
|
||||
acpi_evaluate_object(evt_handle, NULL, &arg_list,
|
||||
NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_os_printf("Could not evaluate _EVT\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
ged_info = ged_info->next;
|
||||
}
|
||||
}
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
@ -106,6 +106,7 @@ enum acpi_ex_debugger_commands {
|
||||
CMD_THREADS,
|
||||
|
||||
CMD_TEST,
|
||||
CMD_INTERRUPT,
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -185,6 +186,7 @@ static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
|
||||
{"THREADS", 3},
|
||||
|
||||
{"TEST", 1},
|
||||
{"INTERRUPT", 1},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
@ -318,6 +320,7 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
|
||||
{1, " Gpes", "Display info on all GPE devices\n"},
|
||||
{1, " Sci", "Generate an SCI\n"},
|
||||
{1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
|
||||
{1, " Interrupt <GSIV>", "Simulate an interrupt\n"},
|
||||
#endif
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
@ -1064,6 +1067,11 @@ acpi_db_command_dispatch(char *input_buffer,
|
||||
acpi_os_printf("Event command not implemented\n");
|
||||
break;
|
||||
|
||||
case CMD_INTERRUPT:
|
||||
|
||||
acpi_db_generate_interrupt(acpi_gbl_db_args[1]);
|
||||
break;
|
||||
|
||||
case CMD_GPE:
|
||||
|
||||
acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
|
||||
|
@ -146,8 +146,8 @@ acpi_ds_result_push(union acpi_operand_object *object,
|
||||
|
||||
if (!object) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Null Object! Obj=%p State=%p Num=%u",
|
||||
object, walk_state, walk_state->result_count));
|
||||
"Null Object! State=%p Num=%u",
|
||||
walk_state, walk_state->result_count));
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
|
@ -343,8 +343,7 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
|
||||
/* Copy the input buffer data to the transfer buffer */
|
||||
|
||||
buffer = buffer_desc->buffer.pointer;
|
||||
data_length = (buffer_length < source_desc->buffer.length ?
|
||||
buffer_length : source_desc->buffer.length);
|
||||
data_length = ACPI_MIN(buffer_length, source_desc->buffer.length);
|
||||
memcpy(buffer, source_desc->buffer.pointer, data_length);
|
||||
|
||||
/* Lock entire transaction if requested */
|
||||
|
@ -603,7 +603,7 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
|
||||
|
||||
/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
|
||||
AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
|
||||
AML_FLAGS_EXEC_0A_0T_1R),
|
||||
AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE),
|
||||
|
||||
/* ACPI 5.0 opcodes */
|
||||
|
||||
|
@ -37,7 +37,12 @@ void acpi_ut_init_stack_ptr_trace(void)
|
||||
{
|
||||
acpi_size current_sp;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if defined(__GNUC__) && __GNUC__ >= 12
|
||||
#pragma GCC diagnostic ignored "-Wdangling-pointer="
|
||||
#endif
|
||||
acpi_gbl_entry_stack_pointer = ¤t_sp;
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -3,4 +3,5 @@ obj-$(CONFIG_ACPI_AGDI) += agdi.o
|
||||
obj-$(CONFIG_ACPI_IORT) += iort.o
|
||||
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
|
||||
obj-$(CONFIG_ACPI_APMT) += apmt.o
|
||||
obj-$(CONFIG_ARM_AMBA) += amba.o
|
||||
obj-y += dma.o init.o
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "init.h"
|
||||
|
||||
static const struct acpi_device_id amba_id_list[] = {
|
||||
{"ARMH0061", 0}, /* PL061 GPIO Device */
|
@ -10,4 +10,6 @@ void __init acpi_arm_init(void)
|
||||
acpi_apmt_init();
|
||||
if (IS_ENABLED(CONFIG_ACPI_IORT))
|
||||
acpi_iort_init();
|
||||
if (IS_ENABLED(CONFIG_ARM_AMBA))
|
||||
acpi_amba_init();
|
||||
}
|
||||
|
@ -4,3 +4,4 @@
|
||||
void __init acpi_agdi_init(void);
|
||||
void __init acpi_apmt_init(void);
|
||||
void __init acpi_iort_init(void);
|
||||
void __init acpi_amba_init(void);
|
||||
|
@ -1034,8 +1034,9 @@ static void acpi_battery_refresh(struct acpi_battery *battery)
|
||||
}
|
||||
|
||||
/* Driver Interface */
|
||||
static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *device = data;
|
||||
struct acpi_battery *battery = acpi_driver_data(device);
|
||||
struct power_supply *old;
|
||||
|
||||
@ -1212,13 +1213,22 @@ static int acpi_battery_add(struct acpi_device *device)
|
||||
|
||||
device_init_wakeup(&device->dev, 1);
|
||||
|
||||
return result;
|
||||
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify);
|
||||
if (result)
|
||||
goto fail_pm;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_pm:
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
fail:
|
||||
sysfs_remove_battery(battery);
|
||||
mutex_destroy(&battery->lock);
|
||||
mutex_destroy(&battery->sysfs_lock);
|
||||
kfree(battery);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1228,10 +1238,16 @@ static void acpi_battery_remove(struct acpi_device *device)
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return;
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
|
||||
battery = acpi_driver_data(device);
|
||||
|
||||
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify);
|
||||
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
sysfs_remove_battery(battery);
|
||||
|
||||
mutex_destroy(&battery->lock);
|
||||
mutex_destroy(&battery->sysfs_lock);
|
||||
kfree(battery);
|
||||
@ -1264,11 +1280,9 @@ static struct acpi_driver acpi_battery_driver = {
|
||||
.name = "battery",
|
||||
.class = ACPI_BATTERY_CLASS,
|
||||
.ids = battery_device_ids,
|
||||
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
|
||||
.ops = {
|
||||
.add = acpi_battery_add,
|
||||
.remove = acpi_battery_remove,
|
||||
.notify = acpi_battery_notify,
|
||||
},
|
||||
.drv.pm = &acpi_battery_pm,
|
||||
};
|
||||
|
@ -554,6 +554,30 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device,
|
||||
acpi_os_wait_events_complete();
|
||||
}
|
||||
|
||||
int acpi_dev_install_notify_handler(struct acpi_device *adev,
|
||||
u32 handler_type,
|
||||
acpi_notify_handler handler)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_install_notify_handler(adev->handle, handler_type,
|
||||
handler, adev);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_install_notify_handler);
|
||||
|
||||
void acpi_dev_remove_notify_handler(struct acpi_device *adev,
|
||||
u32 handler_type,
|
||||
acpi_notify_handler handler)
|
||||
{
|
||||
acpi_remove_notify_handler(adev->handle, handler_type, handler);
|
||||
acpi_os_wait_events_complete();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_remove_notify_handler);
|
||||
|
||||
/* Handle events targeting \_SB device (at present only graceful shutdown) */
|
||||
|
||||
#define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
|
||||
@ -1005,8 +1029,10 @@ static int acpi_device_probe(struct device *dev)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = acpi_drv->ops.add(acpi_dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
acpi_dev->driver_data = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("Driver [%s] successfully bound to device [%s]\n",
|
||||
acpi_drv->name, acpi_dev->pnp.bus_id);
|
||||
@ -1296,9 +1322,6 @@ static int __init acpi_bus_init(void)
|
||||
goto error1;
|
||||
}
|
||||
|
||||
/* Set capability bits for _OSC under processor scope */
|
||||
acpi_early_processor_osc();
|
||||
|
||||
/*
|
||||
* _OSC method may exist in module level code,
|
||||
* so it must be run after ACPI_FULL_INITIALIZATION
|
||||
@ -1314,7 +1337,7 @@ static int __init acpi_bus_init(void)
|
||||
|
||||
acpi_sysfs_init();
|
||||
|
||||
acpi_early_processor_set_pdc();
|
||||
acpi_early_processor_control_setup();
|
||||
|
||||
/*
|
||||
* Maybe EC region is required at bus_scan/acpi_get_devices. So it
|
||||
|
@ -42,22 +42,32 @@ EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
|
||||
* it is used by HEST Generic Hardware Error Source with notify type
|
||||
* SCI.
|
||||
*/
|
||||
static void acpi_hed_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
|
||||
}
|
||||
|
||||
static int acpi_hed_add(struct acpi_device *device)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Only one hardware error device */
|
||||
if (hed_handle)
|
||||
return -EINVAL;
|
||||
hed_handle = device->handle;
|
||||
return 0;
|
||||
|
||||
err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_hed_notify);
|
||||
if (err)
|
||||
hed_handle = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void acpi_hed_remove(struct acpi_device *device)
|
||||
{
|
||||
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_hed_notify);
|
||||
hed_handle = NULL;
|
||||
}
|
||||
|
||||
@ -68,7 +78,6 @@ static struct acpi_driver acpi_hed_driver = {
|
||||
.ops = {
|
||||
.add = acpi_hed_add,
|
||||
.remove = acpi_hed_remove,
|
||||
.notify = acpi_hed_notify,
|
||||
},
|
||||
};
|
||||
module_acpi_driver(acpi_hed_driver);
|
||||
|
@ -28,11 +28,6 @@ void acpi_processor_init(void);
|
||||
void acpi_platform_init(void);
|
||||
void acpi_pnp_init(void);
|
||||
void acpi_int340x_thermal_init(void);
|
||||
#ifdef CONFIG_ARM_AMBA
|
||||
void acpi_amba_init(void);
|
||||
#else
|
||||
static inline void acpi_amba_init(void) {}
|
||||
#endif
|
||||
int acpi_sysfs_init(void);
|
||||
void acpi_gpe_apply_masked_gpes(void);
|
||||
void acpi_container_init(void);
|
||||
@ -128,7 +123,6 @@ int __acpi_device_uevent_modalias(const struct acpi_device *adev,
|
||||
/* --------------------------------------------------------------------------
|
||||
Power Resource
|
||||
-------------------------------------------------------------------------- */
|
||||
int acpi_power_init(void);
|
||||
void acpi_power_resources_list_free(struct list_head *list);
|
||||
int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
|
||||
struct list_head *list);
|
||||
@ -152,15 +146,13 @@ int acpi_wakeup_device_init(void);
|
||||
Processor
|
||||
-------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
|
||||
void acpi_early_processor_control_setup(void);
|
||||
void acpi_early_processor_set_pdc(void);
|
||||
#else
|
||||
static inline void acpi_early_processor_set_pdc(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
void acpi_early_processor_osc(void);
|
||||
void acpi_proc_quirk_mwait_check(void);
|
||||
bool processor_physically_present(acpi_handle handle);
|
||||
#else
|
||||
static inline void acpi_early_processor_osc(void) {}
|
||||
static inline void acpi_early_processor_control_setup(void) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
|
@ -3282,6 +3282,23 @@ static void acpi_nfit_put_table(void *table)
|
||||
acpi_put_table(table);
|
||||
}
|
||||
|
||||
static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *adev = data;
|
||||
|
||||
device_lock(&adev->dev);
|
||||
__acpi_nfit_notify(&adev->dev, handle, event);
|
||||
device_unlock(&adev->dev);
|
||||
}
|
||||
|
||||
static void acpi_nfit_remove_notify_handler(void *data)
|
||||
{
|
||||
struct acpi_device *adev = data;
|
||||
|
||||
acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_nfit_notify);
|
||||
}
|
||||
|
||||
void acpi_nfit_shutdown(void *data)
|
||||
{
|
||||
struct acpi_nfit_desc *acpi_desc = data;
|
||||
@ -3368,12 +3385,18 @@ static int acpi_nfit_add(struct acpi_device *adev)
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
|
||||
}
|
||||
|
||||
static void acpi_nfit_remove(struct acpi_device *adev)
|
||||
{
|
||||
/* see acpi_nfit_unregister */
|
||||
rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_nfit_notify);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler,
|
||||
adev);
|
||||
}
|
||||
|
||||
static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
|
||||
@ -3446,13 +3469,6 @@ void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
|
||||
|
||||
static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
|
||||
{
|
||||
device_lock(&adev->dev);
|
||||
__acpi_nfit_notify(&adev->dev, adev->handle, event);
|
||||
device_unlock(&adev->dev);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id acpi_nfit_ids[] = {
|
||||
{ "ACPI0012", 0 },
|
||||
{ "", 0 },
|
||||
@ -3464,8 +3480,6 @@ static struct acpi_driver acpi_nfit_driver = {
|
||||
.ids = acpi_nfit_ids,
|
||||
.ops = {
|
||||
.add = acpi_nfit_add,
|
||||
.remove = acpi_nfit_remove,
|
||||
.notify = acpi_nfit_notify,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -132,6 +132,30 @@ static int map_rintc_hartid(struct acpi_subtable_header *entry,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve LoongArch CPU physical id
|
||||
*/
|
||||
static int map_core_pic_id(struct acpi_subtable_header *entry,
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *phys_id)
|
||||
{
|
||||
struct acpi_madt_core_pic *core_pic =
|
||||
container_of(entry, struct acpi_madt_core_pic, header);
|
||||
|
||||
if (!(core_pic->flags & ACPI_MADT_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
/* device_declaration means Device object in DSDT, in LoongArch
|
||||
* system, logical processor acpi_id is required in _UID property
|
||||
* of DSDT table, so we should check device_declaration here
|
||||
*/
|
||||
if (device_declaration && (core_pic->processor_id == acpi_id)) {
|
||||
*phys_id = core_pic->core_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
|
||||
int type, u32 acpi_id)
|
||||
{
|
||||
@ -165,6 +189,9 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
|
||||
} else if (header->type == ACPI_MADT_TYPE_RINTC) {
|
||||
if (!map_rintc_hartid(header, type, acpi_id, &phys_id))
|
||||
break;
|
||||
} else if (header->type == ACPI_MADT_TYPE_CORE_PIC) {
|
||||
if (!map_core_pic_id(header, type, acpi_id, &phys_id))
|
||||
break;
|
||||
}
|
||||
entry += header->length;
|
||||
}
|
||||
@ -216,6 +243,8 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
||||
map_x2apic_id(header, type, acpi_id, &phys_id);
|
||||
else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
|
||||
map_gicc_mpidr(header, type, acpi_id, &phys_id);
|
||||
else if (header->type == ACPI_MADT_TYPE_CORE_PIC)
|
||||
map_core_pic_id(header, type, acpi_id, &phys_id);
|
||||
|
||||
exit:
|
||||
kfree(buffer.pointer);
|
||||
|
@ -9,71 +9,19 @@
|
||||
|
||||
#define pr_fmt(fmt) "ACPI: " fmt
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static bool __init processor_physically_present(acpi_handle handle)
|
||||
{
|
||||
int cpuid, type;
|
||||
u32 acpi_id;
|
||||
acpi_status status;
|
||||
acpi_object_type acpi_type;
|
||||
unsigned long long tmp;
|
||||
union acpi_object object = { 0 };
|
||||
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
|
||||
|
||||
status = acpi_get_type(handle, &acpi_type);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
switch (acpi_type) {
|
||||
case ACPI_TYPE_PROCESSOR:
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = object.processor.proc_id;
|
||||
break;
|
||||
case ACPI_TYPE_DEVICE:
|
||||
status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = tmp;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xen_initial_domain())
|
||||
/*
|
||||
* When running as a Xen dom0 the number of processors Linux
|
||||
* sees can be different from the real number of processors on
|
||||
* the system, and we still need to execute _PDC for all of
|
||||
* them.
|
||||
*/
|
||||
return xen_processor_present(acpi_id);
|
||||
|
||||
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
|
||||
cpuid = acpi_get_cpuid(handle, type, acpi_id);
|
||||
|
||||
return !invalid_logical_cpuid(cpuid);
|
||||
}
|
||||
|
||||
static void acpi_set_pdc_bits(u32 *buf)
|
||||
{
|
||||
buf[0] = ACPI_PDC_REVISION_ID;
|
||||
buf[1] = 1;
|
||||
|
||||
/* Enable coordination with firmware's _TSD info */
|
||||
buf[2] = ACPI_PDC_SMP_T_SWCOORD;
|
||||
|
||||
/* Twiddle arch-specific bits needed for _PDC */
|
||||
arch_acpi_set_pdc_bits(buf);
|
||||
arch_acpi_set_proc_cap_bits(&buf[2]);
|
||||
}
|
||||
|
||||
static struct acpi_object_list *acpi_processor_alloc_pdc(void)
|
||||
@ -123,20 +71,6 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
if (boot_option_idle_override == IDLE_NOMWAIT) {
|
||||
/*
|
||||
* If mwait is disabled for CPU C-states, the C2C3_FFH access
|
||||
* mode will be disabled in the parameter of _PDC object.
|
||||
* Of course C1_FFH access mode will also be disabled.
|
||||
*/
|
||||
union acpi_object *obj;
|
||||
u32 *buffer = NULL;
|
||||
|
||||
obj = pdc_in->pointer;
|
||||
buffer = (u32 *)(obj->buffer.pointer);
|
||||
buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
|
||||
|
||||
}
|
||||
status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
@ -174,36 +108,9 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int __init set_no_mwait(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_notice("%s detected - disabling mwait for CPU C-states\n",
|
||||
id->ident);
|
||||
boot_option_idle_override = IDLE_NOMWAIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id processor_idle_dmi_table[] __initconst = {
|
||||
{
|
||||
set_no_mwait, "Extensa 5220", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
|
||||
{},
|
||||
};
|
||||
|
||||
static void __init processor_dmi_check(void)
|
||||
{
|
||||
/*
|
||||
* Check whether the system is DMI table. If yes, OSPM
|
||||
* should not use mwait for CPU-states.
|
||||
*/
|
||||
dmi_check_system(processor_idle_dmi_table);
|
||||
}
|
||||
|
||||
void __init acpi_early_processor_set_pdc(void)
|
||||
{
|
||||
processor_dmi_check();
|
||||
acpi_proc_quirk_mwait_check();
|
||||
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
|
@ -795,6 +795,9 @@ static const char * const acpi_ignore_dep_ids[] = {
|
||||
/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */
|
||||
static const char * const acpi_honor_dep_ids[] = {
|
||||
"INT3472", /* Camera sensor PMIC / clk and regulator info */
|
||||
"INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */
|
||||
"INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */
|
||||
"INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -2616,7 +2619,6 @@ void __init acpi_scan_init(void)
|
||||
acpi_watchdog_init();
|
||||
acpi_pnp_init();
|
||||
acpi_int340x_thermal_init();
|
||||
acpi_amba_init();
|
||||
acpi_init_lpit();
|
||||
|
||||
acpi_scan_add_handler(&generic_device_handler);
|
||||
|
@ -82,10 +82,6 @@ static int tzp;
|
||||
module_param(tzp, int, 0444);
|
||||
MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
|
||||
|
||||
static int nocrt;
|
||||
module_param(nocrt, int, 0);
|
||||
MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
|
||||
|
||||
static int off;
|
||||
module_param(off, int, 0);
|
||||
MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
|
||||
@ -96,35 +92,27 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
|
||||
|
||||
static struct workqueue_struct *acpi_thermal_pm_queue;
|
||||
|
||||
struct acpi_thermal_critical {
|
||||
unsigned long temperature;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct acpi_thermal_hot {
|
||||
struct acpi_thermal_trip {
|
||||
unsigned long temperature;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct acpi_thermal_passive {
|
||||
struct acpi_thermal_trip trip;
|
||||
struct acpi_handle_list devices;
|
||||
unsigned long temperature;
|
||||
unsigned long tc1;
|
||||
unsigned long tc2;
|
||||
unsigned long tsp;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct acpi_thermal_active {
|
||||
struct acpi_thermal_trip trip;
|
||||
struct acpi_handle_list devices;
|
||||
unsigned long temperature;
|
||||
bool valid;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct acpi_thermal_trips {
|
||||
struct acpi_thermal_critical critical;
|
||||
struct acpi_thermal_hot hot;
|
||||
struct acpi_thermal_trip critical;
|
||||
struct acpi_thermal_trip hot;
|
||||
struct acpi_thermal_passive passive;
|
||||
struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
|
||||
};
|
||||
@ -137,6 +125,7 @@ struct acpi_thermal {
|
||||
unsigned long polling_frequency;
|
||||
volatile u8 zombie;
|
||||
struct acpi_thermal_trips trips;
|
||||
struct thermal_trip *trip_table;
|
||||
struct acpi_handle_list devices;
|
||||
struct thermal_zone_device *thermal_zone;
|
||||
int kelvin_offset; /* in millidegrees */
|
||||
@ -190,7 +179,16 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k)
|
||||
{
|
||||
if (temp_deci_k == THERMAL_TEMP_INVALID)
|
||||
return THERMAL_TEMP_INVALID;
|
||||
|
||||
return deci_kelvin_to_millicelsius_with_offset(temp_deci_k,
|
||||
tz->kelvin_offset);
|
||||
}
|
||||
|
||||
static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
{
|
||||
acpi_status status;
|
||||
unsigned long long tmp;
|
||||
@ -255,9 +253,9 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
}
|
||||
|
||||
/* Passive (optional) */
|
||||
if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.valid) ||
|
||||
if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.trip.valid) ||
|
||||
flag == ACPI_TRIPS_INIT) {
|
||||
valid = tz->trips.passive.valid;
|
||||
valid = tz->trips.passive.trip.valid;
|
||||
if (psv == -1) {
|
||||
status = AE_SUPPORT;
|
||||
} else if (psv > 0) {
|
||||
@ -269,44 +267,44 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
tz->trips.passive.valid = false;
|
||||
tz->trips.passive.trip.valid = false;
|
||||
} else {
|
||||
tz->trips.passive.temperature = tmp;
|
||||
tz->trips.passive.valid = true;
|
||||
tz->trips.passive.trip.temperature = tmp;
|
||||
tz->trips.passive.trip.valid = true;
|
||||
if (flag == ACPI_TRIPS_INIT) {
|
||||
status = acpi_evaluate_integer(tz->device->handle,
|
||||
"_TC1", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
tz->trips.passive.valid = false;
|
||||
tz->trips.passive.trip.valid = false;
|
||||
else
|
||||
tz->trips.passive.tc1 = tmp;
|
||||
|
||||
status = acpi_evaluate_integer(tz->device->handle,
|
||||
"_TC2", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
tz->trips.passive.valid = false;
|
||||
tz->trips.passive.trip.valid = false;
|
||||
else
|
||||
tz->trips.passive.tc2 = tmp;
|
||||
|
||||
status = acpi_evaluate_integer(tz->device->handle,
|
||||
"_TSP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
tz->trips.passive.valid = false;
|
||||
tz->trips.passive.trip.valid = false;
|
||||
else
|
||||
tz->trips.passive.tsp = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.valid) {
|
||||
if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.trip.valid) {
|
||||
memset(&devices, 0, sizeof(struct acpi_handle_list));
|
||||
status = acpi_evaluate_reference(tz->device->handle, "_PSL",
|
||||
NULL, &devices);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_info(tz->device->handle,
|
||||
"Invalid passive threshold\n");
|
||||
tz->trips.passive.valid = false;
|
||||
tz->trips.passive.trip.valid = false;
|
||||
} else {
|
||||
tz->trips.passive.valid = true;
|
||||
tz->trips.passive.trip.valid = true;
|
||||
}
|
||||
|
||||
if (memcmp(&tz->trips.passive.devices, &devices,
|
||||
@ -317,24 +315,24 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
}
|
||||
}
|
||||
if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
|
||||
if (valid != tz->trips.passive.valid)
|
||||
if (valid != tz->trips.passive.trip.valid)
|
||||
ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");
|
||||
}
|
||||
|
||||
/* Active (optional) */
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
|
||||
valid = tz->trips.active[i].valid;
|
||||
valid = tz->trips.active[i].trip.valid;
|
||||
|
||||
if (act == -1)
|
||||
break; /* disable all active trip points */
|
||||
|
||||
if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) &&
|
||||
tz->trips.active[i].valid)) {
|
||||
tz->trips.active[i].trip.valid)) {
|
||||
status = acpi_evaluate_integer(tz->device->handle,
|
||||
name, NULL, &tmp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
tz->trips.active[i].valid = false;
|
||||
tz->trips.active[i].trip.valid = false;
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
@ -342,35 +340,36 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
break;
|
||||
|
||||
if (i == 1)
|
||||
tz->trips.active[0].temperature = celsius_to_deci_kelvin(act);
|
||||
tz->trips.active[0].trip.temperature =
|
||||
celsius_to_deci_kelvin(act);
|
||||
else
|
||||
/*
|
||||
* Don't allow override higher than
|
||||
* the next higher trip point
|
||||
*/
|
||||
tz->trips.active[i-1].temperature =
|
||||
tz->trips.active[i-1].trip.temperature =
|
||||
min_t(unsigned long,
|
||||
tz->trips.active[i-2].temperature,
|
||||
tz->trips.active[i-2].trip.temperature,
|
||||
celsius_to_deci_kelvin(act));
|
||||
|
||||
break;
|
||||
} else {
|
||||
tz->trips.active[i].temperature = tmp;
|
||||
tz->trips.active[i].valid = true;
|
||||
tz->trips.active[i].trip.temperature = tmp;
|
||||
tz->trips.active[i].trip.valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
name[2] = 'L';
|
||||
if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].valid) {
|
||||
if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].trip.valid) {
|
||||
memset(&devices, 0, sizeof(struct acpi_handle_list));
|
||||
status = acpi_evaluate_reference(tz->device->handle,
|
||||
name, NULL, &devices);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_info(tz->device->handle,
|
||||
"Invalid active%d threshold\n", i);
|
||||
tz->trips.active[i].valid = false;
|
||||
tz->trips.active[i].trip.valid = false;
|
||||
} else {
|
||||
tz->trips.active[i].valid = true;
|
||||
tz->trips.active[i].trip.valid = true;
|
||||
}
|
||||
|
||||
if (memcmp(&tz->trips.active[i].devices, &devices,
|
||||
@ -381,10 +380,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
}
|
||||
}
|
||||
if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
|
||||
if (valid != tz->trips.active[i].valid)
|
||||
if (valid != tz->trips.active[i].trip.valid)
|
||||
ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");
|
||||
|
||||
if (!tz->trips.active[i].valid)
|
||||
if (!tz->trips.active[i].trip.valid)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -398,24 +397,73 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data)
|
||||
{
|
||||
struct acpi_thermal_trip *acpi_trip = trip->priv;
|
||||
struct acpi_thermal *tz = data;
|
||||
|
||||
if (!acpi_trip)
|
||||
return 0;
|
||||
|
||||
if (acpi_trip->valid)
|
||||
trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature);
|
||||
else
|
||||
trip->temperature = THERMAL_TEMP_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_thermal_adjust_thermal_zone(struct thermal_zone_device *thermal,
|
||||
unsigned long data)
|
||||
{
|
||||
struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
|
||||
int flag = data == ACPI_THERMAL_NOTIFY_THRESHOLDS ?
|
||||
ACPI_TRIPS_THRESHOLDS : ACPI_TRIPS_DEVICES;
|
||||
|
||||
__acpi_thermal_trips_update(tz, flag);
|
||||
|
||||
for_each_thermal_trip(tz->thermal_zone, acpi_thermal_adjust_trip, tz);
|
||||
}
|
||||
|
||||
static void acpi_queue_thermal_check(struct acpi_thermal *tz)
|
||||
{
|
||||
if (!work_pending(&tz->thermal_check_work))
|
||||
queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
|
||||
}
|
||||
|
||||
static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event)
|
||||
{
|
||||
struct acpi_device *adev = tz->device;
|
||||
|
||||
/*
|
||||
* Use thermal_zone_device_exec() to carry out the trip points
|
||||
* update, so as to protect thermal_get_trend() from getting stale
|
||||
* trip point temperatures and to prevent thermal_zone_device_update()
|
||||
* invoked from acpi_thermal_check_fn() from producing inconsistent
|
||||
* results.
|
||||
*/
|
||||
thermal_zone_device_exec(tz->thermal_zone,
|
||||
acpi_thermal_adjust_thermal_zone, event);
|
||||
acpi_queue_thermal_check(tz);
|
||||
acpi_bus_generate_netlink_event(adev->pnp.device_class,
|
||||
dev_name(&adev->dev), event, 0);
|
||||
}
|
||||
|
||||
static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
|
||||
{
|
||||
int i, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
|
||||
bool valid;
|
||||
int i;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
__acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
|
||||
|
||||
valid = tz->trips.critical.valid |
|
||||
tz->trips.hot.valid |
|
||||
tz->trips.passive.valid;
|
||||
tz->trips.passive.trip.valid;
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
|
||||
valid = valid || tz->trips.active[i].valid;
|
||||
valid = valid || tz->trips.active[i].trip.valid;
|
||||
|
||||
if (!valid) {
|
||||
pr_warn(FW_BUG "No valid trip found\n");
|
||||
@ -443,159 +491,55 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int thermal_get_trip_type(struct thermal_zone_device *thermal,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
static int thermal_get_trend(struct thermal_zone_device *thermal,
|
||||
int trip_index, enum thermal_trend *trend)
|
||||
{
|
||||
struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
|
||||
int i;
|
||||
struct acpi_thermal_trip *acpi_trip;
|
||||
int t, i;
|
||||
|
||||
if (!tz || trip < 0)
|
||||
if (!tz || trip_index < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (tz->trips.critical.valid) {
|
||||
if (!trip) {
|
||||
*type = THERMAL_TRIP_CRITICAL;
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
if (tz->trips.critical.valid)
|
||||
trip_index--;
|
||||
|
||||
if (tz->trips.hot.valid) {
|
||||
if (!trip) {
|
||||
*type = THERMAL_TRIP_HOT;
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
if (tz->trips.hot.valid)
|
||||
trip_index--;
|
||||
|
||||
if (tz->trips.passive.valid) {
|
||||
if (!trip) {
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; i++) {
|
||||
if (!trip) {
|
||||
*type = THERMAL_TRIP_ACTIVE;
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
|
||||
int i;
|
||||
|
||||
if (!tz || trip < 0)
|
||||
if (trip_index < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (tz->trips.critical.valid) {
|
||||
if (!trip) {
|
||||
*temp = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->trips.critical.temperature,
|
||||
tz->kelvin_offset);
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
acpi_trip = &tz->trips.passive.trip;
|
||||
if (acpi_trip->valid && !trip_index--) {
|
||||
t = tz->trips.passive.tc1 * (tz->temperature -
|
||||
tz->last_temperature) +
|
||||
tz->trips.passive.tc2 * (tz->temperature -
|
||||
acpi_trip->temperature);
|
||||
if (t > 0)
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
else if (t < 0)
|
||||
*trend = THERMAL_TREND_DROPPING;
|
||||
else
|
||||
*trend = THERMAL_TREND_STABLE;
|
||||
|
||||
if (tz->trips.hot.valid) {
|
||||
if (!trip) {
|
||||
*temp = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->trips.hot.temperature,
|
||||
tz->kelvin_offset);
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
|
||||
if (tz->trips.passive.valid) {
|
||||
if (!trip) {
|
||||
*temp = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->trips.passive.temperature,
|
||||
tz->kelvin_offset);
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
|
||||
tz->trips.active[i].valid; i++) {
|
||||
if (!trip) {
|
||||
*temp = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->trips.active[i].temperature,
|
||||
tz->kelvin_offset);
|
||||
return 0;
|
||||
}
|
||||
trip--;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
|
||||
int *temperature)
|
||||
{
|
||||
struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
|
||||
|
||||
if (tz->trips.critical.valid) {
|
||||
*temperature = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->trips.critical.temperature,
|
||||
tz->kelvin_offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
t = acpi_thermal_temp(tz, tz->temperature);
|
||||
|
||||
static int thermal_get_trend(struct thermal_zone_device *thermal,
|
||||
int trip, enum thermal_trend *trend)
|
||||
{
|
||||
struct acpi_thermal *tz = thermal_zone_device_priv(thermal);
|
||||
enum thermal_trip_type type;
|
||||
int i;
|
||||
|
||||
if (thermal_get_trip_type(thermal, trip, &type))
|
||||
return -EINVAL;
|
||||
|
||||
if (type == THERMAL_TRIP_ACTIVE) {
|
||||
int trip_temp;
|
||||
int temp = deci_kelvin_to_millicelsius_with_offset(
|
||||
tz->temperature, tz->kelvin_offset);
|
||||
if (thermal_get_trip_temp(thermal, trip, &trip_temp))
|
||||
return -EINVAL;
|
||||
|
||||
if (temp > trip_temp) {
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
return 0;
|
||||
} else {
|
||||
/* Fall back on default trend */
|
||||
return -EINVAL;
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
acpi_trip = &tz->trips.active[i].trip;
|
||||
if (acpi_trip->valid && !trip_index--) {
|
||||
if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) {
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* tz->temperature has already been updated by generic thermal layer,
|
||||
* before this callback being invoked
|
||||
*/
|
||||
i = tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature) +
|
||||
tz->trips.passive.tc2 * (tz->temperature - tz->trips.passive.temperature);
|
||||
|
||||
if (i > 0)
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
else if (i < 0)
|
||||
*trend = THERMAL_TREND_DROPPING;
|
||||
else
|
||||
*trend = THERMAL_TREND_STABLE;
|
||||
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal)
|
||||
@ -637,7 +581,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
|
||||
if (tz->trips.hot.valid)
|
||||
trip++;
|
||||
|
||||
if (tz->trips.passive.valid) {
|
||||
if (tz->trips.passive.trip.valid) {
|
||||
trip++;
|
||||
for (i = 0; i < tz->trips.passive.devices.count; i++) {
|
||||
handle = tz->trips.passive.devices.handles[i];
|
||||
@ -662,7 +606,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
if (!tz->trips.active[i].valid)
|
||||
if (!tz->trips.active[i].trip.valid)
|
||||
break;
|
||||
|
||||
trip++;
|
||||
@ -709,9 +653,6 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
|
||||
.bind = acpi_thermal_bind_cooling_device,
|
||||
.unbind = acpi_thermal_unbind_cooling_device,
|
||||
.get_temp = thermal_get_temp,
|
||||
.get_trip_type = thermal_get_trip_type,
|
||||
.get_trip_temp = thermal_get_trip_temp,
|
||||
.get_crit_temp = thermal_get_crit_temp,
|
||||
.get_trend = thermal_get_trend,
|
||||
.hot = acpi_thermal_zone_device_hot,
|
||||
.critical = acpi_thermal_zone_device_critical,
|
||||
@ -745,63 +686,97 @@ static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz)
|
||||
|
||||
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
|
||||
{
|
||||
int trips = 0;
|
||||
struct acpi_thermal_trip *acpi_trip;
|
||||
struct thermal_trip *trip;
|
||||
int passive_delay = 0;
|
||||
int trip_count = 0;
|
||||
int result;
|
||||
acpi_status status;
|
||||
int i;
|
||||
|
||||
if (tz->trips.critical.valid)
|
||||
trips++;
|
||||
trip_count++;
|
||||
|
||||
if (tz->trips.hot.valid)
|
||||
trips++;
|
||||
trip_count++;
|
||||
|
||||
if (tz->trips.passive.valid)
|
||||
trips++;
|
||||
if (tz->trips.passive.trip.valid) {
|
||||
trip_count++;
|
||||
passive_delay = tz->trips.passive.tsp * 100;
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid;
|
||||
i++, trips++);
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].trip.valid; i++)
|
||||
trip_count++;
|
||||
|
||||
if (tz->trips.passive.valid)
|
||||
tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz,
|
||||
&acpi_thermal_zone_ops, NULL,
|
||||
tz->trips.passive.tsp * 100,
|
||||
tz->polling_frequency * 100);
|
||||
else
|
||||
tz->thermal_zone =
|
||||
thermal_zone_device_register("acpitz", trips, 0, tz,
|
||||
&acpi_thermal_zone_ops, NULL,
|
||||
0, tz->polling_frequency * 100);
|
||||
trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL);
|
||||
if (!trip)
|
||||
return -ENOMEM;
|
||||
|
||||
if (IS_ERR(tz->thermal_zone))
|
||||
return -ENODEV;
|
||||
tz->trip_table = trip;
|
||||
|
||||
if (tz->trips.critical.valid) {
|
||||
trip->type = THERMAL_TRIP_CRITICAL;
|
||||
trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature);
|
||||
trip++;
|
||||
}
|
||||
|
||||
if (tz->trips.hot.valid) {
|
||||
trip->type = THERMAL_TRIP_HOT;
|
||||
trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature);
|
||||
trip++;
|
||||
}
|
||||
|
||||
acpi_trip = &tz->trips.passive.trip;
|
||||
if (acpi_trip->valid) {
|
||||
trip->type = THERMAL_TRIP_PASSIVE;
|
||||
trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature);
|
||||
trip->priv = acpi_trip;
|
||||
trip++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
acpi_trip = &tz->trips.active[i].trip;
|
||||
|
||||
if (!acpi_trip->valid)
|
||||
break;
|
||||
|
||||
trip->type = THERMAL_TRIP_ACTIVE;
|
||||
trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature);
|
||||
trip->priv = acpi_trip;
|
||||
trip++;
|
||||
}
|
||||
|
||||
tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz",
|
||||
tz->trip_table,
|
||||
trip_count,
|
||||
0, tz,
|
||||
&acpi_thermal_zone_ops,
|
||||
NULL,
|
||||
passive_delay,
|
||||
tz->polling_frequency * 100);
|
||||
if (IS_ERR(tz->thermal_zone)) {
|
||||
result = PTR_ERR(tz->thermal_zone);
|
||||
goto free_trip_table;
|
||||
}
|
||||
|
||||
result = acpi_thermal_zone_sysfs_add(tz);
|
||||
if (result)
|
||||
goto unregister_tzd;
|
||||
|
||||
status = acpi_bus_attach_private_data(tz->device->handle,
|
||||
tz->thermal_zone);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
result = -ENODEV;
|
||||
goto remove_links;
|
||||
}
|
||||
|
||||
result = thermal_zone_device_enable(tz->thermal_zone);
|
||||
if (result)
|
||||
goto acpi_bus_detach;
|
||||
goto remove_links;
|
||||
|
||||
dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
|
||||
thermal_zone_device_id(tz->thermal_zone));
|
||||
|
||||
return 0;
|
||||
|
||||
acpi_bus_detach:
|
||||
acpi_bus_detach_private_data(tz->device->handle);
|
||||
remove_links:
|
||||
acpi_thermal_zone_sysfs_remove(tz);
|
||||
unregister_tzd:
|
||||
thermal_zone_device_unregister(tz->thermal_zone);
|
||||
free_trip_table:
|
||||
kfree(tz->trip_table);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -810,8 +785,8 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
|
||||
{
|
||||
acpi_thermal_zone_sysfs_remove(tz);
|
||||
thermal_zone_device_unregister(tz->thermal_zone);
|
||||
kfree(tz->trip_table);
|
||||
tz->thermal_zone = NULL;
|
||||
acpi_bus_detach_private_data(tz->device->handle);
|
||||
}
|
||||
|
||||
|
||||
@ -819,14 +794,9 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
static void acpi_queue_thermal_check(struct acpi_thermal *tz)
|
||||
{
|
||||
if (!work_pending(&tz->thermal_check_work))
|
||||
queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
|
||||
}
|
||||
|
||||
static void acpi_thermal_notify(struct acpi_device *device, u32 event)
|
||||
static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *device = data;
|
||||
struct acpi_thermal *tz = acpi_driver_data(device);
|
||||
|
||||
if (!tz)
|
||||
@ -837,16 +807,8 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
|
||||
acpi_queue_thermal_check(tz);
|
||||
break;
|
||||
case ACPI_THERMAL_NOTIFY_THRESHOLDS:
|
||||
acpi_thermal_trips_update(tz, ACPI_TRIPS_THRESHOLDS);
|
||||
acpi_queue_thermal_check(tz);
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event, 0);
|
||||
break;
|
||||
case ACPI_THERMAL_NOTIFY_DEVICES:
|
||||
acpi_thermal_trips_update(tz, ACPI_TRIPS_DEVICES);
|
||||
acpi_queue_thermal_check(tz);
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event, 0);
|
||||
acpi_thermal_trips_update(tz, event);
|
||||
break;
|
||||
default:
|
||||
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
|
||||
@ -997,11 +959,20 @@ static int acpi_thermal_add(struct acpi_device *device)
|
||||
|
||||
pr_info("%s [%s] (%ld C)\n", acpi_device_name(device),
|
||||
acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature));
|
||||
goto end;
|
||||
|
||||
result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_thermal_notify);
|
||||
if (result)
|
||||
goto flush_wq;
|
||||
|
||||
return 0;
|
||||
|
||||
flush_wq:
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
free_memory:
|
||||
kfree(tz);
|
||||
end:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1012,10 +983,14 @@ static void acpi_thermal_remove(struct acpi_device *device)
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return;
|
||||
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
tz = acpi_driver_data(device);
|
||||
|
||||
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_thermal_notify);
|
||||
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
|
||||
kfree(tz);
|
||||
}
|
||||
|
||||
@ -1030,7 +1005,7 @@ static int acpi_thermal_suspend(struct device *dev)
|
||||
static int acpi_thermal_resume(struct device *dev)
|
||||
{
|
||||
struct acpi_thermal *tz;
|
||||
int i, j, power_state, result;
|
||||
int i, j, power_state;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
@ -1040,18 +1015,12 @@ static int acpi_thermal_resume(struct device *dev)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
|
||||
if (!tz->trips.active[i].valid)
|
||||
if (!tz->trips.active[i].trip.valid)
|
||||
break;
|
||||
|
||||
tz->trips.active[i].enabled = true;
|
||||
for (j = 0; j < tz->trips.active[i].devices.count; j++) {
|
||||
result = acpi_bus_update_power(
|
||||
tz->trips.active[i].devices.handles[j],
|
||||
&power_state);
|
||||
if (result || (power_state != ACPI_STATE_D0)) {
|
||||
tz->trips.active[i].enabled = false;
|
||||
break;
|
||||
}
|
||||
acpi_bus_update_power(tz->trips.active[i].devices.handles[j],
|
||||
&power_state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1078,7 +1047,6 @@ static struct acpi_driver acpi_thermal_driver = {
|
||||
.ops = {
|
||||
.add = acpi_thermal_add,
|
||||
.remove = acpi_thermal_remove,
|
||||
.notify = acpi_thermal_notify,
|
||||
},
|
||||
.drv.pm = &acpi_thermal_pm,
|
||||
};
|
||||
@ -1094,7 +1062,7 @@ static int thermal_act(const struct dmi_system_id *d) {
|
||||
static int thermal_nocrt(const struct dmi_system_id *d) {
|
||||
pr_notice("%s detected: disabling all critical thermal trip point actions.\n",
|
||||
d->ident);
|
||||
nocrt = 1;
|
||||
crt = -1;
|
||||
return 0;
|
||||
}
|
||||
static int thermal_tzp(const struct dmi_system_id *d) {
|
||||
|
@ -445,6 +445,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Lenovo Ideapad Z470 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
|
||||
.callback = video_detect_force_native,
|
||||
@ -486,6 +495,24 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "iMac11,3"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://gitlab.freedesktop.org/drm/amd/-/issues/1838 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Apple iMac12,1 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://gitlab.freedesktop.org/drm/amd/-/issues/2753 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Apple iMac12,2 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "iMac12,2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
|
||||
.callback = video_detect_force_native,
|
||||
|
@ -94,6 +94,11 @@ static struct lpi_constraints *lpi_constraints_table;
|
||||
static int lpi_constraints_table_size;
|
||||
static int rev_id;
|
||||
|
||||
#define for_each_lpi_constraint(entry) \
|
||||
for (int i = 0; \
|
||||
entry = &lpi_constraints_table[i], i < lpi_constraints_table_size; \
|
||||
i++)
|
||||
|
||||
static void lpi_device_get_constraints_amd(void)
|
||||
{
|
||||
union acpi_object *out_obj;
|
||||
@ -113,6 +118,12 @@ static void lpi_device_get_constraints_amd(void)
|
||||
union acpi_object *package = &out_obj->package.elements[i];
|
||||
|
||||
if (package->type == ACPI_TYPE_PACKAGE) {
|
||||
if (lpi_constraints_table) {
|
||||
acpi_handle_err(lps0_device_handle,
|
||||
"Duplicate constraints list\n");
|
||||
goto free_acpi_buffer;
|
||||
}
|
||||
|
||||
lpi_constraints_table = kcalloc(package->package.count,
|
||||
sizeof(*lpi_constraints_table),
|
||||
GFP_KERNEL);
|
||||
@ -123,17 +134,16 @@ static void lpi_device_get_constraints_amd(void)
|
||||
acpi_handle_debug(lps0_device_handle,
|
||||
"LPI: constraints list begin:\n");
|
||||
|
||||
for (j = 0; j < package->package.count; ++j) {
|
||||
for (j = 0; j < package->package.count; j++) {
|
||||
union acpi_object *info_obj = &package->package.elements[j];
|
||||
struct lpi_device_constraint_amd dev_info = {};
|
||||
struct lpi_constraints *list;
|
||||
acpi_status status;
|
||||
|
||||
for (k = 0; k < info_obj->package.count; ++k) {
|
||||
union acpi_object *obj = &info_obj->package.elements[k];
|
||||
list = &lpi_constraints_table[lpi_constraints_table_size];
|
||||
|
||||
list = &lpi_constraints_table[lpi_constraints_table_size];
|
||||
list->min_dstate = -1;
|
||||
for (k = 0; k < info_obj->package.count; k++) {
|
||||
union acpi_object *obj = &info_obj->package.elements[k];
|
||||
|
||||
switch (k) {
|
||||
case 0:
|
||||
@ -149,27 +159,25 @@ static void lpi_device_get_constraints_amd(void)
|
||||
dev_info.min_dstate = obj->integer.value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dev_info.enabled || !dev_info.name ||
|
||||
!dev_info.min_dstate)
|
||||
continue;
|
||||
|
||||
status = acpi_get_handle(NULL, dev_info.name,
|
||||
&list->handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
|
||||
acpi_handle_debug(lps0_device_handle,
|
||||
"Name:%s\n", dev_info.name);
|
||||
|
||||
list->min_dstate = dev_info.min_dstate;
|
||||
|
||||
if (list->min_dstate < 0) {
|
||||
acpi_handle_debug(lps0_device_handle,
|
||||
"Incomplete constraint defined\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
acpi_handle_debug(lps0_device_handle,
|
||||
"Name:%s, Enabled: %d, States: %d, MinDstate: %d\n",
|
||||
dev_info.name,
|
||||
dev_info.enabled,
|
||||
dev_info.function_states,
|
||||
dev_info.min_dstate);
|
||||
|
||||
if (!dev_info.enabled || !dev_info.name ||
|
||||
!dev_info.min_dstate)
|
||||
continue;
|
||||
|
||||
status = acpi_get_handle(NULL, dev_info.name, &list->handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
|
||||
list->min_dstate = dev_info.min_dstate;
|
||||
|
||||
lpi_constraints_table_size++;
|
||||
}
|
||||
}
|
||||
@ -214,7 +222,7 @@ static void lpi_device_get_constraints(void)
|
||||
if (!package)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < package->package.count; ++j) {
|
||||
for (j = 0; j < package->package.count; j++) {
|
||||
union acpi_object *element =
|
||||
&(package->package.elements[j]);
|
||||
|
||||
@ -246,7 +254,7 @@ static void lpi_device_get_constraints(void)
|
||||
|
||||
constraint->min_dstate = -1;
|
||||
|
||||
for (j = 0; j < package_count; ++j) {
|
||||
for (j = 0; j < package_count; j++) {
|
||||
union acpi_object *info_obj = &info.package[j];
|
||||
union acpi_object *cnstr_pkg;
|
||||
union acpi_object *obj;
|
||||
@ -291,32 +299,55 @@ free_acpi_buffer:
|
||||
ACPI_FREE(out_obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_get_lps0_constraint - Get the LPS0 constraint for a device.
|
||||
* @adev: Device to get the constraint for.
|
||||
*
|
||||
* The LPS0 constraint is the shallowest (minimum) power state in which the
|
||||
* device can be so as to allow the platform as a whole to achieve additional
|
||||
* energy conservation by utilizing a system-wide low-power state.
|
||||
*
|
||||
* Returns:
|
||||
* - ACPI power state value of the constraint for @adev on success.
|
||||
* - Otherwise, ACPI_STATE_UNKNOWN.
|
||||
*/
|
||||
int acpi_get_lps0_constraint(struct acpi_device *adev)
|
||||
{
|
||||
struct lpi_constraints *entry;
|
||||
|
||||
for_each_lpi_constraint(entry) {
|
||||
if (adev->handle == entry->handle)
|
||||
return entry->min_dstate;
|
||||
}
|
||||
|
||||
return ACPI_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void lpi_check_constraints(void)
|
||||
{
|
||||
int i;
|
||||
struct lpi_constraints *entry;
|
||||
|
||||
for (i = 0; i < lpi_constraints_table_size; ++i) {
|
||||
acpi_handle handle = lpi_constraints_table[i].handle;
|
||||
struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
|
||||
for_each_lpi_constraint(entry) {
|
||||
struct acpi_device *adev = acpi_fetch_acpi_dev(entry->handle);
|
||||
|
||||
if (!adev)
|
||||
continue;
|
||||
|
||||
acpi_handle_debug(handle,
|
||||
acpi_handle_debug(entry->handle,
|
||||
"LPI: required min power state:%s current power state:%s\n",
|
||||
acpi_power_state_string(lpi_constraints_table[i].min_dstate),
|
||||
acpi_power_state_string(entry->min_dstate),
|
||||
acpi_power_state_string(adev->power.state));
|
||||
|
||||
if (!adev->flags.power_manageable) {
|
||||
acpi_handle_info(handle, "LPI: Device not power manageable\n");
|
||||
lpi_constraints_table[i].handle = NULL;
|
||||
acpi_handle_info(entry->handle, "LPI: Device not power manageable\n");
|
||||
entry->handle = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (adev->power.state < lpi_constraints_table[i].min_dstate)
|
||||
acpi_handle_info(handle,
|
||||
if (adev->power.state < entry->min_dstate)
|
||||
acpi_handle_info(entry->handle,
|
||||
"LPI: Constraint not met; min power state:%s current power state:%s\n",
|
||||
acpi_power_state_string(lpi_constraints_table[i].min_dstate),
|
||||
acpi_power_state_string(entry->min_dstate),
|
||||
acpi_power_state_string(adev->power.state));
|
||||
}
|
||||
}
|
||||
|
@ -518,3 +518,38 @@ bool acpi_quirk_skip_acpi_ac_and_battery(void)
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_quirk_skip_acpi_ac_and_battery);
|
||||
|
||||
/* This section provides a workaround for a specific x86 system
|
||||
* which requires disabling of mwait to work correctly.
|
||||
*/
|
||||
static int __init acpi_proc_quirk_set_no_mwait(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_notice("%s detected - disabling mwait for CPU C-states\n",
|
||||
id->ident);
|
||||
boot_option_idle_override = IDLE_NOMWAIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id acpi_proc_quirk_mwait_dmi_table[] __initconst = {
|
||||
{
|
||||
.callback = acpi_proc_quirk_set_no_mwait,
|
||||
.ident = "Extensa 5220",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Columbia"),
|
||||
},
|
||||
.driver_data = NULL,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
void __init acpi_proc_quirk_mwait_check(void)
|
||||
{
|
||||
/*
|
||||
* Check whether the system is DMI table. If yes, OSPM
|
||||
* should not use mwait for CPU-states.
|
||||
*/
|
||||
dmi_check_system(acpi_proc_quirk_mwait_dmi_table);
|
||||
}
|
||||
|
@ -254,6 +254,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
||||
else
|
||||
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
|
||||
|
||||
/* Handle possible string truncation */
|
||||
dev->name[sizeof(dev->name) - 1] = '\0';
|
||||
|
||||
if (dev->active)
|
||||
pnpacpi_parse_allocated_resource(dev);
|
||||
|
||||
|
@ -348,7 +348,8 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id)
|
||||
struct thermal_trip trip;
|
||||
|
||||
/* Ignore disabled trip points */
|
||||
if (test_bit(trip_id, &tz->trips_disabled))
|
||||
if (test_bit(trip_id, &tz->trips_disabled) ||
|
||||
trip.temperature == THERMAL_TEMP_INVALID)
|
||||
return;
|
||||
|
||||
__thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
@ -496,6 +497,25 @@ void thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_update);
|
||||
|
||||
/**
|
||||
* thermal_zone_device_exec - Run a callback under the zone lock.
|
||||
* @tz: Thermal zone.
|
||||
* @cb: Callback to run.
|
||||
* @data: Data to pass to the callback.
|
||||
*/
|
||||
void thermal_zone_device_exec(struct thermal_zone_device *tz,
|
||||
void (*cb)(struct thermal_zone_device *,
|
||||
unsigned long),
|
||||
unsigned long data)
|
||||
{
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
cb(tz, data);
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device_exec);
|
||||
|
||||
static void thermal_zone_device_check(struct work_struct *work)
|
||||
{
|
||||
struct thermal_zone_device *tz = container_of(work, struct
|
||||
|
@ -54,10 +54,6 @@ int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
|
||||
int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
|
||||
void *thermal_governor);
|
||||
|
||||
int __for_each_thermal_trip(struct thermal_zone_device *,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *);
|
||||
|
||||
struct thermal_zone_device *thermal_zone_get_by_id(int id);
|
||||
|
||||
struct thermal_attr {
|
||||
|
@ -9,28 +9,26 @@
|
||||
*/
|
||||
#include "thermal_core.h"
|
||||
|
||||
int __for_each_thermal_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data)
|
||||
int for_each_thermal_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data)
|
||||
{
|
||||
int i, ret;
|
||||
struct thermal_trip trip;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
|
||||
if (!tz->trips)
|
||||
return -ENODATA;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cb(&trip, data);
|
||||
ret = cb(&tz->trips[i], data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(for_each_thermal_trip);
|
||||
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz)
|
||||
{
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define METHOD_NAME__DDN "_DDN"
|
||||
#define METHOD_NAME__DIS "_DIS"
|
||||
#define METHOD_NAME__DMA "_DMA"
|
||||
#define METHOD_NAME__EVT "_EVT"
|
||||
#define METHOD_NAME__HID "_HID"
|
||||
#define METHOD_NAME__INI "_INI"
|
||||
#define METHOD_NAME__PLD "_PLD"
|
||||
|
@ -515,6 +515,12 @@ void acpi_bus_private_data_handler(acpi_handle, void *);
|
||||
int acpi_bus_get_private_data(acpi_handle, void **);
|
||||
int acpi_bus_attach_private_data(acpi_handle, void *);
|
||||
void acpi_bus_detach_private_data(acpi_handle);
|
||||
int acpi_dev_install_notify_handler(struct acpi_device *adev,
|
||||
u32 handler_type,
|
||||
acpi_notify_handler handler);
|
||||
void acpi_dev_remove_notify_handler(struct acpi_device *adev,
|
||||
u32 handler_type,
|
||||
acpi_notify_handler handler);
|
||||
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
|
||||
extern int register_acpi_notifier(struct notifier_block *);
|
||||
extern int unregister_acpi_notifier(struct notifier_block *);
|
||||
@ -563,8 +569,6 @@ int acpi_match_device_ids(struct acpi_device *device,
|
||||
const struct acpi_device_id *ids);
|
||||
void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
|
||||
char *modalias, size_t len);
|
||||
int acpi_create_dir(struct acpi_device *);
|
||||
void acpi_remove_dir(struct acpi_device *);
|
||||
|
||||
static inline bool acpi_device_enumerated(struct acpi_device *adev)
|
||||
{
|
||||
@ -645,6 +649,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev);
|
||||
#ifdef CONFIG_X86
|
||||
bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status);
|
||||
bool acpi_quirk_skip_acpi_ac_and_battery(void);
|
||||
int acpi_install_cmos_rtc_space_handler(acpi_handle handle);
|
||||
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle);
|
||||
#else
|
||||
static inline bool acpi_device_override_status(struct acpi_device *adev,
|
||||
unsigned long long *status)
|
||||
@ -655,6 +661,13 @@ static inline bool acpi_quirk_skip_acpi_ac_and_battery(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20230331
|
||||
#define ACPI_CA_VERSION 0x20230628
|
||||
|
||||
#include <acpi/acconfig.h>
|
||||
#include <acpi/actypes.h>
|
||||
@ -970,8 +970,6 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
void **data,
|
||||
void (*callback)(void *)))
|
||||
|
||||
void acpi_run_debugger(char *batch_buffer);
|
||||
|
||||
void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
|
||||
|
||||
#endif /* __ACXFACE_H__ */
|
||||
|
@ -402,7 +402,7 @@ struct acpi_cdat_dsmas {
|
||||
|
||||
/* Flags for subtable above */
|
||||
|
||||
#define ACPI_CEDT_DSMAS_NON_VOLATILE (1 << 2)
|
||||
#define ACPI_CDAT_DSMAS_NON_VOLATILE (1 << 2)
|
||||
|
||||
/* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
|
||||
|
||||
|
@ -893,7 +893,10 @@ enum acpi_madt_type {
|
||||
ACPI_MADT_TYPE_BIO_PIC = 22,
|
||||
ACPI_MADT_TYPE_LPC_PIC = 23,
|
||||
ACPI_MADT_TYPE_RINTC = 24,
|
||||
ACPI_MADT_TYPE_RESERVED = 25, /* 25 to 0x7F are reserved */
|
||||
ACPI_MADT_TYPE_IMSIC = 25,
|
||||
ACPI_MADT_TYPE_APLIC = 26,
|
||||
ACPI_MADT_TYPE_PLIC = 27,
|
||||
ACPI_MADT_TYPE_RESERVED = 28, /* 28 to 0x7F are reserved */
|
||||
ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */
|
||||
};
|
||||
|
||||
@ -1261,6 +1264,9 @@ struct acpi_madt_rintc {
|
||||
u32 flags;
|
||||
u64 hart_id;
|
||||
u32 uid; /* ACPI processor UID */
|
||||
u32 ext_intc_id; /* External INTC Id */
|
||||
u64 imsic_addr; /* IMSIC base address */
|
||||
u32 imsic_size; /* IMSIC size */
|
||||
};
|
||||
|
||||
/* Values for RISC-V INTC Version field above */
|
||||
@ -1271,6 +1277,48 @@ enum acpi_madt_rintc_version {
|
||||
ACPI_MADT_RINTC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
/* 25: RISC-V IMSIC */
|
||||
struct acpi_madt_imsic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u8 reserved;
|
||||
u32 flags;
|
||||
u16 num_ids;
|
||||
u16 num_guest_ids;
|
||||
u8 guest_index_bits;
|
||||
u8 hart_index_bits;
|
||||
u8 group_index_bits;
|
||||
u8 group_index_shift;
|
||||
};
|
||||
|
||||
/* 26: RISC-V APLIC */
|
||||
struct acpi_madt_aplic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u8 id;
|
||||
u32 flags;
|
||||
u8 hw_id[8];
|
||||
u16 num_idcs;
|
||||
u16 num_sources;
|
||||
u32 gsi_base;
|
||||
u64 base_addr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
/* 27: RISC-V PLIC */
|
||||
struct acpi_madt_plic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u8 id;
|
||||
u8 hw_id[8];
|
||||
u16 num_irqs;
|
||||
u16 max_prio;
|
||||
u32 flags;
|
||||
u32 size;
|
||||
u64 base_addr;
|
||||
u32 gsi_base;
|
||||
};
|
||||
|
||||
/* 80: OEM data */
|
||||
|
||||
struct acpi_madt_oem_data {
|
||||
@ -2730,12 +2778,15 @@ enum acpi_rgrt_image_type {
|
||||
|
||||
struct acpi_table_rhct {
|
||||
struct acpi_table_header header; /* Common ACPI table header */
|
||||
u32 reserved;
|
||||
u32 flags; /* RHCT flags */
|
||||
u64 time_base_freq;
|
||||
u32 node_count;
|
||||
u32 node_offset;
|
||||
};
|
||||
|
||||
/* RHCT Flags */
|
||||
|
||||
#define ACPI_RHCT_TIMER_CANNOT_WAKEUP_CPU (1)
|
||||
/*
|
||||
* RHCT subtables
|
||||
*/
|
||||
@ -2749,6 +2800,9 @@ struct acpi_rhct_node_header {
|
||||
|
||||
enum acpi_rhct_node_type {
|
||||
ACPI_RHCT_NODE_TYPE_ISA_STRING = 0x0000,
|
||||
ACPI_RHCT_NODE_TYPE_CMO = 0x0001,
|
||||
ACPI_RHCT_NODE_TYPE_MMU = 0x0002,
|
||||
ACPI_RHCT_NODE_TYPE_RESERVED = 0x0003,
|
||||
ACPI_RHCT_NODE_TYPE_HART_INFO = 0xFFFF,
|
||||
};
|
||||
|
||||
@ -2762,6 +2816,24 @@ struct acpi_rhct_isa_string {
|
||||
char isa[];
|
||||
};
|
||||
|
||||
struct acpi_rhct_cmo_node {
|
||||
u8 reserved; /* Must be zero */
|
||||
u8 cbom_size; /* CBOM size in powerof 2 */
|
||||
u8 cbop_size; /* CBOP size in powerof 2 */
|
||||
u8 cboz_size; /* CBOZ size in powerof 2 */
|
||||
};
|
||||
|
||||
struct acpi_rhct_mmu_node {
|
||||
u8 reserved; /* Must be zero */
|
||||
u8 mmu_type; /* Virtual Address Scheme */
|
||||
};
|
||||
|
||||
enum acpi_rhct_mmu_type {
|
||||
ACPI_RHCT_MMU_TYPE_SV39 = 0,
|
||||
ACPI_RHCT_MMU_TYPE_SV48 = 1,
|
||||
ACPI_RHCT_MMU_TYPE_SV57 = 2
|
||||
};
|
||||
|
||||
/* Hart Info node structure */
|
||||
struct acpi_rhct_hart_info {
|
||||
u16 num_offsets;
|
||||
|
@ -279,12 +279,14 @@ struct acpi_srat_gic_its_affinity {
|
||||
* 6: ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY
|
||||
*/
|
||||
|
||||
#define ACPI_SRAT_DEVICE_HANDLE_SIZE 16
|
||||
|
||||
struct acpi_srat_generic_affinity {
|
||||
struct acpi_subtable_header header;
|
||||
u8 reserved;
|
||||
u8 device_handle_type;
|
||||
u32 proximity_domain;
|
||||
u8 device_handle[16];
|
||||
u8 device_handle[ACPI_SRAT_DEVICE_HANDLE_SIZE];
|
||||
u32 flags;
|
||||
u32 reserved1;
|
||||
};
|
||||
|
@ -1,36 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
/* _PDC bit definition for Intel processors */
|
||||
|
||||
#ifndef __PDC_INTEL_H__
|
||||
#define __PDC_INTEL_H__
|
||||
|
||||
#define ACPI_PDC_P_FFH (0x0001)
|
||||
#define ACPI_PDC_C_C1_HALT (0x0002)
|
||||
#define ACPI_PDC_T_FFH (0x0004)
|
||||
#define ACPI_PDC_SMP_C1PT (0x0008)
|
||||
#define ACPI_PDC_SMP_C2C3 (0x0010)
|
||||
#define ACPI_PDC_SMP_P_SWCOORD (0x0020)
|
||||
#define ACPI_PDC_SMP_C_SWCOORD (0x0040)
|
||||
#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
|
||||
#define ACPI_PDC_C_C1_FFH (0x0100)
|
||||
#define ACPI_PDC_C_C2C3_FFH (0x0200)
|
||||
#define ACPI_PDC_SMP_P_HWCOORD (0x0800)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_P_FFH)
|
||||
|
||||
#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_SMP_P_SWCOORD | \
|
||||
ACPI_PDC_SMP_P_HWCOORD | \
|
||||
ACPI_PDC_P_FFH)
|
||||
|
||||
#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
|
||||
ACPI_PDC_SMP_C1PT | \
|
||||
ACPI_PDC_C_C1_HALT | \
|
||||
ACPI_PDC_C_C1_FFH | \
|
||||
ACPI_PDC_C_C2C3_FFH)
|
||||
|
||||
#endif /* __PDC_INTEL_H__ */
|
@ -182,6 +182,7 @@
|
||||
#ifdef ACPI_USE_STANDARD_HEADERS
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ACPI_OFFSET(d, f) offsetof(d, f)
|
||||
#endif
|
||||
|
@ -10,9 +10,6 @@
|
||||
#ifndef __ACZEPHYR_H__
|
||||
#define __ACZEPHYR_H__
|
||||
|
||||
#define SEEK_SET FS_SEEK_SET
|
||||
#define SEEK_END FS_SEEK_END
|
||||
|
||||
#define ACPI_MACHINE_WIDTH 64
|
||||
|
||||
#define ACPI_NO_ERROR_MESSAGES
|
||||
|
40
include/acpi/proc_cap_intel.h
Normal file
40
include/acpi/proc_cap_intel.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
/* Vendor specific processor capabilities bit definition
|
||||
* for Intel processors. Those bits are used to convey OSPM
|
||||
* power management capabilities to the platform.
|
||||
*/
|
||||
|
||||
#ifndef __PROC_CAP_INTEL_H__
|
||||
#define __PROC_CAP_INTEL_H__
|
||||
|
||||
#define ACPI_PROC_CAP_P_FFH (0x0001)
|
||||
#define ACPI_PROC_CAP_C_C1_HALT (0x0002)
|
||||
#define ACPI_PROC_CAP_T_FFH (0x0004)
|
||||
#define ACPI_PROC_CAP_SMP_C1PT (0x0008)
|
||||
#define ACPI_PROC_CAP_SMP_C2C3 (0x0010)
|
||||
#define ACPI_PROC_CAP_SMP_P_SWCOORD (0x0020)
|
||||
#define ACPI_PROC_CAP_SMP_C_SWCOORD (0x0040)
|
||||
#define ACPI_PROC_CAP_SMP_T_SWCOORD (0x0080)
|
||||
#define ACPI_PROC_CAP_C_C1_FFH (0x0100)
|
||||
#define ACPI_PROC_CAP_C_C2C3_FFH (0x0200)
|
||||
#define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800)
|
||||
#define ACPI_PROC_CAP_COLLAB_PROC_PERF (0x1000)
|
||||
|
||||
#define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \
|
||||
ACPI_PROC_CAP_C_C1_HALT | \
|
||||
ACPI_PROC_CAP_P_FFH)
|
||||
|
||||
#define ACPI_PROC_CAP_EST_CAPABILITY_SWSMP (ACPI_PROC_CAP_SMP_C1PT | \
|
||||
ACPI_PROC_CAP_C_C1_HALT | \
|
||||
ACPI_PROC_CAP_SMP_P_SWCOORD | \
|
||||
ACPI_PROC_CAP_SMP_P_HWCOORD | \
|
||||
ACPI_PROC_CAP_P_FFH)
|
||||
|
||||
#define ACPI_PROC_CAP_C_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C2C3 | \
|
||||
ACPI_PROC_CAP_SMP_C1PT | \
|
||||
ACPI_PROC_CAP_C_C1_HALT | \
|
||||
ACPI_PROC_CAP_C_C1_FFH | \
|
||||
ACPI_PROC_CAP_C_C2C3_FFH)
|
||||
|
||||
#endif /* __PROC_CAP_INTEL_H__ */
|
@ -477,8 +477,6 @@ static inline int acpi_get_node(acpi_handle handle)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
extern int acpi_paddr_to_node(u64 start_addr, u64 size);
|
||||
|
||||
extern int pnpacpi_disabled;
|
||||
|
||||
#define PXM_INVAL (-1)
|
||||
@ -1100,7 +1098,7 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
|
||||
|
||||
acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state,
|
||||
u32 val_a, u32 val_b);
|
||||
#ifdef CONFIG_X86
|
||||
#if defined(CONFIG_SUSPEND) && defined(CONFIG_X86)
|
||||
struct acpi_s2idle_dev_ops {
|
||||
struct list_head list_node;
|
||||
void (*prepare)(void);
|
||||
@ -1109,7 +1107,13 @@ struct acpi_s2idle_dev_ops {
|
||||
};
|
||||
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg);
|
||||
void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg);
|
||||
#endif /* CONFIG_X86 */
|
||||
int acpi_get_lps0_constraint(struct acpi_device *adev);
|
||||
#else /* CONFIG_SUSPEND && CONFIG_X86 */
|
||||
static inline int acpi_get_lps0_constraint(struct device *dev)
|
||||
{
|
||||
return ACPI_STATE_UNKNOWN;
|
||||
}
|
||||
#endif /* CONFIG_SUSPEND && CONFIG_X86 */
|
||||
#ifndef CONFIG_IA64
|
||||
void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
|
||||
#else
|
||||
|
@ -81,11 +81,13 @@ struct thermal_zone_device_ops {
|
||||
* @temperature: temperature value in miliCelsius
|
||||
* @hysteresis: relative hysteresis in miliCelsius
|
||||
* @type: trip point type
|
||||
* @priv: pointer to driver data associated with this trip
|
||||
*/
|
||||
struct thermal_trip {
|
||||
int temperature;
|
||||
int hysteresis;
|
||||
enum thermal_trip_type type;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct thermal_cooling_device_ops {
|
||||
@ -287,6 +289,9 @@ int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
const struct thermal_trip *trip);
|
||||
|
||||
int for_each_thermal_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data);
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz);
|
||||
|
||||
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp);
|
||||
@ -323,6 +328,10 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
|
||||
struct thermal_cooling_device *);
|
||||
void thermal_zone_device_update(struct thermal_zone_device *,
|
||||
enum thermal_notify_event);
|
||||
void thermal_zone_device_exec(struct thermal_zone_device *tz,
|
||||
void (*cb)(struct thermal_zone_device *,
|
||||
unsigned long),
|
||||
unsigned long data);
|
||||
|
||||
struct thermal_cooling_device *thermal_cooling_device_register(const char *,
|
||||
void *, const struct thermal_cooling_device_ops *);
|
||||
|
Loading…
Reference in New Issue
Block a user