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:
Linus Torvalds 2023-08-28 17:58:39 -07:00
commit 330235e874
53 changed files with 971 additions and 584 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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__ */

View file

@ -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 */

View file

@ -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;

View file

@ -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,

View file

@ -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)
/*******************************************************************************
*

View file

@ -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]);

View file

@ -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);
}

View file

@ -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 */

View file

@ -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 */

View file

@ -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 = &current_sp;
#pragma GCC diagnostic pop
}
/*******************************************************************************

View file

@ -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

View file

@ -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 */

View file

@ -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();
}

View file

@ -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);

View file

@ -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,
};

View file

@ -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

View file

@ -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);

View file

@ -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
/* --------------------------------------------------------------------------

View file

@ -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,
},
};

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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) {

View file

@ -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,

View file

@ -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 @@ static void lpi_device_get_constraints(void)
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));
}
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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 {

View file

@ -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)
{

View file

@ -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"

View file

@ -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)

View file

@ -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__ */

View file

@ -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) */

View file

@ -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;

View file

@ -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;
};

View file

@ -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__ */

View file

@ -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

View file

@ -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

View 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__ */

View file

@ -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

View file

@ -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 *);