ACPI updates for 6.2-rc1

- Update the ACPICA code in the kernel to the 20221020 upstream
    version and fix a couple of issues in it:
 
    * Make acpi_ex_load_op() match upstream implementation (Rafael
      Wysocki).
    * Add support for loong_arch-specific APICs in MADT (Huacai Chen).
    * Add support for fixed PCIe wake event (Huacai Chen).
    * Add EBDA pointer sanity checks (Vit Kabele).
    * Avoid accessing VGA memory when EBDA < 1KiB (Vit Kabele).
    * Add CCEL table support to both compiler/disassembler (Kuppuswamy
      Sathyanarayanan).
    * Add a couple of new UUIDs to the known UUID list (Bob Moore).
    * Add support for FFH Opregion special context data (Sudeep Holla).
    * Improve warning message for "invalid ACPI name" (Bob Moore).
    * Add support for CXL 3.0 structures (CXIMS & RDPAS) in the CEDT
      table (Alison Schofield).
    * Prepare IORT support for revision E.e (Robin Murphy).
    * Finish support for the CDAT table (Bob Moore).
    * Fix error code path in acpi_ds_call_control_method() (Rafael
      Wysocki).
    * Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() (Li
      Zetao).
    * Update the version of the ACPICA code in the kernel (Bob Moore).
 
  - Use ZERO_PAGE(0) instead of empty_zero_page in the ACPI device
    enumeration code (Giulio Benetti).
 
  - Change the return type of the ACPI driver remove callback to void and
    update its users accordingly (Dawei Li).
 
  - Add general support for FFH address space type and implement the low-
    level part of it for ARM64 (Sudeep Holla).
 
  - Fix stale comments in the ACPI tables parsing code and make it print
    more messages related to MADT (Hanjun Guo, Huacai Chen).
 
  - Replace invocations of generic library functions with more kernel-
    specific counterparts in the ACPI sysfs interface (Christophe JAILLET,
    Xu Panda).
 
  - Print full name paths of ACPI power resource objects during
    enumeration (Kane Chen).
 
  - Eliminate a compiler warning regarding a missing function prototype
    in the ACPI power management code (Sudeep Holla).
 
  - Fix and clean up the ACPI processor driver (Rafael Wysocki, Li Zhong,
    Colin Ian King, Sudeep Holla).
 
  - Add quirk for the HP Pavilion Gaming 15-cx0041ur to the ACPI EC
    driver (Mia Kanashi).
 
  - Add some mew ACPI backlight handling quirks and update some existing
    ones (Hans de Goede).
 
  - Make the ACPI backlight driver prefer the native backlight control
    over vendor backlight control when possible (Hans de Goede).
 
  - Drop unsetting ACPI APEI driver data on remove (Uwe Kleine-König).
 
  - Use xchg_release() instead of cmpxchg() for updating new GHES cache
    slots (Ard Biesheuvel).
 
  - Clean up the ACPI APEI code (Sudeep Holla, Christophe JAILLET, Jay Lu).
 
  - Add new I2C device enumeration quirks for Medion Lifetab S10346 and
    Lenovo Yoga Tab 3 Pro (YT3-X90F) (Hans de Goede).
 
  - Make the ACPI battery driver notify user space about adding new
    battery hooks and removing the existing ones (Armin Wolf).
 
  - Modify the pfr_update and pfr_telemetry drivers to use ACPI_FREE()
    for freeing acpi_object structures to help diagnostics (Wang ShaoBo).
 
  - Make the ACPI fan driver use sysfs_emit_at() in its sysfs interface
    code (ye xingchen).
 
  - Fix the _FIF package extraction failure handling in the ACPI fan
    driver (Hanjun Guo).
 
  - Fix the PCC mailbox handling error code path (Huisong Li).
 
  - Avoid using PCC Opregions if there is no platform interrupt allocated
    for this purpose (Huisong Li).
 
  - Use sysfs_emit() instead of scnprintf() in the ACPI PAD driver and
    CPPC library (ye xingchen).
 
  - Fix some kernel-doc issues in the ACPI GSI processing code (Xiongfeng
    Wang).
 
  - Fix name memory leak in pnp_alloc_dev() (Yang Yingliang).
 
  - Do not disable PNP devices on suspend when they cannot be re-enabled
    on resume (Hans de Goede).
 
  - Clean up the ACPI thermal driver a bit (Rafael Wysocki).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmOXV10SHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxuOwP/2zew6val2Jf7I/Yxf1iQLlRyGmhFnaH
 wpltJvBjlHjAUKnPQ/kLYK9fjuUY5HVgjOE03WpwhFUpmhftYTrSkhoVkJ1Mw9Zl
 RNOAEgCG484ThHiTIVp/dMPxrtfuqpdbamhWX3Q51IfXjGW8Vc/lDxIa3k/JQxyq
 ko8GFPCoebJrSCfuwaAf2+xSQaf6dq4jpL/rlIk+nYMMB9mQmXhNEhc+l97NaCe8
 MyCIGynyNbhGsIlwdHRvTp04EIe8h0Z1+Dyns7g/TrzHj3Aezy7QVZbn8sKdZWa1
 W/Ck9QST5tfpDWyr+hUXxUJjEn4Yy+GXjM2xON0EMx5q+JD9XsOpwWOVwTR7CS5s
 FwEd6I89SC8OZM86AgMtnGxygjpK24R/kGzHjhG15IQCsypc8Rvzoxl0L0YVoon/
 UTkE57GzNWVzu0pY/oXJc2aT7lVqFXMFZ6ft/zHnBRnQmrcIi+xgDO5ni5KxctFN
 TVFwbAMCuwVx6IOcVQCZM2g4aJw426KpUn19fKnXvPwR5UIufBaCzSKWMiYrtdXr
 O5BM8ElYuyKCWGYEE0GSMjZygyDpyY6ENLH7s7P1IEmFyigBzaaGBbKm108JJq4V
 eCWJYTAx8pAptsU/vfuMvEQ1ErfhZ3TTokA5Lv0uPf53VcAnWDb7EAbW6ZGMwFSI
 IaV6cv6ILoqO
 =GVzp
 -----END PGP SIGNATURE-----

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

Pull ACPI and PNP updates from Rafael Wysocki:
 "These include new code (for instance, support for the FFH address
  space type and support for new firmware data structures in ACPICA),
  some new quirks (mostly related to backlight handling and I2C
  enumeration), a number of fixes and a fair amount of cleanups all
  over.

  Specifics:

   - Update the ACPICA code in the kernel to the 20221020 upstream
     version and fix a couple of issues in it:
      - Make acpi_ex_load_op() match upstream implementation (Rafael
        Wysocki)
      - Add support for loong_arch-specific APICs in MADT (Huacai Chen)
      - Add support for fixed PCIe wake event (Huacai Chen)
      - Add EBDA pointer sanity checks (Vit Kabele)
      - Avoid accessing VGA memory when EBDA < 1KiB (Vit Kabele)
      - Add CCEL table support to both compiler/disassembler (Kuppuswamy
        Sathyanarayanan)
      - Add a couple of new UUIDs to the known UUID list (Bob Moore)
      - Add support for FFH Opregion special context data (Sudeep
        Holla)
      - Improve warning message for "invalid ACPI name" (Bob Moore)
      - Add support for CXL 3.0 structures (CXIMS & RDPAS) in the CEDT
        table (Alison Schofield)
      - Prepare IORT support for revision E.e (Robin Murphy)
      - Finish support for the CDAT table (Bob Moore)
      - Fix error code path in acpi_ds_call_control_method() (Rafael
        Wysocki)
      - Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() (Li
        Zetao)
      - Update the version of the ACPICA code in the kernel (Bob Moore)

   - Use ZERO_PAGE(0) instead of empty_zero_page in the ACPI device
     enumeration code (Giulio Benetti)

   - Change the return type of the ACPI driver remove callback to void
     and update its users accordingly (Dawei Li)

   - Add general support for FFH address space type and implement the
     low- level part of it for ARM64 (Sudeep Holla)

   - Fix stale comments in the ACPI tables parsing code and make it
     print more messages related to MADT (Hanjun Guo, Huacai Chen)

   - Replace invocations of generic library functions with more kernel-
     specific counterparts in the ACPI sysfs interface (Christophe
     JAILLET, Xu Panda)

   - Print full name paths of ACPI power resource objects during
     enumeration (Kane Chen)

   - Eliminate a compiler warning regarding a missing function prototype
     in the ACPI power management code (Sudeep Holla)

   - Fix and clean up the ACPI processor driver (Rafael Wysocki, Li
     Zhong, Colin Ian King, Sudeep Holla)

   - Add quirk for the HP Pavilion Gaming 15-cx0041ur to the ACPI EC
     driver (Mia Kanashi)

   - Add some mew ACPI backlight handling quirks and update some
     existing ones (Hans de Goede)

   - Make the ACPI backlight driver prefer the native backlight control
     over vendor backlight control when possible (Hans de Goede)

   - Drop unsetting ACPI APEI driver data on remove (Uwe Kleine-König)

   - Use xchg_release() instead of cmpxchg() for updating new GHES cache
     slots (Ard Biesheuvel)

   - Clean up the ACPI APEI code (Sudeep Holla, Christophe JAILLET, Jay
     Lu)

   - Add new I2C device enumeration quirks for Medion Lifetab S10346 and
     Lenovo Yoga Tab 3 Pro (YT3-X90F) (Hans de Goede)

   - Make the ACPI battery driver notify user space about adding new
     battery hooks and removing the existing ones (Armin Wolf)

   - Modify the pfr_update and pfr_telemetry drivers to use ACPI_FREE()
     for freeing acpi_object structures to help diagnostics (Wang
     ShaoBo)

   - Make the ACPI fan driver use sysfs_emit_at() in its sysfs interface
     code (ye xingchen)

   - Fix the _FIF package extraction failure handling in the ACPI fan
     driver (Hanjun Guo)

   - Fix the PCC mailbox handling error code path (Huisong Li)

   - Avoid using PCC Opregions if there is no platform interrupt
     allocated for this purpose (Huisong Li)

   - Use sysfs_emit() instead of scnprintf() in the ACPI PAD driver and
     CPPC library (ye xingchen)

   - Fix some kernel-doc issues in the ACPI GSI processing code
     (Xiongfeng Wang)

   - Fix name memory leak in pnp_alloc_dev() (Yang Yingliang)

   - Do not disable PNP devices on suspend when they cannot be
     re-enabled on resume (Hans de Goede)

   - Clean up the ACPI thermal driver a bit (Rafael Wysocki)"

* tag 'acpi-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (67 commits)
  ACPI: x86: Add skip i2c clients quirk for Medion Lifetab S10346
  ACPI: APEI: EINJ: Refactor available_error_type_show()
  ACPI: APEI: EINJ: Fix formatting errors
  ACPI: processor: perflib: Adjust acpi_processor_notify_smm() return value
  ACPI: processor: perflib: Rearrange acpi_processor_notify_smm()
  ACPI: processor: perflib: Rearrange unregistration routine
  ACPI: processor: perflib: Drop redundant parentheses
  ACPI: processor: perflib: Adjust white space
  ACPI: processor: idle: Drop unnecessary statements and parens
  ACPI: thermal: Adjust critical.flags.valid check
  ACPI: fan: Convert to use sysfs_emit_at() API
  ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage()
  ACPI: battery: Call power_supply_changed() when adding hooks
  ACPI: use sysfs_emit() instead of scnprintf()
  ACPI: x86: Add skip i2c clients quirk for Lenovo Yoga Tab 3 Pro (YT3-X90F)
  ACPI: APEI: Remove a useless include
  PNP: Do not disable devices on suspend when they cannot be re-enabled on resume
  ACPI: processor: Silence missing prototype warnings
  ACPI: processor_idle: Silence missing prototype warnings
  ACPI: PM: Silence missing prototype warning
  ...
This commit is contained in:
Linus Torvalds 2022-12-12 13:38:17 -08:00
commit 456ed864fd
106 changed files with 1174 additions and 637 deletions

View File

@ -13,6 +13,7 @@
#define pr_fmt(fmt) "ACPI: " fmt #define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/arm-smccc.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/efi-bgrt.h> #include <linux/efi-bgrt.h>
@ -411,3 +412,108 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
{ {
memblock_mark_nomap(addr, size); memblock_mark_nomap(addr, size);
} }
#ifdef CONFIG_ACPI_FFH
/*
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
* specified in https://developer.arm.com/docs/den0048/latest
*/
struct acpi_ffh_data {
struct acpi_ffh_info info;
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3,
unsigned long a4, unsigned long a5,
unsigned long a6, unsigned long a7,
struct arm_smccc_res *args,
struct arm_smccc_quirk *res);
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
};
int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
{
enum arm_smccc_conduit conduit;
struct acpi_ffh_data *ffh_ctxt;
ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
if (!ffh_ctxt)
return -ENOMEM;
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
return -EOPNOTSUPP;
conduit = arm_smccc_1_1_get_conduit();
if (conduit == SMCCC_CONDUIT_NONE) {
pr_err("%s: invalid SMCCC conduit\n", __func__);
return -EOPNOTSUPP;
}
if (conduit == SMCCC_CONDUIT_SMC) {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
} else {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
}
memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
*region_ctxt = ffh_ctxt;
return AE_OK;
}
static bool acpi_ffh_smccc_owner_allowed(u32 fid)
{
int owner = ARM_SMCCC_OWNER_NUM(fid);
if (owner == ARM_SMCCC_OWNER_STANDARD ||
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
return true;
return false;
}
int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
{
int ret = 0;
struct acpi_ffh_data *ffh_ctxt = region_context;
if (ffh_ctxt->info.offset == 0) {
/* SMC/HVC 32bit call */
struct arm_smccc_res res;
u32 a[8] = { 0 }, *ptr = (u32 *)value;
if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
!acpi_ffh_smccc_owner_allowed(*ptr) ||
ffh_ctxt->info.length > 32) {
ret = AE_ERROR;
} else {
int idx, len = ffh_ctxt->info.length >> 2;
for (idx = 0; idx < len; idx++)
a[idx] = *(ptr + idx);
ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
a[5], a[6], a[7], &res, NULL);
memcpy(value, &res, sizeof(res));
}
} else if (ffh_ctxt->info.offset == 1) {
/* SMC/HVC 64bit call */
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
!acpi_ffh_smccc_owner_allowed(r->a0) ||
ffh_ctxt->info.length > sizeof(*r)) {
ret = AE_ERROR;
} else {
ffh_ctxt->invoke_ffh64_fn(r, r);
memcpy(value, r, ffh_ctxt->info.length);
}
} else {
ret = AE_ERROR;
}
return ret;
}
#endif /* CONFIG_ACPI_FFH */

View File

@ -187,9 +187,9 @@ static int aml_nfw_add(struct acpi_device *device)
return aml_nfw_add_global_handler(); return aml_nfw_add_global_handler();
} }
static int aml_nfw_remove(struct acpi_device *device) static void aml_nfw_remove(struct acpi_device *device)
{ {
return aml_nfw_remove_global_handler(); aml_nfw_remove_global_handler();
} }
static const struct acpi_device_id aml_nfw_ids[] = { static const struct acpi_device_id aml_nfw_ids[] = {

View File

@ -31,148 +31,6 @@ static inline bool acpi_has_cpu_in_madt(void)
extern struct list_head acpi_wakeup_device_list; extern struct list_head acpi_wakeup_device_list;
/*
* Temporary definitions until the core ACPICA code gets updated (see
* 1656837932-18257-1-git-send-email-lvjianmin@loongson.cn and its
* follow-ups for the "rationale").
*
* Once the "legal reasons" are cleared and that the code is merged,
* this can be dropped entierely.
*/
#if (ACPI_CA_VERSION == 0x20220331 && !defined(LOONGARCH_ACPICA_EXT))
#define LOONGARCH_ACPICA_EXT 1
#define ACPI_MADT_TYPE_CORE_PIC 17
#define ACPI_MADT_TYPE_LIO_PIC 18
#define ACPI_MADT_TYPE_HT_PIC 19
#define ACPI_MADT_TYPE_EIO_PIC 20
#define ACPI_MADT_TYPE_MSI_PIC 21
#define ACPI_MADT_TYPE_BIO_PIC 22
#define ACPI_MADT_TYPE_LPC_PIC 23
/* Values for Version field above */
enum acpi_madt_core_pic_version {
ACPI_MADT_CORE_PIC_VERSION_NONE = 0,
ACPI_MADT_CORE_PIC_VERSION_V1 = 1,
ACPI_MADT_CORE_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_lio_pic_version {
ACPI_MADT_LIO_PIC_VERSION_NONE = 0,
ACPI_MADT_LIO_PIC_VERSION_V1 = 1,
ACPI_MADT_LIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_eio_pic_version {
ACPI_MADT_EIO_PIC_VERSION_NONE = 0,
ACPI_MADT_EIO_PIC_VERSION_V1 = 1,
ACPI_MADT_EIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_ht_pic_version {
ACPI_MADT_HT_PIC_VERSION_NONE = 0,
ACPI_MADT_HT_PIC_VERSION_V1 = 1,
ACPI_MADT_HT_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_bio_pic_version {
ACPI_MADT_BIO_PIC_VERSION_NONE = 0,
ACPI_MADT_BIO_PIC_VERSION_V1 = 1,
ACPI_MADT_BIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_msi_pic_version {
ACPI_MADT_MSI_PIC_VERSION_NONE = 0,
ACPI_MADT_MSI_PIC_VERSION_V1 = 1,
ACPI_MADT_MSI_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
enum acpi_madt_lpc_pic_version {
ACPI_MADT_LPC_PIC_VERSION_NONE = 0,
ACPI_MADT_LPC_PIC_VERSION_V1 = 1,
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
#pragma pack(1)
/* Core Interrupt Controller */
struct acpi_madt_core_pic {
struct acpi_subtable_header header;
u8 version;
u32 processor_id;
u32 core_id;
u32 flags;
};
/* Legacy I/O Interrupt Controller */
struct acpi_madt_lio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[2];
u32 cascade_map[2];
};
/* Extend I/O Interrupt Controller */
struct acpi_madt_eio_pic {
struct acpi_subtable_header header;
u8 version;
u8 cascade;
u8 node;
u64 node_map;
};
/* HT Interrupt Controller */
struct acpi_madt_ht_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[8];
};
/* Bridge I/O Interrupt Controller */
struct acpi_madt_bio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u16 id;
u16 gsi_base;
};
/* MSI Interrupt Controller */
struct acpi_madt_msi_pic {
struct acpi_subtable_header header;
u8 version;
u64 msg_address;
u32 start;
u32 count;
};
/* LPC Interrupt Controller */
struct acpi_madt_lpc_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade;
};
#pragma pack()
#endif
#endif /* !CONFIG_ACPI */ #endif /* !CONFIG_ACPI */
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT #define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT

View File

@ -183,13 +183,12 @@ err_sysfs:
return r; return r;
} }
static int xo15_sci_remove(struct acpi_device *device) static void xo15_sci_remove(struct acpi_device *device)
{ {
acpi_disable_gpe(NULL, xo15_sci_gpe); acpi_disable_gpe(NULL, xo15_sci_gpe);
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
cancel_work_sync(&sci_work); cancel_work_sync(&sci_work);
sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr); sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@ -564,6 +564,16 @@ config ACPI_PCC
Enable this feature if you want to set up and install the PCC Address Enable this feature if you want to set up and install the PCC Address
Space handler to handle PCC OpRegion in the firmware. Space handler to handle PCC OpRegion in the firmware.
config ACPI_FFH
bool "ACPI FFH Address Space"
default n
help
The FFH(Fixed Function Hardware) Address Space also referred as FFH
Operation Region allows to define platform specific opregion.
Enable this feature if you want to set up and install the FFH Address
Space handler to handle FFH OpRegion in the firmware.
source "drivers/acpi/pmic/Kconfig" source "drivers/acpi/pmic/Kconfig"
config ACPI_VIOT config ACPI_VIOT

View File

@ -68,6 +68,7 @@ acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
acpi-$(CONFIG_ACPI_PRMT) += prmt.o acpi-$(CONFIG_ACPI_PRMT) += prmt.o
acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o
acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o
# Address translation # Address translation
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o

View File

@ -33,7 +33,7 @@ MODULE_DESCRIPTION("ACPI AC Adapter Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device); static void acpi_ac_remove(struct acpi_device *device);
static void acpi_ac_notify(struct acpi_device *device, u32 event); static void acpi_ac_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id ac_device_ids[] = { static const struct acpi_device_id ac_device_ids[] = {
@ -288,12 +288,12 @@ static int acpi_ac_resume(struct device *dev)
#define acpi_ac_resume NULL #define acpi_ac_resume NULL
#endif #endif
static int acpi_ac_remove(struct acpi_device *device) static void acpi_ac_remove(struct acpi_device *device)
{ {
struct acpi_ac *ac = NULL; struct acpi_ac *ac = NULL;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return;
ac = acpi_driver_data(device); ac = acpi_driver_data(device);
@ -301,8 +301,6 @@ static int acpi_ac_remove(struct acpi_device *device)
unregister_acpi_notifier(&ac->battery_nb); unregister_acpi_notifier(&ac->battery_nb);
kfree(ac); kfree(ac);
return 0;
} }
static int __init acpi_ac_init(void) static int __init acpi_ac_init(void)

55
drivers/acpi/acpi_ffh.c Normal file
View File

@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Author: Sudeep Holla <sudeep.holla@arm.com>
* Copyright 2022 Arm Limited
*/
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/io.h>
#include <linux/arm-smccc.h>
static struct acpi_ffh_info ffh_ctx;
int __weak acpi_ffh_address_space_arch_setup(void *handler_ctxt,
void **region_ctxt)
{
return -EOPNOTSUPP;
}
int __weak acpi_ffh_address_space_arch_handler(acpi_integer *value,
void *region_context)
{
return -EOPNOTSUPP;
}
static acpi_status
acpi_ffh_address_space_setup(acpi_handle region_handle, u32 function,
void *handler_context, void **region_context)
{
return acpi_ffh_address_space_arch_setup(handler_context,
region_context);
}
static acpi_status
acpi_ffh_address_space_handler(u32 function, acpi_physical_address addr,
u32 bits, acpi_integer *value,
void *handler_context, void *region_context)
{
return acpi_ffh_address_space_arch_handler(value, region_context);
}
void __init acpi_init_ffh(void)
{
acpi_status status;
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_FIXED_HARDWARE,
&acpi_ffh_address_space_handler,
&acpi_ffh_address_space_setup,
&ffh_ctx);
if (ACPI_FAILURE(status))
pr_alert("OperationRegion handler could not be installed\n");
}

View File

@ -287,7 +287,7 @@ static ssize_t rrtime_store(struct device *dev,
static ssize_t rrtime_show(struct device *dev, static ssize_t rrtime_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time); return sysfs_emit(buf, "%d\n", round_robin_time);
} }
static DEVICE_ATTR_RW(rrtime); static DEVICE_ATTR_RW(rrtime);
@ -309,7 +309,7 @@ static ssize_t idlepct_store(struct device *dev,
static ssize_t idlepct_show(struct device *dev, static ssize_t idlepct_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct); return sysfs_emit(buf, "%d\n", idle_pct);
} }
static DEVICE_ATTR_RW(idlepct); static DEVICE_ATTR_RW(idlepct);
@ -449,7 +449,7 @@ static int acpi_pad_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_pad_remove(struct acpi_device *device) static void acpi_pad_remove(struct acpi_device *device)
{ {
mutex_lock(&isolated_cpus_lock); mutex_lock(&isolated_cpus_lock);
acpi_pad_idle_cpus(0); acpi_pad_idle_cpus(0);
@ -458,7 +458,6 @@ static int acpi_pad_remove(struct acpi_device *device)
acpi_remove_notify_handler(device->handle, acpi_remove_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY, acpi_pad_notify); ACPI_DEVICE_NOTIFY, acpi_pad_notify);
acpi_pad_remove_sysfs(device); acpi_pad_remove_sysfs(device);
return 0;
} }
static const struct acpi_device_id pad_device_ids[] = { static const struct acpi_device_id pad_device_ids[] = {

View File

@ -53,6 +53,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
struct pcc_data *data; struct pcc_data *data;
struct acpi_pcc_info *ctx = handler_context; struct acpi_pcc_info *ctx = handler_context;
struct pcc_mbox_chan *pcc_chan; struct pcc_mbox_chan *pcc_chan;
static acpi_status ret;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
@ -69,23 +70,35 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
if (IS_ERR(data->pcc_chan)) { if (IS_ERR(data->pcc_chan)) {
pr_err("Failed to find PCC channel for subspace %d\n", pr_err("Failed to find PCC channel for subspace %d\n",
ctx->subspace_id); ctx->subspace_id);
kfree(data); ret = AE_NOT_FOUND;
return AE_NOT_FOUND; goto err_free_data;
} }
pcc_chan = data->pcc_chan; pcc_chan = data->pcc_chan;
if (!pcc_chan->mchan->mbox->txdone_irq) {
pr_err("This channel-%d does not support interrupt.\n",
ctx->subspace_id);
ret = AE_SUPPORT;
goto err_free_channel;
}
data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr, data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr,
pcc_chan->shmem_size); pcc_chan->shmem_size);
if (!data->pcc_comm_addr) { if (!data->pcc_comm_addr) {
pr_err("Failed to ioremap PCC comm region mem for %d\n", pr_err("Failed to ioremap PCC comm region mem for %d\n",
ctx->subspace_id); ctx->subspace_id);
pcc_mbox_free_channel(data->pcc_chan); ret = AE_NO_MEMORY;
kfree(data); goto err_free_channel;
return AE_NO_MEMORY;
} }
*region_context = data; *region_context = data;
return AE_OK; return AE_OK;
err_free_channel:
pcc_mbox_free_channel(data->pcc_chan);
err_free_data:
kfree(data);
return ret;
} }
static acpi_status static acpi_status
@ -106,7 +119,6 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
if (ret < 0) if (ret < 0)
return AE_ERROR; return AE_ERROR;
if (data->pcc_chan->mchan->mbox->txdone_irq) {
/* /*
* pcc_chan->latency is just a Nominal value. In reality the remote * pcc_chan->latency is just a Nominal value. In reality the remote
* processor could be much slower to reply. So add an arbitrary * processor could be much slower to reply. So add an arbitrary
@ -119,7 +131,6 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
pr_err("PCC command executed timeout!\n"); pr_err("PCC command executed timeout!\n");
return AE_TIME; return AE_TIME;
} }
}
mbox_chan_txdone(data->pcc_chan->mchan, ret); mbox_chan_txdone(data->pcc_chan->mchan, ret);

View File

@ -86,7 +86,7 @@ static DEFINE_MUTEX(register_count_mutex);
static DEFINE_MUTEX(video_list_lock); static DEFINE_MUTEX(video_list_lock);
static LIST_HEAD(video_bus_head); static LIST_HEAD(video_bus_head);
static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device); static void acpi_video_bus_remove(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event); static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored); static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
static DECLARE_DELAYED_WORK(video_bus_register_backlight_work, static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
@ -2067,13 +2067,13 @@ err_free_video:
return error; return error;
} }
static int acpi_video_bus_remove(struct acpi_device *device) static void acpi_video_bus_remove(struct acpi_device *device)
{ {
struct acpi_video_bus *video = NULL; struct acpi_video_bus *video = NULL;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return;
video = acpi_driver_data(device); video = acpi_driver_data(device);
@ -2087,8 +2087,6 @@ static int acpi_video_bus_remove(struct acpi_device *device)
kfree(video->attached_array); kfree(video->attached_array);
kfree(video); kfree(video);
return 0;
} }
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored) static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)

View File

@ -155,6 +155,7 @@ acpi-y += \
utalloc.o \ utalloc.o \
utascii.o \ utascii.o \
utbuffer.o \ utbuffer.o \
utcksum.o \
utcopy.o \ utcopy.o \
utexcep.o \ utexcep.o \
utdebug.o \ utdebug.o \

View File

@ -24,6 +24,7 @@ ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list);
ACPI_GLOBAL(struct acpi_table_header *, acpi_gbl_DSDT); ACPI_GLOBAL(struct acpi_table_header *, acpi_gbl_DSDT);
ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header); ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header);
ACPI_INIT_GLOBAL(char *, acpi_gbl_CDAT, NULL);
ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX); ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX); ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX); ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);

View File

@ -124,11 +124,6 @@ void
acpi_tb_print_table_header(acpi_physical_address address, acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header); struct acpi_table_header *header);
u8 acpi_tb_checksum(u8 *buffer, u32 length);
acpi_status
acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void acpi_tb_check_dsdt_header(void); void acpi_tb_check_dsdt_header(void);
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);

View File

@ -158,6 +158,19 @@ u8 acpi_ut_valid_name_char(char character, u32 position);
void acpi_ut_check_and_repair_ascii(u8 *name, char *repaired_name, u32 count); void acpi_ut_check_and_repair_ascii(u8 *name, char *repaired_name, u32 count);
/*
* utcksum - Checksum utilities
*/
u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum);
u8 acpi_ut_checksum(u8 *buffer, u32 length);
acpi_status
acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length);
acpi_status
acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length);
/* /*
* utnonansi - Non-ANSI C library functions * utnonansi - Non-ANSI C library functions
*/ */

View File

@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
if (!info) { if (!info) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto pop_walk_state;
} }
info->parameters = &this_walk_state->operands[0]; info->parameters = &this_walk_state->operands[0];
@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
ACPI_FREE(info); ACPI_FREE(info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto cleanup; goto pop_walk_state;
} }
next_walk_state->method_nesting_depth = next_walk_state->method_nesting_depth =
@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
pop_walk_state:
/* On error, pop the walk state to be deleted from thread */
acpi_ds_pop_walk_state(thread);
cleanup: cleanup:
/* On error, we must terminate the method properly */ /* On error, we must terminate the method properly */

View File

@ -142,6 +142,9 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
status = status =
acpi_write_bit_register(acpi_gbl_fixed_event_info acpi_write_bit_register(acpi_gbl_fixed_event_info
[i].enable_register_id, [i].enable_register_id,
(i ==
ACPI_EVENT_PCIE_WAKE) ?
ACPI_ENABLE_EVENT :
ACPI_DISABLE_EVENT); ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
@ -185,6 +188,11 @@ u32 acpi_ev_fixed_event_detect(void)
return (int_status); return (int_status);
} }
if (fixed_enable & ACPI_BITMASK_PCIEXP_WAKE_DISABLE)
fixed_enable &= ~ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
else
fixed_enable |= ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n", "Fixed Event Block: Enable %08X Status %08X\n",
fixed_enable, fixed_status)); fixed_enable, fixed_status));
@ -250,6 +258,9 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
if (!acpi_gbl_fixed_event_handlers[event].handler) { if (!acpi_gbl_fixed_event_handlers[event].handler) {
(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
enable_register_id, enable_register_id,
(event ==
ACPI_EVENT_PCIE_WAKE) ?
ACPI_ENABLE_EVENT :
ACPI_DISABLE_EVENT); ACPI_DISABLE_EVENT);
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,

View File

@ -172,6 +172,15 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
ctx->subspace_id = (u8)region_obj->region.address; ctx->subspace_id = (u8)region_obj->region.address;
} }
if (region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE) {
struct acpi_ffh_info *ctx =
handler_desc->address_space.context;
ctx->length = region_obj->region.length;
ctx->offset = region_obj->region.address;
}
/* /*
* We must exit the interpreter because the region setup will * We must exit the interpreter because the region setup will
* potentially execute control methods (for example, the _REG method * potentially execute control methods (for example, the _REG method

View File

@ -295,8 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
target)); target));
} }
if (target->common.type != ACPI_TYPE_INTEGER) { if (target->common.type != ACPI_TYPE_INTEGER) {
ACPI_EXCEPTION((AE_INFO, AE_TYPE, ACPI_ERROR((AE_INFO, "Type not integer: %X",
"Type not integer: %X\n", target->common.type)); target->common.type));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE); return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
} }

View File

@ -141,7 +141,9 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
|| obj_desc->field.region_obj->region.space_id == || obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id == || obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) { ACPI_ADR_SPACE_PLATFORM_RT
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
/* SMBus, GSBus, IPMI serial */ /* SMBus, GSBus, IPMI serial */
@ -305,7 +307,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|| obj_desc->field.region_obj->region.space_id == || obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_IPMI ACPI_ADR_SPACE_IPMI
|| obj_desc->field.region_obj->region.space_id == || obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_PLATFORM_RT)) { ACPI_ADR_SPACE_PLATFORM_RT
|| obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
/* SMBus, GSBus, IPMI serial */ /* SMBus, GSBus, IPMI serial */

View File

@ -323,6 +323,12 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
function = ACPI_WRITE; function = ACPI_WRITE;
break; break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
function = ACPI_WRITE;
break;
default: default:
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
} }

View File

@ -311,6 +311,20 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
[ACPI_EVENT_SLEEP_BUTTON]. [ACPI_EVENT_SLEEP_BUTTON].
status_register_id, ACPI_CLEAR_STATUS); status_register_id, ACPI_CLEAR_STATUS);
/* Enable pcie wake event if support */
if ((acpi_gbl_FADT.flags & ACPI_FADT_PCI_EXPRESS_WAKE)) {
(void)
acpi_write_bit_register(acpi_gbl_fixed_event_info
[ACPI_EVENT_PCIE_WAKE].
enable_register_id,
ACPI_DISABLE_EVENT);
(void)
acpi_write_bit_register(acpi_gbl_fixed_event_info
[ACPI_EVENT_PCIE_WAKE].
status_register_id,
ACPI_CLEAR_STATUS);
}
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }

View File

@ -522,7 +522,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
/* Verify the checksum */ /* Verify the checksum */
status = status =
acpi_tb_verify_checksum(table_desc->pointer, acpi_ut_verify_checksum(table_desc->pointer,
table_desc->length); table_desc->length);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,

View File

@ -298,7 +298,7 @@ void acpi_tb_parse_fadt(void)
* Validate the FADT checksum before we copy the table. Ignore * Validate the FADT checksum before we copy the table. Ignore
* checksum error as we want to try to get the DSDT and FACS. * checksum error as we want to try to get the DSDT and FACS.
*/ */
(void)acpi_tb_verify_checksum(table, length); (void)acpi_ut_verify_checksum(table, length);
/* Create a local copy of the FADT in common ACPI 2.0+ format */ /* Create a local copy of the FADT in common ACPI 2.0+ format */

View File

@ -10,6 +10,7 @@
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include "accommon.h" #include "accommon.h"
#include "actables.h" #include "actables.h"
#include "acutils.h"
#define _COMPONENT ACPI_TABLES #define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME("tbprint") ACPI_MODULE_NAME("tbprint")
@ -39,7 +40,7 @@ static void acpi_tb_fix_string(char *string, acpi_size length)
{ {
while (length && *string) { while (length && *string) {
if (!isprint((int)*string)) { if (!isprint((int)(u8)*string)) {
*string = '?'; *string = '?';
} }
@ -135,77 +136,3 @@ acpi_tb_print_table_header(acpi_physical_address address,
local_header.asl_compiler_revision)); local_header.asl_compiler_revision));
} }
} }
/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_checksum
*
* PARAMETERS: table - ACPI table to verify
* length - Length of entire table
*
* RETURN: Status
*
* DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
* exception on bad checksum.
*
******************************************************************************/
acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
{
u8 checksum;
/*
* FACS/S3PT:
* They are the odd tables, have no standard ACPI header and no checksum
*/
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
return (AE_OK);
}
/* Compute the checksum on the table */
checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
/* Checksum ok? (should be zero) */
if (checksum) {
ACPI_BIOS_WARNING((AE_INFO,
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
"should be 0x%2.2X",
table->signature, table->checksum,
(u8)(table->checksum - checksum)));
#if (ACPI_CHECKSUM_ABORT)
return (AE_BAD_CHECKSUM);
#endif
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_checksum
*
* PARAMETERS: buffer - Pointer to memory region to be checked
* length - Length of this memory region
*
* RETURN: Checksum (u8)
*
* DESCRIPTION: Calculates circular checksum of memory region.
*
******************************************************************************/
u8 acpi_tb_checksum(u8 *buffer, u32 length)
{
u8 sum = 0;
u8 *end = buffer + length;
while (buffer < end) {
sum = (u8)(sum + *(buffer++));
}
return (sum);
}

View File

@ -299,7 +299,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
/* Validate the root table checksum */ /* Validate the root table checksum */
status = acpi_tb_verify_checksum(table, length); status = acpi_ut_verify_checksum(table, length);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_os_unmap_memory(table, length); acpi_os_unmap_memory(table, length);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);

View File

@ -74,14 +74,14 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
/* Check the standard checksum */ /* Check the standard checksum */
if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { if (acpi_ut_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
return (AE_BAD_CHECKSUM); return (AE_BAD_CHECKSUM);
} }
/* Check extended checksum if table version >= 2 */ /* Check extended checksum if table version >= 2 */
if ((rsdp->revision >= 2) && if ((rsdp->revision >= 2) &&
(acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { (acpi_ut_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
return (AE_BAD_CHECKSUM); return (AE_BAD_CHECKSUM);
} }
@ -114,6 +114,7 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
u8 *table_ptr; u8 *table_ptr;
u8 *mem_rover; u8 *mem_rover;
u32 physical_address; u32 physical_address;
u32 ebda_window_size;
ACPI_FUNCTION_TRACE(acpi_find_root_pointer); ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
@ -139,26 +140,37 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
/* EBDA present? */ /* EBDA present? */
if (physical_address > 0x400) {
/* /*
* 1b) Search EBDA paragraphs (EBDA is required to be a * Check that the EBDA pointer from memory is sane and does not point
* minimum of 1K length) * above valid low memory
*/
if (physical_address > 0x400 && physical_address < 0xA0000) {
/*
* Calculate the scan window size
* The EBDA is not guaranteed to be larger than a ki_b and in case
* that it is smaller, the scanning function would leave the low
* memory and continue to the VGA range.
*/
ebda_window_size = ACPI_MIN(ACPI_EBDA_WINDOW_SIZE,
0xA0000 - physical_address);
/*
* 1b) Search EBDA paragraphs
*/ */
table_ptr = acpi_os_map_memory((acpi_physical_address) table_ptr = acpi_os_map_memory((acpi_physical_address)
physical_address, physical_address,
ACPI_EBDA_WINDOW_SIZE); ebda_window_size);
if (!table_ptr) { if (!table_ptr) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Could not map memory at 0x%8.8X for length %u", "Could not map memory at 0x%8.8X for length %u",
physical_address, ACPI_EBDA_WINDOW_SIZE)); physical_address, ebda_window_size));
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
mem_rover = mem_rover =
acpi_tb_scan_memory_for_rsdp(table_ptr, acpi_tb_scan_memory_for_rsdp(table_ptr, ebda_window_size);
ACPI_EBDA_WINDOW_SIZE); acpi_os_unmap_memory(table_ptr, ebda_window_size);
acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) { if (mem_rover) {

View File

@ -0,0 +1,170 @@
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
*
* Module Name: utcksum - Support generating table checksums
*
* Copyright (C) 2000 - 2022, Intel Corp.
*
*****************************************************************************/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acutils.h"
/* This module used for application-level code only */
#define _COMPONENT ACPI_CA_DISASSEMBLER
ACPI_MODULE_NAME("utcksum")
/*******************************************************************************
*
* FUNCTION: acpi_ut_verify_checksum
*
* PARAMETERS: table - ACPI table to verify
* length - Length of entire table
*
* RETURN: Status
*
* DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
* exception on bad checksum.
* Note: We don't have to check for a CDAT here, since CDAT is
* not in the RSDT/XSDT, and the CDAT table is never installed
* via ACPICA.
*
******************************************************************************/
acpi_status acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length)
{
u8 checksum;
/*
* FACS/S3PT:
* They are the odd tables, have no standard ACPI header and no checksum
*/
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
return (AE_OK);
}
/* Compute the checksum on the table */
length = table->length;
checksum =
acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, table), length,
table->checksum);
/* Computed checksum matches table? */
if (checksum != table->checksum) {
ACPI_BIOS_WARNING((AE_INFO,
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
"should be 0x%2.2X",
table->signature, table->checksum,
table->checksum - checksum));
#if (ACPI_CHECKSUM_ABORT)
return (AE_BAD_CHECKSUM);
#endif
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_verify_cdat_checksum
*
* PARAMETERS: table - CDAT ACPI table to verify
* length - Length of entire table
*
* RETURN: Status
*
* DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally
* returns an exception on bad checksum.
*
******************************************************************************/
acpi_status
acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length)
{
u8 checksum;
/* Compute the checksum on the table */
checksum = acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, cdat_table),
cdat_table->length,
cdat_table->checksum);
/* Computed checksum matches table? */
if (checksum != cdat_table->checksum) {
ACPI_BIOS_WARNING((AE_INFO,
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
"should be 0x%2.2X",
acpi_gbl_CDAT, cdat_table->checksum,
checksum));
#if (ACPI_CHECKSUM_ABORT)
return (AE_BAD_CHECKSUM);
#endif
}
cdat_table->checksum = checksum;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_generate_checksum
*
* PARAMETERS: table - Pointer to table to be checksummed
* length - Length of the table
* original_checksum - Value of the checksum field
*
* RETURN: 8 bit checksum of buffer
*
* DESCRIPTION: Computes an 8 bit checksum of the table.
*
******************************************************************************/
u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum)
{
u8 checksum;
/* Sum the entire table as-is */
checksum = acpi_ut_checksum((u8 *)table, length);
/* Subtract off the existing checksum value in the table */
checksum = (u8)(checksum - original_checksum);
/* Compute and return the final checksum */
checksum = (u8)(0 - checksum);
return (checksum);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_checksum
*
* PARAMETERS: buffer - Pointer to memory region to be checked
* length - Length of this memory region
*
* RETURN: Checksum (u8)
*
* DESCRIPTION: Calculates circular checksum of memory region.
*
******************************************************************************/
u8 acpi_ut_checksum(u8 *buffer, u32 length)
{
u8 sum = 0;
u8 *end = buffer + length;
while (buffer < end) {
sum = (u8)(sum + *(buffer++));
}
return (sum);
}

View File

@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
status = acpi_ut_walk_package_tree(source_obj, dest_obj, status = acpi_ut_walk_package_tree(source_obj, dest_obj,
acpi_ut_copy_ielement_to_ielement, acpi_ut_copy_ielement_to_ielement,
walk_state); walk_state);
if (ACPI_FAILURE(status)) {
/* On failure, delete the destination package object */
acpi_ut_remove_reference(dest_obj);
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }

View File

@ -186,6 +186,10 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITREG_RT_CLOCK_ENABLE,
ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS,
ACPI_BITMASK_RT_CLOCK_ENABLE}, ACPI_BITMASK_RT_CLOCK_ENABLE},
/* ACPI_EVENT_PCIE_WAKE */ {ACPI_BITREG_PCIEXP_WAKE_STATUS,
ACPI_BITREG_PCIEXP_WAKE_DISABLE,
ACPI_BITMASK_PCIEXP_WAKE_STATUS,
ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
}; };
#endif /* !ACPI_REDUCED_HARDWARE */ #endif /* !ACPI_REDUCED_HARDWARE */

View File

@ -145,7 +145,7 @@ void acpi_ut_repair_name(char *name)
return; return;
} }
ACPI_COPY_NAMESEG(&original_name, name); ACPI_COPY_NAMESEG(&original_name, &name[0]);
/* Check each character in the name */ /* Check each character in the name */
@ -156,10 +156,10 @@ void acpi_ut_repair_name(char *name)
/* /*
* Replace a bad character with something printable, yet technically * Replace a bad character with something printable, yet technically
* still invalid. This prevents any collisions with existing "good" * "odd". This prevents any collisions with existing "good"
* names in the namespace. * names in the namespace.
*/ */
name[i] = '*'; name[i] = '_';
found_bad_char = TRUE; found_bad_char = TRUE;
} }
@ -169,8 +169,8 @@ void acpi_ut_repair_name(char *name)
if (!acpi_gbl_enable_interpreter_slack) { if (!acpi_gbl_enable_interpreter_slack) {
ACPI_WARNING((AE_INFO, ACPI_WARNING((AE_INFO,
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", "Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]",
original_name, name)); original_name, name, &name[0]));
} else { } else {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]", "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",

View File

@ -25,9 +25,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/rculist.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <acpi/apei.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "apei-internal.h" #include "apei-internal.h"

View File

@ -358,6 +358,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
*/ */
if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) { if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
struct apei_resources addr_resources; struct apei_resources addr_resources;
apei_resources_init(&addr_resources); apei_resources_init(&addr_resources);
trigger_param_region = einj_get_trigger_parameter_region( trigger_param_region = einj_get_trigger_parameter_region(
trigger_tab, param1, param2); trigger_tab, param1, param2);
@ -466,6 +467,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
return rc; return rc;
if (einj_param) { if (einj_param) {
struct einj_parameter *v4param = einj_param; struct einj_parameter *v4param = einj_param;
v4param->param1 = param1; v4param->param1 = param1;
v4param->param2 = param2; v4param->param2 = param2;
} }
@ -569,6 +571,20 @@ static u64 error_param2;
static u64 error_param3; static u64 error_param3;
static u64 error_param4; static u64 error_param4;
static struct dentry *einj_debug_dir; static struct dentry *einj_debug_dir;
static const char * const einj_error_type_string[] = {
"0x00000001\tProcessor Correctable\n",
"0x00000002\tProcessor Uncorrectable non-fatal\n",
"0x00000004\tProcessor Uncorrectable fatal\n",
"0x00000008\tMemory Correctable\n",
"0x00000010\tMemory Uncorrectable non-fatal\n",
"0x00000020\tMemory Uncorrectable fatal\n",
"0x00000040\tPCI Express Correctable\n",
"0x00000080\tPCI Express Uncorrectable non-fatal\n",
"0x00000100\tPCI Express Uncorrectable fatal\n",
"0x00000200\tPlatform Correctable\n",
"0x00000400\tPlatform Uncorrectable non-fatal\n",
"0x00000800\tPlatform Uncorrectable fatal\n",
};
static int available_error_type_show(struct seq_file *m, void *v) static int available_error_type_show(struct seq_file *m, void *v)
{ {
@ -578,30 +594,9 @@ static int available_error_type_show(struct seq_file *m, void *v)
rc = einj_get_available_error_type(&available_error_type); rc = einj_get_available_error_type(&available_error_type);
if (rc) if (rc)
return rc; return rc;
if (available_error_type & 0x0001) for (int pos = 0; pos < ARRAY_SIZE(einj_error_type_string); pos++)
seq_printf(m, "0x00000001\tProcessor Correctable\n"); if (available_error_type & BIT(pos))
if (available_error_type & 0x0002) seq_puts(m, einj_error_type_string[pos]);
seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n");
if (available_error_type & 0x0004)
seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n");
if (available_error_type & 0x0008)
seq_printf(m, "0x00000008\tMemory Correctable\n");
if (available_error_type & 0x0010)
seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n");
if (available_error_type & 0x0020)
seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n");
if (available_error_type & 0x0040)
seq_printf(m, "0x00000040\tPCI Express Correctable\n");
if (available_error_type & 0x0080)
seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n");
if (available_error_type & 0x0100)
seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n");
if (available_error_type & 0x0200)
seq_printf(m, "0x00000200\tPlatform Correctable\n");
if (available_error_type & 0x0400)
seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n");
if (available_error_type & 0x0800)
seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n");
return 0; return 0;
} }
@ -689,8 +684,7 @@ static int __init einj_init(void)
if (status == AE_NOT_FOUND) { if (status == AE_NOT_FOUND) {
pr_warn("EINJ table not found.\n"); pr_warn("EINJ table not found.\n");
return -ENODEV; return -ENODEV;
} } else if (ACPI_FAILURE(status)) {
else if (ACPI_FAILURE(status)) {
pr_err("Failed to get EINJ table: %s\n", pr_err("Failed to get EINJ table: %s\n",
acpi_format_exception(status)); acpi_format_exception(status));
return -EINVAL; return -EINVAL;

View File

@ -138,7 +138,7 @@ struct ghes_vendor_record_entry {
static struct gen_pool *ghes_estatus_pool; static struct gen_pool *ghes_estatus_pool;
static unsigned long ghes_estatus_pool_size_request; static unsigned long ghes_estatus_pool_size_request;
static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; static struct ghes_estatus_cache __rcu *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
static atomic_t ghes_estatus_cache_alloced; static atomic_t ghes_estatus_cache_alloced;
static int ghes_panic_timeout __read_mostly = 30; static int ghes_panic_timeout __read_mostly = 30;
@ -773,48 +773,42 @@ static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
return cache; return cache;
} }
static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache) static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
{ {
struct ghes_estatus_cache *cache;
u32 len; u32 len;
cache = container_of(head, struct ghes_estatus_cache, rcu);
len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache));
len = GHES_ESTATUS_CACHE_LEN(len); len = GHES_ESTATUS_CACHE_LEN(len);
gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len);
atomic_dec(&ghes_estatus_cache_alloced); atomic_dec(&ghes_estatus_cache_alloced);
} }
static void ghes_estatus_cache_rcu_free(struct rcu_head *head) static void
{ ghes_estatus_cache_add(struct acpi_hest_generic *generic,
struct ghes_estatus_cache *cache;
cache = container_of(head, struct ghes_estatus_cache, rcu);
ghes_estatus_cache_free(cache);
}
static void ghes_estatus_cache_add(
struct acpi_hest_generic *generic,
struct acpi_hest_generic_status *estatus) struct acpi_hest_generic_status *estatus)
{ {
int i, slot = -1, count;
unsigned long long now, duration, period, max_period = 0; unsigned long long now, duration, period, max_period = 0;
struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache; struct ghes_estatus_cache *cache, *new_cache;
struct ghes_estatus_cache __rcu *victim;
int i, slot = -1, count;
new_cache = ghes_estatus_cache_alloc(generic, estatus); new_cache = ghes_estatus_cache_alloc(generic, estatus);
if (new_cache == NULL) if (!new_cache)
return; return;
rcu_read_lock(); rcu_read_lock();
now = sched_clock(); now = sched_clock();
for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
cache = rcu_dereference(ghes_estatus_caches[i]); cache = rcu_dereference(ghes_estatus_caches[i]);
if (cache == NULL) { if (cache == NULL) {
slot = i; slot = i;
slot_cache = NULL;
break; break;
} }
duration = now - cache->time_in; duration = now - cache->time_in;
if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) { if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) {
slot = i; slot = i;
slot_cache = cache;
break; break;
} }
count = atomic_read(&cache->count); count = atomic_read(&cache->count);
@ -823,18 +817,30 @@ static void ghes_estatus_cache_add(
if (period > max_period) { if (period > max_period) {
max_period = period; max_period = period;
slot = i; slot = i;
slot_cache = cache;
} }
} }
/* new_cache must be put into array after its contents are written */
smp_wmb();
if (slot != -1 && cmpxchg(ghes_estatus_caches + slot,
slot_cache, new_cache) == slot_cache) {
if (slot_cache)
call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free);
} else
ghes_estatus_cache_free(new_cache);
rcu_read_unlock(); rcu_read_unlock();
if (slot != -1) {
/*
* Use release semantics to ensure that ghes_estatus_cached()
* running on another CPU will see the updated cache fields if
* it can see the new value of the pointer.
*/
victim = xchg_release(&ghes_estatus_caches[slot],
RCU_INITIALIZER(new_cache));
/*
* At this point, victim may point to a cached item different
* from the one based on which we selected the slot. Instead of
* going to the loop again to pick another slot, let's just
* drop the other item anyway: this may cause a false cache
* miss later on, but that won't cause any problems.
*/
if (victim)
call_rcu(&unrcu_pointer(victim)->rcu,
ghes_estatus_cache_rcu_free);
}
} }
static void __ghes_panic(struct ghes *ghes, static void __ghes_panic(struct ghes *ghes,
@ -1444,8 +1450,6 @@ static int ghes_remove(struct platform_device *ghes_dev)
kfree(ghes); kfree(ghes);
platform_set_drvdata(ghes_dev, NULL);
return 0; return 0;
} }

View File

@ -696,7 +696,8 @@ static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
if (lock) if (lock)
mutex_lock(&hook_mutex); mutex_lock(&hook_mutex);
list_for_each_entry(battery, &acpi_battery_list, list) { list_for_each_entry(battery, &acpi_battery_list, list) {
hook->remove_battery(battery->bat, hook); if (!hook->remove_battery(battery->bat, hook))
power_supply_changed(battery->bat);
} }
list_del(&hook->list); list_del(&hook->list);
if (lock) if (lock)
@ -735,6 +736,8 @@ void battery_hook_register(struct acpi_battery_hook *hook)
__battery_hook_unregister(hook, 0); __battery_hook_unregister(hook, 0);
goto end; goto end;
} }
power_supply_changed(battery->bat);
} }
pr_info("new extension: %s\n", hook->name); pr_info("new extension: %s\n", hook->name);
end: end:
@ -1208,12 +1211,12 @@ fail:
return result; return result;
} }
static int acpi_battery_remove(struct acpi_device *device) static void acpi_battery_remove(struct acpi_device *device)
{ {
struct acpi_battery *battery = NULL; struct acpi_battery *battery = NULL;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return;
device_init_wakeup(&device->dev, 0); device_init_wakeup(&device->dev, 0);
battery = acpi_driver_data(device); battery = acpi_driver_data(device);
unregister_pm_notifier(&battery->pm_nb); unregister_pm_notifier(&battery->pm_nb);
@ -1221,7 +1224,6 @@ static int acpi_battery_remove(struct acpi_device *device)
mutex_destroy(&battery->lock); mutex_destroy(&battery->lock);
mutex_destroy(&battery->sysfs_lock); mutex_destroy(&battery->sysfs_lock);
kfree(battery); kfree(battery);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@ -324,6 +324,8 @@ static void acpi_bus_osc_negotiate_platform_control(void)
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
if (IS_ENABLED(CONFIG_ACPI_PRMT)) if (IS_ENABLED(CONFIG_ACPI_PRMT))
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
if (IS_ENABLED(CONFIG_ACPI_FFH))
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FFH_OPR_SUPPORT;
#ifdef CONFIG_ARM64 #ifdef CONFIG_ARM64
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
@ -1409,6 +1411,7 @@ static int __init acpi_init(void)
disable_acpi(); disable_acpi();
return result; return result;
} }
acpi_init_ffh();
pci_mmcfg_late_init(); pci_mmcfg_late_init();
acpi_iort_init(); acpi_iort_init();

View File

@ -125,7 +125,7 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
}; };
static int acpi_button_add(struct acpi_device *device); static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device); static void acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event); static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
@ -580,14 +580,13 @@ static int acpi_button_add(struct acpi_device *device)
return error; return error;
} }
static int acpi_button_remove(struct acpi_device *device) static void acpi_button_remove(struct acpi_device *device)
{ {
struct acpi_button *button = acpi_driver_data(device); struct acpi_button *button = acpi_driver_data(device);
acpi_button_remove_fs(device); acpi_button_remove_fs(device);
input_unregister_device(button->input); input_unregister_device(button->input);
kfree(button); kfree(button);
return 0;
} }
static int param_set_lid_init_state(const char *val, static int param_set_lid_init_state(const char *val,

View File

@ -148,7 +148,7 @@ __ATTR(_name, 0444, show_##_name, NULL)
if (ret) \ if (ret) \
return ret; \ return ret; \
\ \
return scnprintf(buf, PAGE_SIZE, "%llu\n", \ return sysfs_emit(buf, "%llu\n", \
(u64)st_name.member_name); \ (u64)st_name.member_name); \
} \ } \
define_one_cppc_ro(member_name) define_one_cppc_ro(member_name)
@ -174,7 +174,7 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj,
if (ret) if (ret)
return ret; return ret;
return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n", return sysfs_emit(buf, "ref:%llu del:%llu\n",
fb_ctrs.reference, fb_ctrs.delivered); fb_ctrs.reference, fb_ctrs.delivered);
} }
define_one_cppc_ro(feedback_ctrs); define_one_cppc_ro(feedback_ctrs);

View File

@ -1663,12 +1663,12 @@ err:
return ret; return ret;
} }
static int acpi_ec_remove(struct acpi_device *device) static void acpi_ec_remove(struct acpi_device *device)
{ {
struct acpi_ec *ec; struct acpi_ec *ec;
if (!device) if (!device)
return -EINVAL; return;
ec = acpi_driver_data(device); ec = acpi_driver_data(device);
release_region(ec->data_addr, 1); release_region(ec->data_addr, 1);
@ -1678,7 +1678,6 @@ static int acpi_ec_remove(struct acpi_device *device)
ec_remove_handlers(ec); ec_remove_handlers(ec);
acpi_ec_free(ec); acpi_ec_free(ec);
} }
return 0;
} }
static acpi_status static acpi_status
@ -1875,6 +1874,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),
}, },
}, },
{
/*
* HP Pavilion Gaming Laptop 15-cx0041ur
*/
.callback = ec_honor_dsdt_gpe,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"),
},
},
{ {
/* /*
* Samsung hardware * Samsung hardware

View File

@ -27,24 +27,24 @@ static ssize_t show_state(struct device *dev, struct device_attribute *attr, cha
count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control); count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9) if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:"); count += sysfs_emit_at(buf, count, "not-defined:");
else else
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point); count += sysfs_emit_at(buf, count, "%lld:", fps->trip_point);
if (fps->speed == 0xFFFFFFFF) if (fps->speed == 0xFFFFFFFF)
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:"); count += sysfs_emit_at(buf, count, "not-defined:");
else else
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed); count += sysfs_emit_at(buf, count, "%lld:", fps->speed);
if (fps->noise_level == 0xFFFFFFFF) if (fps->noise_level == 0xFFFFFFFF)
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:"); count += sysfs_emit_at(buf, count, "not-defined:");
else else
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100); count += sysfs_emit_at(buf, count, "%lld:", fps->noise_level * 100);
if (fps->power == 0xFFFFFFFF) if (fps->power == 0xFFFFFFFF)
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n"); count += sysfs_emit_at(buf, count, "not-defined\n");
else else
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power); count += sysfs_emit_at(buf, count, "%lld\n", fps->power);
return count; return count;
} }

View File

@ -236,6 +236,7 @@ static int acpi_fan_get_fif(struct acpi_device *device)
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Invalid _FIF element\n"); dev_err(&device->dev, "Invalid _FIF element\n");
status = -EINVAL; status = -EINVAL;
goto err;
} }
fan->fif.revision = fields[0]; fan->fif.revision = fields[0];

View File

@ -56,10 +56,9 @@ static int acpi_hed_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_hed_remove(struct acpi_device *device) static void acpi_hed_remove(struct acpi_device *device)
{ {
hed_handle = NULL; hed_handle = NULL;
return 0;
} }
static struct acpi_driver acpi_hed_driver = { static struct acpi_driver acpi_hed_driver = {

View File

@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
/** /**
* acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source. * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source.
* @source: acpi_resource_source to use for the lookup. * @source: acpi_resource_source to use for the lookup.
* @gsi: GSI IRQ number
* *
* Description: * Description:
* Retrieve the fwhandle of the device referenced by the given IRQ resource * Retrieve the fwhandle of the device referenced by the given IRQ resource
@ -297,8 +298,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get);
/** /**
* acpi_set_irq_model - Setup the GSI irqdomain information * acpi_set_irq_model - Setup the GSI irqdomain information
* @model: the value assigned to acpi_irq_model * @model: the value assigned to acpi_irq_model
* @fwnode: the irq_domain identifier for mapping and looking up * @fn: a dispatcher function that will return the domain fwnode
* GSI interrupts * for a given GSI
*/ */
void __init acpi_set_irq_model(enum acpi_irq_model_id model, void __init acpi_set_irq_model(enum acpi_irq_model_id model,
struct fwnode_handle *(*fn)(u32)) struct fwnode_handle *(*fn)(u32))

View File

@ -3371,10 +3371,9 @@ static int acpi_nfit_add(struct acpi_device *adev)
return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc); return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
} }
static int acpi_nfit_remove(struct acpi_device *adev) static void acpi_nfit_remove(struct acpi_device *adev)
{ {
/* see acpi_nfit_unregister */ /* see acpi_nfit_unregister */
return 0;
} }
static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle) static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)

View File

@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info,
ret = 0; ret = 0;
free_acpi_buffer: free_acpi_buffer:
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }
@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev)
ret = -EBUSY; ret = -EBUSY;
} }
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }
@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev)
ret = obj->integer.value; ret = obj->integer.value;
free_acpi_buffer: free_acpi_buffer:
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }

View File

@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr,
ret = 0; ret = 0;
free_acpi_buffer: free_acpi_buffer:
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }
@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info,
ret = 0; ret = 0;
free_acpi_buffer: free_acpi_buffer:
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }
@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev)
ret = 0; ret = 0;
free_acpi_buffer: free_acpi_buffer:
kfree(out_obj); ACPI_FREE(out_obj);
return ret; return ret;
} }

View File

@ -967,7 +967,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
if (acpi_power_get_state(resource, &state_dummy)) if (acpi_power_get_state(resource, &state_dummy))
__acpi_power_on(resource); __acpi_power_on(resource);
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device)); acpi_handle_info(handle, "New power resource\n");
result = acpi_tie_acpi_dev(device); result = acpi_tie_acpi_dev(device);
if (result) if (result)

View File

@ -324,7 +324,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* the erratum), but this is known to disrupt certain ISA * the erratum), but this is known to disrupt certain ISA
* devices thus we take the conservative approach. * devices thus we take the conservative approach.
*/ */
else if (errata.piix4.fdma) { if (errata.piix4.fdma) {
acpi_handle_debug(pr->handle, acpi_handle_debug(pr->handle,
"C3 not supported on PIIX4 with Type-F DMA\n"); "C3 not supported on PIIX4 with Type-F DMA\n");
return; return;
@ -384,8 +384,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* handle BM_RLD is to set it and leave it set. * handle BM_RLD is to set it and leave it set.
*/ */
acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1); acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
} }
static int acpi_cst_latency_cmp(const void *a, const void *b) static int acpi_cst_latency_cmp(const void *a, const void *b)
@ -459,7 +457,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
lapic_timer_propagate_broadcast(pr); lapic_timer_propagate_broadcast(pr);
return (working); return working;
} }
static int acpi_processor_get_cstate_info(struct acpi_processor *pr) static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
@ -1134,6 +1132,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
status = acpi_get_parent(handle, &pr_ahandle); status = acpi_get_parent(handle, &pr_ahandle);
while (ACPI_SUCCESS(status)) { while (ACPI_SUCCESS(status)) {
d = acpi_fetch_acpi_dev(pr_ahandle); d = acpi_fetch_acpi_dev(pr_ahandle);
if (!d)
break;
handle = pr_ahandle; handle = pr_ahandle;
if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID)) if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID))

View File

@ -142,6 +142,7 @@ int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
pr = per_cpu(processors, cpu); pr = per_cpu(processors, cpu);
if (!pr || !pr->performance || !pr->performance->state_count) if (!pr || !pr->performance || !pr->performance->state_count)
return -ENODEV; return -ENODEV;
*limit = pr->performance->states[pr->performance_platform_limit]. *limit = pr->performance->states[pr->performance_platform_limit].
core_frequency * 1000; core_frequency * 1000;
return 0; return 0;
@ -201,8 +202,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
} }
pct = (union acpi_object *)buffer.pointer; pct = (union acpi_object *)buffer.pointer;
if (!pct || (pct->type != ACPI_TYPE_PACKAGE) if (!pct || pct->type != ACPI_TYPE_PACKAGE || pct->package.count != 2) {
|| (pct->package.count != 2)) {
pr_err("Invalid _PCT data\n"); pr_err("Invalid _PCT data\n");
result = -EFAULT; result = -EFAULT;
goto end; goto end;
@ -214,9 +214,8 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
obj = pct->package.elements[0]; obj = pct->package.elements[0];
if ((obj.type != ACPI_TYPE_BUFFER) if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER ||
|| (obj.buffer.length < sizeof(struct acpi_pct_register)) obj.buffer.length < sizeof(struct acpi_pct_register)) {
|| (obj.buffer.pointer == NULL)) {
pr_err("Invalid _PCT data (control_register)\n"); pr_err("Invalid _PCT data (control_register)\n");
result = -EFAULT; result = -EFAULT;
goto end; goto end;
@ -230,9 +229,8 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
obj = pct->package.elements[1]; obj = pct->package.elements[1];
if ((obj.type != ACPI_TYPE_BUFFER) if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER ||
|| (obj.buffer.length < sizeof(struct acpi_pct_register)) obj.buffer.length < sizeof(struct acpi_pct_register)) {
|| (obj.buffer.pointer == NULL)) {
pr_err("Invalid _PCT data (status_register)\n"); pr_err("Invalid _PCT data (status_register)\n");
result = -EFAULT; result = -EFAULT;
goto end; goto end;
@ -260,8 +258,8 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return; return;
if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) ||
|| boot_cpu_data.x86 == 0x11) { boot_cpu_data.x86 == 0x11) {
rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
/* /*
* MSR C001_0064+: * MSR C001_0064+:
@ -300,7 +298,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
} }
pss = buffer.pointer; pss = buffer.pointer;
if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { if (!pss || pss->type != ACPI_TYPE_PACKAGE) {
pr_err("Invalid _PSS data\n"); pr_err("Invalid _PSS data\n");
result = -EFAULT; result = -EFAULT;
goto end; goto end;
@ -353,8 +351,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
* Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
*/ */
if (!px->core_frequency || if (!px->core_frequency ||
((u32)(px->core_frequency * 1000) != (u32)(px->core_frequency * 1000) != px->core_frequency * 1000) {
(px->core_frequency * 1000))) {
pr_err(FW_BUG pr_err(FW_BUG
"Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n", "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
pr->id, px->core_frequency); pr->id, px->core_frequency);
@ -456,7 +453,7 @@ int acpi_processor_pstate_control(void)
int acpi_processor_notify_smm(struct module *calling_module) int acpi_processor_notify_smm(struct module *calling_module)
{ {
static int is_done; static int is_done;
int result; int result = 0;
if (!acpi_processor_cpufreq_init) if (!acpi_processor_cpufreq_init)
return -EBUSY; return -EBUSY;
@ -464,42 +461,41 @@ int acpi_processor_notify_smm(struct module *calling_module)
if (!try_module_get(calling_module)) if (!try_module_get(calling_module))
return -EINVAL; return -EINVAL;
/* is_done is set to negative if an error occurred, /*
* and to postitive if _no_ error occurred, but SMM * is_done is set to negative if an error occurs and to 1 if no error
* was already notified. This avoids double notification * occurrs, but SMM has been notified already. This avoids repeated
* which might lead to unexpected results... * notification which might lead to unexpected results.
*/ */
if (is_done > 0) { if (is_done != 0) {
module_put(calling_module); if (is_done < 0)
return 0; result = is_done;
} else if (is_done < 0) {
module_put(calling_module);
return is_done;
}
is_done = -EIO; goto out_put;
}
result = acpi_processor_pstate_control(); result = acpi_processor_pstate_control();
if (!result) { if (result <= 0) {
if (result) {
is_done = result;
} else {
pr_debug("No SMI port or pstate_control\n"); pr_debug("No SMI port or pstate_control\n");
module_put(calling_module); is_done = 1;
return 0;
} }
if (result < 0) { goto out_put;
}
is_done = 1;
/*
* Success. If there _PPC, unloading the cpufreq driver would be risky,
* so disallow it in that case.
*/
if (acpi_processor_ppc_in_use)
return 0;
out_put:
module_put(calling_module); module_put(calling_module);
return result; return result;
}
/* Success. If there's no _PPC, we need to fear nothing, so
* we can allow the cpufreq driver to be rmmod'ed. */
is_done = 1;
if (!acpi_processor_ppc_in_use)
module_put(calling_module);
return 0;
} }
EXPORT_SYMBOL(acpi_processor_notify_smm); EXPORT_SYMBOL(acpi_processor_notify_smm);
int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain) int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
@ -517,7 +513,7 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
} }
psd = buffer.pointer; psd = buffer.pointer;
if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { if (!psd || psd->type != ACPI_TYPE_PACKAGE) {
pr_err("Invalid _PSD data\n"); pr_err("Invalid _PSD data\n");
result = -EFAULT; result = -EFAULT;
goto end; goto end;
@ -532,8 +528,7 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
state.length = sizeof(struct acpi_psd_package); state.length = sizeof(struct acpi_psd_package);
state.pointer = pdomain; state.pointer = pdomain;
status = acpi_extract_package(&(psd->package.elements[0]), status = acpi_extract_package(&(psd->package.elements[0]), &format, &state);
&format, &state);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
pr_err("Invalid _PSD data\n"); pr_err("Invalid _PSD data\n");
result = -EFAULT; result = -EFAULT;
@ -716,8 +711,7 @@ err_out:
} }
EXPORT_SYMBOL(acpi_processor_preregister_performance); EXPORT_SYMBOL(acpi_processor_preregister_performance);
int int acpi_processor_register_performance(struct acpi_processor_performance
acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu) *performance, unsigned int cpu)
{ {
struct acpi_processor *pr; struct acpi_processor *pr;
@ -751,7 +745,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL(acpi_processor_register_performance); EXPORT_SYMBOL(acpi_processor_register_performance);
void acpi_processor_unregister_performance(unsigned int cpu) void acpi_processor_unregister_performance(unsigned int cpu)
@ -761,18 +754,15 @@ void acpi_processor_unregister_performance(unsigned int cpu)
mutex_lock(&performance_mutex); mutex_lock(&performance_mutex);
pr = per_cpu(processors, cpu); pr = per_cpu(processors, cpu);
if (!pr) { if (!pr)
mutex_unlock(&performance_mutex); goto unlock;
return;
}
if (pr->performance) if (pr->performance)
kfree(pr->performance->states); kfree(pr->performance->states);
pr->performance = NULL; pr->performance = NULL;
unlock:
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return;
} }
EXPORT_SYMBOL(acpi_processor_unregister_performance); EXPORT_SYMBOL(acpi_processor_unregister_performance);

View File

@ -50,7 +50,7 @@ static int __acpi_processor_set_throttling(struct acpi_processor *pr,
static int acpi_processor_update_tsd_coord(void) static int acpi_processor_update_tsd_coord(void)
{ {
int count, count_target; int count_target;
int retval = 0; int retval = 0;
unsigned int i, j; unsigned int i, j;
cpumask_var_t covered_cpus; cpumask_var_t covered_cpus;
@ -107,7 +107,6 @@ static int acpi_processor_update_tsd_coord(void)
/* Validate the Domain info */ /* Validate the Domain info */
count_target = pdomain->num_processors; count_target = pdomain->num_processors;
count = 1;
for_each_possible_cpu(j) { for_each_possible_cpu(j) {
if (i == j) if (i == j)
@ -140,7 +139,6 @@ static int acpi_processor_update_tsd_coord(void)
cpumask_set_cpu(j, covered_cpus); cpumask_set_cpu(j, covered_cpus);
cpumask_set_cpu(j, pthrottling->shared_cpu_map); cpumask_set_cpu(j, pthrottling->shared_cpu_map);
count++;
} }
for_each_possible_cpu(j) { for_each_possible_cpu(j) {
if (i == j) if (i == j)

View File

@ -96,7 +96,7 @@ struct acpi_sbs {
#define to_acpi_sbs(x) power_supply_get_drvdata(x) #define to_acpi_sbs(x) power_supply_get_drvdata(x)
static int acpi_sbs_remove(struct acpi_device *device); static void acpi_sbs_remove(struct acpi_device *device);
static int acpi_battery_get_state(struct acpi_battery *battery); static int acpi_battery_get_state(struct acpi_battery *battery);
static inline int battery_scale(int log) static inline int battery_scale(int log)
@ -664,16 +664,16 @@ end:
return result; return result;
} }
static int acpi_sbs_remove(struct acpi_device *device) static void acpi_sbs_remove(struct acpi_device *device)
{ {
struct acpi_sbs *sbs; struct acpi_sbs *sbs;
int id; int id;
if (!device) if (!device)
return -EINVAL; return;
sbs = acpi_driver_data(device); sbs = acpi_driver_data(device);
if (!sbs) if (!sbs)
return -EINVAL; return;
mutex_lock(&sbs->lock); mutex_lock(&sbs->lock);
acpi_smbus_unregister_callback(sbs->hc); acpi_smbus_unregister_callback(sbs->hc);
for (id = 0; id < MAX_SBS_BAT; ++id) for (id = 0; id < MAX_SBS_BAT; ++id)
@ -682,7 +682,6 @@ static int acpi_sbs_remove(struct acpi_device *device)
mutex_unlock(&sbs->lock); mutex_unlock(&sbs->lock);
mutex_destroy(&sbs->lock); mutex_destroy(&sbs->lock);
kfree(sbs); kfree(sbs);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@ -30,7 +30,7 @@ struct acpi_smb_hc {
}; };
static int acpi_smbus_hc_add(struct acpi_device *device); static int acpi_smbus_hc_add(struct acpi_device *device);
static int acpi_smbus_hc_remove(struct acpi_device *device); static void acpi_smbus_hc_remove(struct acpi_device *device);
static const struct acpi_device_id sbs_device_ids[] = { static const struct acpi_device_id sbs_device_ids[] = {
{"ACPI0001", 0}, {"ACPI0001", 0},
@ -280,19 +280,18 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
static int acpi_smbus_hc_remove(struct acpi_device *device) static void acpi_smbus_hc_remove(struct acpi_device *device)
{ {
struct acpi_smb_hc *hc; struct acpi_smb_hc *hc;
if (!device) if (!device)
return -EINVAL; return;
hc = acpi_driver_data(device); hc = acpi_driver_data(device);
acpi_ec_remove_query_handler(hc->ec, hc->query_bit); acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
acpi_os_wait_events_complete(); acpi_os_wait_events_complete();
kfree(hc); kfree(hc);
device->driver_data = NULL; device->driver_data = NULL;
return 0;
} }
module_acpi_driver(acpi_smb_hc_driver); module_acpi_driver(acpi_smb_hc_driver);

View File

@ -30,7 +30,7 @@ extern struct acpi_device *acpi_root;
#define ACPI_BUS_HID "LNXSYBUS" #define ACPI_BUS_HID "LNXSYBUS"
#define ACPI_BUS_DEVICE_NAME "System Bus" #define ACPI_BUS_DEVICE_NAME "System Bus"
#define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) #define INVALID_ACPI_HANDLE ((acpi_handle)ZERO_PAGE(0))
static const char *dummy_hid = "device"; static const char *dummy_hid = "device";

View File

@ -9,6 +9,7 @@
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kstrtox.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include "internal.h" #include "internal.h"
@ -197,7 +198,7 @@ static int param_set_trace_method_name(const char *val,
static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp) static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp)
{ {
return scnprintf(buffer, PAGE_SIZE, "%s\n", acpi_gbl_trace_method_name); return sysfs_emit(buffer, "%s\n", acpi_gbl_trace_method_name);
} }
static const struct kernel_param_ops param_ops_trace_method = { static const struct kernel_param_ops param_ops_trace_method = {
@ -992,7 +993,7 @@ static ssize_t force_remove_store(struct kobject *kobj,
bool val; bool val;
int ret; int ret;
ret = strtobool(buf, &val); ret = kstrtobool(buf, &val);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -210,6 +210,16 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
} }
break; break;
case ACPI_MADT_TYPE_CORE_PIC:
{
struct acpi_madt_core_pic *p = (struct acpi_madt_core_pic *)header;
pr_debug("CORE PIC (processor_id[0x%02x] core_id[0x%02x] %s)\n",
p->processor_id, p->core_id,
(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
}
break;
default: default:
pr_warn("Found unsupported MADT entry (type = 0x%x)\n", pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
header->type); header->type);
@ -838,12 +848,11 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
/* /*
* acpi_locate_initial_tables() * acpi_locate_initial_tables()
* *
* find RSDP, find and checksum SDT/XSDT. * Get the RSDP, then find and checksum all the ACPI tables.
* checksum all tables, print SDT/XSDT
* *
* result: sdt_entry[] is initialized * result: initial_tables[] is initialized, and points to
* a list of ACPI tables.
*/ */
int __init acpi_locate_initial_tables(void) int __init acpi_locate_initial_tables(void)
{ {
acpi_status status; acpi_status status;

View File

@ -74,7 +74,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
static struct workqueue_struct *acpi_thermal_pm_queue; static struct workqueue_struct *acpi_thermal_pm_queue;
static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device); static void acpi_thermal_remove(struct acpi_device *device);
static void acpi_thermal_notify(struct acpi_device *device, u32 event); static void acpi_thermal_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id thermal_device_ids[] = { static const struct acpi_device_id thermal_device_ids[] = {
@ -291,7 +291,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
"Found critical threshold [%lu]\n", "Found critical threshold [%lu]\n",
tz->trips.critical.temperature); tz->trips.critical.temperature);
} }
if (tz->trips.critical.flags.valid == 1) { if (tz->trips.critical.flags.valid) {
if (crt == -1) { if (crt == -1) {
tz->trips.critical.flags.valid = 0; tz->trips.critical.flags.valid = 0;
} else if (crt > 0) { } else if (crt > 0) {
@ -1059,19 +1059,18 @@ end:
return result; return result;
} }
static int acpi_thermal_remove(struct acpi_device *device) static void acpi_thermal_remove(struct acpi_device *device)
{ {
struct acpi_thermal *tz; struct acpi_thermal *tz;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return;
flush_workqueue(acpi_thermal_pm_queue); flush_workqueue(acpi_thermal_pm_queue);
tz = acpi_driver_data(device); tz = acpi_driver_data(device);
acpi_thermal_unregister_thermal_zone(tz); acpi_thermal_unregister_thermal_zone(tz);
kfree(tz); kfree(tz);
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@ -19,11 +19,15 @@ static const struct acpi_device_id tiny_power_button_device_ids[] = {
}; };
MODULE_DEVICE_TABLE(acpi, tiny_power_button_device_ids); MODULE_DEVICE_TABLE(acpi, tiny_power_button_device_ids);
static int acpi_noop_add_remove(struct acpi_device *device) static int acpi_noop_add(struct acpi_device *device)
{ {
return 0; return 0;
} }
static void acpi_noop_remove(struct acpi_device *device)
{
}
static void acpi_tiny_power_button_notify(struct acpi_device *device, u32 event) static void acpi_tiny_power_button_notify(struct acpi_device *device, u32 event)
{ {
kill_cad_pid(power_signal, 1); kill_cad_pid(power_signal, 1);
@ -34,8 +38,8 @@ static struct acpi_driver acpi_tiny_power_button_driver = {
.class = "tiny-power-button", .class = "tiny-power-button",
.ids = tiny_power_button_device_ids, .ids = tiny_power_button_device_ids,
.ops = { .ops = {
.add = acpi_noop_add_remove, .add = acpi_noop_add,
.remove = acpi_noop_add_remove, .remove = acpi_noop_remove,
.notify = acpi_tiny_power_button_notify, .notify = acpi_tiny_power_button_notify,
}, },
}; };

View File

@ -132,6 +132,10 @@ static int video_detect_force_none(const struct dmi_system_id *d)
} }
static const struct dmi_system_id video_detect_dmi_table[] = { static const struct dmi_system_id video_detect_dmi_table[] = {
/*
* Models which should use the vendor backlight interface,
* because of broken ACPI video backlight control.
*/
{ {
/* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */ /* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
.callback = video_detect_force_vendor, .callback = video_detect_force_vendor,
@ -166,6 +170,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
}, },
}, },
{ {
/* https://bugs.launchpad.net/bugs/1000146 */
.callback = video_detect_force_vendor, .callback = video_detect_force_vendor,
/* Asus X101CH */ /* Asus X101CH */
.matches = { .matches = {
@ -190,6 +195,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
}, },
}, },
{ {
/* https://bugs.launchpad.net/bugs/1000146 */
.callback = video_detect_force_vendor, .callback = video_detect_force_vendor,
/* Asus 1015CX */ /* Asus 1015CX */
.matches = { .matches = {
@ -197,14 +203,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"), DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"),
}, },
}, },
{
.callback = video_detect_force_vendor,
/* GIGABYTE GB-BXBT-2807 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
},
},
{ {
.callback = video_detect_force_vendor, .callback = video_detect_force_vendor,
/* Samsung N150/N210/N220 */ /* Samsung N150/N210/N220 */
@ -232,14 +230,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"), DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"),
}, },
}, },
{
.callback = video_detect_force_vendor,
/* Sony VPCEH3U1E */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
},
},
{ {
.callback = video_detect_force_vendor, .callback = video_detect_force_vendor,
/* Xiaomi Mi Pad 2 */ /* Xiaomi Mi Pad 2 */
@ -249,6 +239,19 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
}, },
}, },
/*
* Models which should use the vendor backlight interface,
* because of broken native backlight control.
*/
{
.callback = video_detect_force_vendor,
/* Sony Vaio PCG-FRV35 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
},
},
/* /*
* Toshiba models with Transflective display, these need to use * Toshiba models with Transflective display, these need to use
* the toshiba_acpi vendor driver for proper Transflective handling. * the toshiba_acpi vendor driver for proper Transflective handling.
@ -400,8 +403,8 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
}, },
}, },
/* https://bugs.launchpad.net/bugs/1894667 */
{ {
/* https://bugs.launchpad.net/bugs/1894667 */
.callback = video_detect_force_video, .callback = video_detect_force_video,
/* HP 635 Notebook */ /* HP 635 Notebook */
.matches = { .matches = {
@ -609,6 +612,23 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "N250P"), DMI_MATCH(DMI_BOARD_NAME, "N250P"),
}, },
}, },
{
/* https://bugzilla.kernel.org/show_bug.cgi?id=202401 */
.callback = video_detect_force_native,
/* Sony Vaio VPCEH3U1E */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
},
},
{
.callback = video_detect_force_native,
/* Sony Vaio VPCY11S1E */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VPCY11S1E"),
},
},
/* /*
* These Toshibas have a broken acpi-video interface for brightness * These Toshibas have a broken acpi-video interface for brightness
@ -671,6 +691,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
}, },
}, },
{
.callback = video_detect_force_none,
/* GIGABYTE GB-BXBT-2807 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
},
},
{ {
.callback = video_detect_force_none, .callback = video_detect_force_none,
/* MSI MS-7721 */ /* MSI MS-7721 */
@ -687,6 +715,16 @@ static bool google_cros_ec_present(void)
return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C"); return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C");
} }
/*
* Windows 8 and newer no longer use the ACPI video interface, so it often
* does not work. So on win8+ systems prefer native brightness control.
* Chromebooks should always prefer native backlight control.
*/
static bool prefer_native_over_acpi_video(void)
{
return acpi_osi_is_win8() || google_cros_ec_present();
}
/* /*
* Determine which type of backlight interface to use on this system, * Determine which type of backlight interface to use on this system,
* First check cmdline, then dmi quirks, then do autodetect. * First check cmdline, then dmi quirks, then do autodetect.
@ -732,28 +770,16 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
if (apple_gmux_present()) if (apple_gmux_present())
return acpi_backlight_apple_gmux; return acpi_backlight_apple_gmux;
/* Chromebooks should always prefer native backlight control. */ /* Use ACPI video if available, except when native should be preferred. */
if (google_cros_ec_present() && native_available) if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
return acpi_backlight_native; !(native_available && prefer_native_over_acpi_video()))
/* On systems with ACPI video use either native or ACPI video. */
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
/*
* Windows 8 and newer no longer use the ACPI video interface,
* so it often does not work. If the ACPI tables are written
* for win8 and native brightness ctl is available, use that.
*
* The native check deliberately is inside the if acpi-video
* block on older devices without acpi-video support native
* is usually not the best choice.
*/
if (acpi_osi_is_win8() && native_available)
return acpi_backlight_native;
else
return acpi_backlight_video; return acpi_backlight_video;
}
/* No ACPI video (old hw), use vendor specific fw methods. */ /* Use native if available */
if (native_available)
return acpi_backlight_native;
/* No ACPI video/native (old hw), use vendor specific fw methods. */
return acpi_backlight_vendor; return acpi_backlight_vendor;
} }
@ -765,18 +791,6 @@ EXPORT_SYMBOL(acpi_video_get_backlight_type);
bool acpi_video_backlight_use_native(void) bool acpi_video_backlight_use_native(void)
{ {
/* return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
* Call __acpi_video_get_backlight_type() to let it know that
* a native backlight is available.
*/
__acpi_video_get_backlight_type(true);
/*
* For now just always return true. There is a whole bunch of laptop
* models where (video_caps & ACPI_VIDEO_BACKLIGHT) is false causing
* __acpi_video_get_backlight_type() to return vendor, while these
* models only have a native backlight control.
*/
return true;
} }
EXPORT_SYMBOL(acpi_video_backlight_use_native); EXPORT_SYMBOL(acpi_video_backlight_use_native);

View File

@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
}, },
{ {
/* Lenovo Yoga Tablet 1050F/L */ /* Lenovo Yoga Tablet 2 1050F/L */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
@ -319,6 +319,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
}, },
{
/* Lenovo Yoga Tab 3 Pro X90F */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
},
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
},
{
/* Medion Lifetab S10346 */
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
/* Way too generic, also match on BIOS data */
DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
},
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
},
{ {
/* Nextbook Ares 8 */ /* Nextbook Ares 8 */
.matches = { .matches = {
@ -348,6 +369,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = {
{ "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */
{ "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */
{ "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */
{ "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */
{ "NPCE69A", 0 }, /* Asus Transformer keyboard dock */ { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */
{} {}
}; };

View File

@ -1123,10 +1123,9 @@ static int sonypi_acpi_add(struct acpi_device *device)
return 0; return 0;
} }
static int sonypi_acpi_remove(struct acpi_device *device) static void sonypi_acpi_remove(struct acpi_device *device)
{ {
sonypi_acpi_device = NULL; sonypi_acpi_device = NULL;
return 0;
} }
static const struct acpi_device_id sonypi_device_ids[] = { static const struct acpi_device_id sonypi_device_ids[] = {

View File

@ -724,14 +724,12 @@ out:
return rc; return rc;
} }
static int crb_acpi_remove(struct acpi_device *device) static void crb_acpi_remove(struct acpi_device *device)
{ {
struct device *dev = &device->dev; struct device *dev = &device->dev;
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
tpm_chip_unregister(chip); tpm_chip_unregister(chip);
return 0;
} }
static const struct dev_pm_ops crb_pm = { static const struct dev_pm_ops crb_pm = {

View File

@ -2262,7 +2262,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
return AE_OK; return AE_OK;
} }
static int vmbus_acpi_remove(struct acpi_device *device) static void vmbus_acpi_remove(struct acpi_device *device)
{ {
struct resource *cur_res; struct resource *cur_res;
struct resource *next_res; struct resource *next_res;
@ -2279,8 +2279,6 @@ static int vmbus_acpi_remove(struct acpi_device *device)
kfree(cur_res); kfree(cur_res);
} }
} }
return 0;
} }
static void vmbus_reserve_fb(void) static void vmbus_reserve_fb(void)

View File

@ -910,12 +910,12 @@ exit:
return res; return res;
} }
static int acpi_power_meter_remove(struct acpi_device *device) static void acpi_power_meter_remove(struct acpi_device *device)
{ {
struct acpi_power_meter_resource *resource; struct acpi_power_meter_resource *resource;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return;
resource = acpi_driver_data(device); resource = acpi_driver_data(device);
hwmon_device_unregister(resource->hwmon_dev); hwmon_device_unregister(resource->hwmon_dev);
@ -924,7 +924,6 @@ static int acpi_power_meter_remove(struct acpi_device *device)
free_capabilities(resource); free_capabilities(resource);
kfree(resource); kfree(resource);
return 0;
} }
static int acpi_power_meter_resume(struct device *dev) static int acpi_power_meter_resume(struct device *dev)

View File

@ -187,7 +187,7 @@ struct atk_acpi_input_buf {
}; };
static int atk_add(struct acpi_device *device); static int atk_add(struct acpi_device *device);
static int atk_remove(struct acpi_device *device); static void atk_remove(struct acpi_device *device);
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
@ -1344,7 +1344,7 @@ out:
return err; return err;
} }
static int atk_remove(struct acpi_device *device) static void atk_remove(struct acpi_device *device)
{ {
struct atk_data *data = device->driver_data; struct atk_data *data = device->driver_data;
dev_dbg(&device->dev, "removing...\n"); dev_dbg(&device->dev, "removing...\n");
@ -1359,8 +1359,6 @@ static int atk_remove(struct acpi_device *device)
if (atk_ec_ctl(data, 0)) if (atk_ec_ctl(data, 0))
dev_err(&device->dev, "Failed to disable EC\n"); dev_err(&device->dev, "Failed to disable EC\n");
} }
return 0;
} }
static int __init atk0110_init(void) static int __init atk0110_init(void)

View File

@ -106,7 +106,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
return err; return err;
} }
static int atlas_acpi_button_remove(struct acpi_device *device) static void atlas_acpi_button_remove(struct acpi_device *device)
{ {
acpi_status status; acpi_status status;
@ -116,8 +116,6 @@ static int atlas_acpi_button_remove(struct acpi_device *device)
pr_err("error removing addr spc handler\n"); pr_err("error removing addr spc handler\n");
input_unregister_device(input_dev); input_unregister_device(input_dev);
return 0;
} }
static const struct acpi_device_id atlas_device_ids[] = { static const struct acpi_device_id atlas_device_ids[] = {

View File

@ -743,6 +743,7 @@ static int __init pcc_init(void)
if (IS_ERR(pcc_pdev)) { if (IS_ERR(pcc_pdev)) {
pr_debug("Err creating PCC platform bundle\n"); pr_debug("Err creating PCC platform bundle\n");
pcc_chan_count = 0;
return PTR_ERR(pcc_pdev); return PTR_ERR(pcc_pdev);
} }

View File

@ -145,14 +145,12 @@ static int fjes_acpi_add(struct acpi_device *device)
return 0; return 0;
} }
static int fjes_acpi_remove(struct acpi_device *device) static void fjes_acpi_remove(struct acpi_device *device)
{ {
struct platform_device *plat_dev; struct platform_device *plat_dev;
plat_dev = (struct platform_device *)acpi_driver_data(device); plat_dev = (struct platform_device *)acpi_driver_data(device);
platform_device_unregister(plat_dev); platform_device_unregister(plat_dev);
return 0;
} }
static struct acpi_driver fjes_acpi_driver = { static struct acpi_driver fjes_acpi_driver = {

View File

@ -123,12 +123,11 @@ static int chromeos_privacy_screen_add(struct acpi_device *adev)
return 0; return 0;
} }
static int chromeos_privacy_screen_remove(struct acpi_device *adev) static void chromeos_privacy_screen_remove(struct acpi_device *adev)
{ {
struct drm_privacy_screen *drm_privacy_screen = acpi_driver_data(adev); struct drm_privacy_screen *drm_privacy_screen = acpi_driver_data(adev);
drm_privacy_screen_unregister(drm_privacy_screen); drm_privacy_screen_unregister(drm_privacy_screen);
return 0;
} }
static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = { static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {

View File

@ -500,15 +500,13 @@ free_minor:
return error; return error;
} }
static int event_device_remove(struct acpi_device *adev) static void event_device_remove(struct acpi_device *adev)
{ {
struct event_device_data *dev_data = adev->driver_data; struct event_device_data *dev_data = adev->driver_data;
cdev_device_del(&dev_data->cdev, &dev_data->dev); cdev_device_del(&dev_data->cdev, &dev_data->dev);
ida_simple_remove(&event_ida, MINOR(dev_data->dev.devt)); ida_simple_remove(&event_ida, MINOR(dev_data->dev.devt));
hangup_device(dev_data); hangup_device(dev_data);
return 0;
} }
static const struct acpi_device_id event_acpi_ids[] = { static const struct acpi_device_id event_acpi_ids[] = {

View File

@ -239,13 +239,12 @@ static int surface_button_add(struct acpi_device *device)
return error; return error;
} }
static int surface_button_remove(struct acpi_device *device) static void surface_button_remove(struct acpi_device *device)
{ {
struct surface_button *button = acpi_driver_data(device); struct surface_button *button = acpi_driver_data(device);
input_unregister_device(button->input); input_unregister_device(button->input);
kfree(button); kfree(button);
return 0;
} }
static SIMPLE_DEV_PM_OPS(surface_button_pm, static SIMPLE_DEV_PM_OPS(surface_button_pm,

View File

@ -1901,7 +1901,7 @@ fail_platform:
return result; return result;
} }
static int asus_acpi_remove(struct acpi_device *device) static void asus_acpi_remove(struct acpi_device *device)
{ {
struct asus_laptop *asus = acpi_driver_data(device); struct asus_laptop *asus = acpi_driver_data(device);
@ -1914,7 +1914,6 @@ static int asus_acpi_remove(struct acpi_device *device)
kfree(asus->name); kfree(asus->name);
kfree(asus); kfree(asus);
return 0;
} }
static const struct acpi_device_id asus_device_ids[] = { static const struct acpi_device_id asus_device_ids[] = {

View File

@ -175,7 +175,7 @@ static int asus_wireless_add(struct acpi_device *adev)
return err; return err;
} }
static int asus_wireless_remove(struct acpi_device *adev) static void asus_wireless_remove(struct acpi_device *adev)
{ {
struct asus_wireless_data *data = acpi_driver_data(adev); struct asus_wireless_data *data = acpi_driver_data(adev);
@ -183,7 +183,6 @@ static int asus_wireless_remove(struct acpi_device *adev)
devm_led_classdev_unregister(&adev->dev, &data->led); devm_led_classdev_unregister(&adev->dev, &data->led);
destroy_workqueue(data->wq); destroy_workqueue(data->wq);
} }
return 0;
} }
static struct acpi_driver asus_wireless_driver = { static struct acpi_driver asus_wireless_driver = {

View File

@ -418,11 +418,11 @@ failed_sensitivity:
return error; return error;
} }
static int cmpc_accel_remove_v4(struct acpi_device *acpi) static void cmpc_accel_remove_v4(struct acpi_device *acpi)
{ {
device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
return cmpc_remove_acpi_notify_device(acpi); cmpc_remove_acpi_notify_device(acpi);
} }
static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4, static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4,
@ -648,10 +648,10 @@ failed_file:
return error; return error;
} }
static int cmpc_accel_remove(struct acpi_device *acpi) static void cmpc_accel_remove(struct acpi_device *acpi)
{ {
device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
return cmpc_remove_acpi_notify_device(acpi); cmpc_remove_acpi_notify_device(acpi);
} }
static const struct acpi_device_id cmpc_accel_device_ids[] = { static const struct acpi_device_id cmpc_accel_device_ids[] = {
@ -727,9 +727,9 @@ static int cmpc_tablet_add(struct acpi_device *acpi)
cmpc_tablet_idev_init); cmpc_tablet_idev_init);
} }
static int cmpc_tablet_remove(struct acpi_device *acpi) static void cmpc_tablet_remove(struct acpi_device *acpi)
{ {
return cmpc_remove_acpi_notify_device(acpi); cmpc_remove_acpi_notify_device(acpi);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
@ -974,7 +974,7 @@ out_bd:
return retval; return retval;
} }
static int cmpc_ipml_remove(struct acpi_device *acpi) static void cmpc_ipml_remove(struct acpi_device *acpi)
{ {
struct ipml200_dev *ipml; struct ipml200_dev *ipml;
@ -988,8 +988,6 @@ static int cmpc_ipml_remove(struct acpi_device *acpi)
} }
kfree(ipml); kfree(ipml);
return 0;
} }
static const struct acpi_device_id cmpc_ipml_device_ids[] = { static const struct acpi_device_id cmpc_ipml_device_ids[] = {
@ -1055,9 +1053,9 @@ static int cmpc_keys_add(struct acpi_device *acpi)
cmpc_keys_idev_init); cmpc_keys_idev_init);
} }
static int cmpc_keys_remove(struct acpi_device *acpi) static void cmpc_keys_remove(struct acpi_device *acpi)
{ {
return cmpc_remove_acpi_notify_device(acpi); cmpc_remove_acpi_notify_device(acpi);
} }
static const struct acpi_device_id cmpc_keys_device_ids[] = { static const struct acpi_device_id cmpc_keys_device_ids[] = {

View File

@ -206,7 +206,7 @@ static void rbtn_input_event(struct rbtn_data *rbtn_data)
*/ */
static int rbtn_add(struct acpi_device *device); static int rbtn_add(struct acpi_device *device);
static int rbtn_remove(struct acpi_device *device); static void rbtn_remove(struct acpi_device *device);
static void rbtn_notify(struct acpi_device *device, u32 event); static void rbtn_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id rbtn_ids[] = { static const struct acpi_device_id rbtn_ids[] = {
@ -426,7 +426,7 @@ static int rbtn_add(struct acpi_device *device)
} }
static int rbtn_remove(struct acpi_device *device) static void rbtn_remove(struct acpi_device *device)
{ {
struct rbtn_data *rbtn_data = device->driver_data; struct rbtn_data *rbtn_data = device->driver_data;
@ -443,8 +443,6 @@ static int rbtn_remove(struct acpi_device *device)
rbtn_acquire(device, false); rbtn_acquire(device, false);
device->driver_data = NULL; device->driver_data = NULL;
return 0;
} }
static void rbtn_notify(struct acpi_device *device, u32 event) static void rbtn_notify(struct acpi_device *device, u32 event)

View File

@ -1440,7 +1440,7 @@ fail_platform:
return result; return result;
} }
static int eeepc_acpi_remove(struct acpi_device *device) static void eeepc_acpi_remove(struct acpi_device *device)
{ {
struct eeepc_laptop *eeepc = acpi_driver_data(device); struct eeepc_laptop *eeepc = acpi_driver_data(device);
@ -1451,7 +1451,6 @@ static int eeepc_acpi_remove(struct acpi_device *device)
eeepc_platform_exit(eeepc); eeepc_platform_exit(eeepc);
kfree(eeepc); kfree(eeepc);
return 0;
} }

View File

@ -847,15 +847,13 @@ err_free_fifo:
return ret; return ret;
} }
static int acpi_fujitsu_laptop_remove(struct acpi_device *device) static void acpi_fujitsu_laptop_remove(struct acpi_device *device)
{ {
struct fujitsu_laptop *priv = acpi_driver_data(device); struct fujitsu_laptop *priv = acpi_driver_data(device);
fujitsu_laptop_platform_remove(device); fujitsu_laptop_platform_remove(device);
kfifo_free(&priv->fifo); kfifo_free(&priv->fifo);
return 0;
} }
static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode) static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode)

View File

@ -484,12 +484,11 @@ static int acpi_fujitsu_add(struct acpi_device *adev)
return 0; return 0;
} }
static int acpi_fujitsu_remove(struct acpi_device *adev) static void acpi_fujitsu_remove(struct acpi_device *adev)
{ {
free_irq(fujitsu.irq, fujitsu_interrupt); free_irq(fujitsu.irq, fujitsu_interrupt);
release_region(fujitsu.io_base, fujitsu.io_length); release_region(fujitsu.io_base, fujitsu.io_length);
input_fujitsu_remove(); input_fujitsu_remove();
return 0;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@ -113,12 +113,10 @@ static int irst_add(struct acpi_device *acpi)
return error; return error;
} }
static int irst_remove(struct acpi_device *acpi) static void irst_remove(struct acpi_device *acpi)
{ {
device_remove_file(&acpi->dev, &irst_wakeup_attr); device_remove_file(&acpi->dev, &irst_wakeup_attr);
device_remove_file(&acpi->dev, &irst_timeout_attr); device_remove_file(&acpi->dev, &irst_timeout_attr);
return 0;
} }
static const struct acpi_device_id irst_ids[] = { static const struct acpi_device_id irst_ids[] = {

View File

@ -761,7 +761,7 @@ out_platform_registered:
return ret; return ret;
} }
static int acpi_remove(struct acpi_device *device) static void acpi_remove(struct acpi_device *device)
{ {
sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group); sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group);
@ -773,8 +773,6 @@ static int acpi_remove(struct acpi_device *device)
platform_device_unregister(pf_device); platform_device_unregister(pf_device);
pf_device = NULL; pf_device = NULL;
platform_driver_unregister(&pf_driver); platform_driver_unregister(&pf_driver);
return 0;
} }
static const struct acpi_device_id device_ids[] = { static const struct acpi_device_id device_ids[] = {

View File

@ -183,7 +183,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
static int acpi_pcc_hotkey_add(struct acpi_device *device); static int acpi_pcc_hotkey_add(struct acpi_device *device);
static int acpi_pcc_hotkey_remove(struct acpi_device *device); static void acpi_pcc_hotkey_remove(struct acpi_device *device);
static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id pcc_device_ids[] = { static const struct acpi_device_id pcc_device_ids[] = {
@ -1065,12 +1065,12 @@ out_hotkey:
return result; return result;
} }
static int acpi_pcc_hotkey_remove(struct acpi_device *device) static void acpi_pcc_hotkey_remove(struct acpi_device *device)
{ {
struct pcc_acpi *pcc = acpi_driver_data(device); struct pcc_acpi *pcc = acpi_driver_data(device);
if (!device || !pcc) if (!device || !pcc)
return -EINVAL; return;
i8042_remove_filter(panasonic_i8042_filter); i8042_remove_filter(panasonic_i8042_filter);
@ -1088,8 +1088,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device)
kfree(pcc->sinf); kfree(pcc->sinf);
kfree(pcc); kfree(pcc);
return 0;
} }
module_acpi_driver(acpi_pcc_driver); module_acpi_driver(acpi_pcc_driver);

View File

@ -3261,7 +3261,7 @@ outwalk:
return result; return result;
} }
static int sony_nc_remove(struct acpi_device *device) static void sony_nc_remove(struct acpi_device *device)
{ {
struct sony_nc_value *item; struct sony_nc_value *item;
@ -3278,8 +3278,6 @@ static int sony_nc_remove(struct acpi_device *device)
sony_pf_remove(); sony_pf_remove();
sony_laptop_remove_input(); sony_laptop_remove_input();
dprintk(SONY_NC_DRIVER_NAME " removed.\n"); dprintk(SONY_NC_DRIVER_NAME " removed.\n");
return 0;
} }
static const struct acpi_device_id sony_device_ids[] = { static const struct acpi_device_id sony_device_ids[] = {
@ -4628,14 +4626,14 @@ found:
* ACPI driver * ACPI driver
* *
*****************/ *****************/
static int sony_pic_remove(struct acpi_device *device) static void sony_pic_remove(struct acpi_device *device)
{ {
struct sony_pic_ioport *io, *tmp_io; struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq; struct sony_pic_irq *irq, *tmp_irq;
if (sony_pic_disable(device)) { if (sony_pic_disable(device)) {
pr_err("Couldn't disable device\n"); pr_err("Couldn't disable device\n");
return -ENXIO; return;
} }
free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
@ -4665,7 +4663,6 @@ static int sony_pic_remove(struct acpi_device *device)
spic_dev.cur_irq = NULL; spic_dev.cur_irq = NULL;
dprintk(SONY_PIC_DRIVER_NAME " removed.\n"); dprintk(SONY_PIC_DRIVER_NAME " removed.\n");
return 0;
} }
static int sony_pic_add(struct acpi_device *device) static int sony_pic_add(struct acpi_device *device)

View File

@ -744,7 +744,7 @@ error:
} }
// Remove a System76 ACPI device // Remove a System76 ACPI device
static int system76_remove(struct acpi_device *acpi_dev) static void system76_remove(struct acpi_device *acpi_dev)
{ {
struct system76_data *data; struct system76_data *data;
@ -760,8 +760,6 @@ static int system76_remove(struct acpi_device *acpi_dev)
devm_led_classdev_unregister(&acpi_dev->dev, &data->kb_led); devm_led_classdev_unregister(&acpi_dev->dev, &data->kb_led);
system76_get(data, "FINI"); system76_get(data, "FINI");
return 0;
} }
static struct acpi_driver system76_driver = { static struct acpi_driver system76_driver = {

View File

@ -332,7 +332,7 @@ err_free:
return err; return err;
} }
static int topstar_acpi_remove(struct acpi_device *device) static void topstar_acpi_remove(struct acpi_device *device)
{ {
struct topstar_laptop *topstar = acpi_driver_data(device); struct topstar_laptop *topstar = acpi_driver_data(device);
@ -344,7 +344,6 @@ static int topstar_acpi_remove(struct acpi_device *device)
topstar_acpi_exit(topstar); topstar_acpi_exit(topstar);
kfree(topstar); kfree(topstar);
return 0;
} }
static const struct acpi_device_id topstar_device_ids[] = { static const struct acpi_device_id topstar_device_ids[] = {

View File

@ -3186,7 +3186,7 @@ static void print_supported_features(struct toshiba_acpi_dev *dev)
pr_cont("\n"); pr_cont("\n");
} }
static int toshiba_acpi_remove(struct acpi_device *acpi_dev) static void toshiba_acpi_remove(struct acpi_device *acpi_dev)
{ {
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
@ -3234,8 +3234,6 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
toshiba_acpi = NULL; toshiba_acpi = NULL;
kfree(dev); kfree(dev);
return 0;
} }
static const char *find_hci_method(acpi_handle handle) static const char *find_hci_method(acpi_handle handle)

View File

@ -36,7 +36,7 @@ struct toshiba_bluetooth_dev {
}; };
static int toshiba_bt_rfkill_add(struct acpi_device *device); static int toshiba_bt_rfkill_add(struct acpi_device *device);
static int toshiba_bt_rfkill_remove(struct acpi_device *device); static void toshiba_bt_rfkill_remove(struct acpi_device *device);
static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id bt_device_ids[] = { static const struct acpi_device_id bt_device_ids[] = {
@ -279,7 +279,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
return result; return result;
} }
static int toshiba_bt_rfkill_remove(struct acpi_device *device) static void toshiba_bt_rfkill_remove(struct acpi_device *device)
{ {
struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device);
@ -291,7 +291,7 @@ static int toshiba_bt_rfkill_remove(struct acpi_device *device)
kfree(bt_dev); kfree(bt_dev);
return toshiba_bluetooth_disable(device->handle); toshiba_bluetooth_disable(device->handle);
} }
module_acpi_driver(toshiba_bt_rfkill_driver); module_acpi_driver(toshiba_bt_rfkill_driver);

View File

@ -138,14 +138,12 @@ static void toshiba_haps_notify(struct acpi_device *device, u32 event)
event, 0); event, 0);
} }
static int toshiba_haps_remove(struct acpi_device *device) static void toshiba_haps_remove(struct acpi_device *device)
{ {
sysfs_remove_group(&device->dev.kobj, &haps_attr_group); sysfs_remove_group(&device->dev.kobj, &haps_attr_group);
if (toshiba_haps) if (toshiba_haps)
toshiba_haps = NULL; toshiba_haps = NULL;
return 0;
} }
/* Helper function */ /* Helper function */

View File

@ -103,10 +103,9 @@ static int wl_add(struct acpi_device *device)
return err; return err;
} }
static int wl_remove(struct acpi_device *device) static void wl_remove(struct acpi_device *device)
{ {
wireless_input_destroy(device); wireless_input_destroy(device);
return 0;
} }
static struct acpi_driver wl_driver = { static struct acpi_driver wl_driver = {

View File

@ -143,13 +143,12 @@ static int ebook_switch_add(struct acpi_device *device)
return error; return error;
} }
static int ebook_switch_remove(struct acpi_device *device) static void ebook_switch_remove(struct acpi_device *device)
{ {
struct ebook_switch *button = acpi_driver_data(device); struct ebook_switch *button = acpi_driver_data(device);
input_unregister_device(button->input); input_unregister_device(button->input);
kfree(button); kfree(button);
return 0;
} }
static struct acpi_driver xo15_ebook_driver = { static struct acpi_driver xo15_ebook_driver = {

View File

@ -148,14 +148,14 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
dev->dev.coherent_dma_mask = dev->dma_mask; dev->dev.coherent_dma_mask = dev->dma_mask;
dev->dev.release = &pnp_release_device; dev->dev.release = &pnp_release_device;
dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
dev_id = pnp_add_id(dev, pnpid); dev_id = pnp_add_id(dev, pnpid);
if (!dev_id) { if (!dev_id) {
kfree(dev); kfree(dev);
return NULL; return NULL;
} }
dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
return dev; return dev;
} }

View File

@ -182,7 +182,8 @@ static int __pnp_bus_suspend(struct device *dev, pm_message_t state)
return error; return error;
} }
if (pnp_can_disable(pnp_dev)) { /* can_write is necessary to be able to re-start the device on resume */
if (pnp_can_disable(pnp_dev) && pnp_can_write(pnp_dev)) {
error = pnp_stop_dev(pnp_dev); error = pnp_stop_dev(pnp_dev);
if (error) if (error)
return error; return error;

View File

@ -101,10 +101,9 @@ static int ptp_vmw_acpi_add(struct acpi_device *device)
return 0; return 0;
} }
static int ptp_vmw_acpi_remove(struct acpi_device *device) static void ptp_vmw_acpi_remove(struct acpi_device *device)
{ {
ptp_clock_unregister(ptp_vmw_clock); ptp_clock_unregister(ptp_vmw_clock);
return 0;
} }
static const struct acpi_device_id ptp_vmw_acpi_device_ids[] = { static const struct acpi_device_id ptp_vmw_acpi_device_ids[] = {

View File

@ -179,22 +179,20 @@ static int intel_menlow_memory_add(struct acpi_device *device)
} }
static int intel_menlow_memory_remove(struct acpi_device *device) static void intel_menlow_memory_remove(struct acpi_device *device)
{ {
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cdev;
if (!device) if (!device)
return -EINVAL; return;
cdev = acpi_driver_data(device); cdev = acpi_driver_data(device);
if (!cdev) if (!cdev)
return -EINVAL; return;
sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
sysfs_remove_link(&cdev->device.kobj, "device"); sysfs_remove_link(&cdev->device.kobj, "device");
thermal_cooling_device_unregister(cdev); thermal_cooling_device_unregister(cdev);
return 0;
} }
static const struct acpi_device_id intel_menlow_memory_ids[] = { static const struct acpi_device_id intel_menlow_memory_ids[] = {

View File

@ -193,13 +193,12 @@ static int apple_bl_add(struct acpi_device *dev)
return 0; return 0;
} }
static int apple_bl_remove(struct acpi_device *dev) static void apple_bl_remove(struct acpi_device *dev)
{ {
backlight_device_unregister(apple_backlight_device); backlight_device_unregister(apple_backlight_device);
release_region(hw_data->iostart, hw_data->iolen); release_region(hw_data->iostart, hw_data->iolen);
hw_data = NULL; hw_data = NULL;
return 0;
} }
static const struct acpi_device_id apple_bl_ids[] = { static const struct acpi_device_id apple_bl_ids[] = {

View File

@ -224,14 +224,12 @@ static int ni903x_acpi_add(struct acpi_device *device)
return 0; return 0;
} }
static int ni903x_acpi_remove(struct acpi_device *device) static void ni903x_acpi_remove(struct acpi_device *device)
{ {
struct ni903x_wdt *wdt = acpi_driver_data(device); struct ni903x_wdt *wdt = acpi_driver_data(device);
ni903x_wdd_stop(&wdt->wdd); ni903x_wdd_stop(&wdt->wdd);
watchdog_unregister_device(&wdt->wdd); watchdog_unregister_device(&wdt->wdd);
return 0;
} }
static const struct acpi_device_id ni903x_device_ids[] = { static const struct acpi_device_id ni903x_device_ids[] = {

View File

@ -122,7 +122,7 @@ static int acpi_pad_add(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_pad_remove(struct acpi_device *device) static void acpi_pad_remove(struct acpi_device *device)
{ {
mutex_lock(&xen_cpu_lock); mutex_lock(&xen_cpu_lock);
xen_acpi_pad_idle_cpus(0); xen_acpi_pad_idle_cpus(0);
@ -130,7 +130,6 @@ static int acpi_pad_remove(struct acpi_device *device)
acpi_remove_notify_handler(device->handle, acpi_remove_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY, acpi_pad_notify); ACPI_DEVICE_NOTIFY, acpi_pad_notify);
return 0;
} }
static const struct acpi_device_id pad_device_ids[] = { static const struct acpi_device_id pad_device_ids[] = {

View File

@ -190,6 +190,8 @@
#define ACPI_PRM_INPUT_BUFFER_SIZE 26 #define ACPI_PRM_INPUT_BUFFER_SIZE 26
#define ACPI_FFH_INPUT_BUFFER_SIZE 256
/* _sx_d and _sx_w control methods */ /* _sx_d and _sx_w control methods */
#define ACPI_NUM_sx_d_METHODS 4 #define ACPI_NUM_sx_d_METHODS 4

View File

@ -149,7 +149,7 @@ struct acpi_hotplug_context {
*/ */
typedef int (*acpi_op_add) (struct acpi_device * device); typedef int (*acpi_op_add) (struct acpi_device * device);
typedef int (*acpi_op_remove) (struct acpi_device * device); typedef void (*acpi_op_remove) (struct acpi_device *device);
typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
struct acpi_device_ops { struct acpi_device_ops {

View File

@ -12,7 +12,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */ /* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20220331 #define ACPI_CA_VERSION 0x20221020
#include <acpi/acconfig.h> #include <acpi/acconfig.h>
#include <acpi/actypes.h> #include <acpi/actypes.h>

View File

@ -45,6 +45,7 @@
#define ACPI_SIG_HMAT "HMAT" /* Heterogeneous Memory Attributes Table */ #define ACPI_SIG_HMAT "HMAT" /* Heterogeneous Memory Attributes Table */
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
#define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ #define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */
#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */
#define ACPI_SIG_S3PT "S3PT" /* S3 Performance (sub)Table */ #define ACPI_SIG_S3PT "S3PT" /* S3 Performance (sub)Table */
#define ACPI_SIG_PCCS "PCC" /* PCC Shared Memory Region */ #define ACPI_SIG_PCCS "PCC" /* PCC Shared Memory Region */
@ -303,12 +304,125 @@ struct acpi_table_boot {
u8 reserved[3]; u8 reserved[3];
}; };
/*******************************************************************************
*
* CDAT - Coherent Device Attribute Table
* Version 1
*
* Conforms to the "Coherent Device Attribute Table (CDAT) Specification
" (Revision 1.01, October 2020.)
*
******************************************************************************/
struct acpi_table_cdat {
u32 length; /* Length of table in bytes, including this header */
u8 revision; /* ACPI Specification minor version number */
u8 checksum; /* To make sum of entire table == 0 */
u8 reserved[6];
u32 sequence; /* Used to detect runtime CDAT table changes */
};
/* CDAT common subtable header */
struct acpi_cdat_header {
u8 type;
u8 reserved;
u16 length;
};
/* Values for Type field above */
enum acpi_cdat_type {
ACPI_CDAT_TYPE_DSMAS = 0,
ACPI_CDAT_TYPE_DSLBIS = 1,
ACPI_CDAT_TYPE_DSMSCIS = 2,
ACPI_CDAT_TYPE_DSIS = 3,
ACPI_CDAT_TYPE_DSEMTS = 4,
ACPI_CDAT_TYPE_SSLBIS = 5,
ACPI_CDAT_TYPE_RESERVED = 6 /* 6 through 0xFF are reserved */
};
/* Subtable 0: Device Scoped Memory Affinity Structure (DSMAS) */
struct acpi_cadt_dsmas {
u8 dsmad_handle;
u8 flags;
u16 reserved;
u64 dpa_base_address;
u64 dpa_length;
};
/* Flags for subtable above */
#define ACPI_CEDT_DSMAS_NON_VOLATILE (1 << 2)
/* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
struct acpi_cdat_dslbis {
u8 handle;
u8 flags; /* If Handle matches a DSMAS handle, the definition of this field matches
* Flags field in HMAT System Locality Latency */
u8 data_type;
u8 reserved;
u64 entry_base_unit;
u16 entry[3];
u16 reserved2;
};
/* Subtable 2: Device Scoped Memory Side Cache Information Structure (DSMSCIS) */
struct acpi_cdat_dsmscis {
u8 dsmas_handle;
u8 reserved[3];
u64 side_cache_size;
u32 cache_attributes;
};
/* Subtable 3: Device Scoped Initiator Structure (DSIS) */
struct acpi_cdat_dsis {
u8 flags;
u8 handle;
u16 reserved;
};
/* Flags for above subtable */
#define ACPI_CDAT_DSIS_MEM_ATTACHED (1 << 0)
/* Subtable 4: Device Scoped EFI Memory Type Structure (DSEMTS) */
struct acpi_cdat_dsemts {
u8 dsmas_handle;
u8 memory_type;
u16 reserved;
u64 dpa_offset;
u64 range_length;
};
/* Subtable 5: Switch Scoped Latency and Bandwidth Information Structure (SSLBIS) */
struct acpi_cdat_sslbis {
u8 data_type;
u8 reserved[3];
u64 entry_base_unit;
};
/* Sub-subtable for above, sslbe_entries field */
struct acpi_cdat_sslbe {
u16 portx_id;
u16 porty_id;
u16 latency_or_bandwidth;
u16 reserved;
};
/******************************************************************************* /*******************************************************************************
* *
* CEDT - CXL Early Discovery Table * CEDT - CXL Early Discovery Table
* Version 1 * Version 1
* *
* Conforms to the "CXL Early Discovery Table" (CXL 2.0) * Conforms to the "CXL Early Discovery Table" (CXL 2.0, October 2020)
* *
******************************************************************************/ ******************************************************************************/
@ -329,7 +443,9 @@ struct acpi_cedt_header {
enum acpi_cedt_type { enum acpi_cedt_type {
ACPI_CEDT_TYPE_CHBS = 0, ACPI_CEDT_TYPE_CHBS = 0,
ACPI_CEDT_TYPE_CFMWS = 1, ACPI_CEDT_TYPE_CFMWS = 1,
ACPI_CEDT_TYPE_RESERVED = 2, ACPI_CEDT_TYPE_CXIMS = 2,
ACPI_CEDT_TYPE_RDPAS = 3,
ACPI_CEDT_TYPE_RESERVED = 4,
}; };
/* Values for version field above */ /* Values for version field above */
@ -380,6 +496,7 @@ struct acpi_cedt_cfmws_target_element {
/* Values for Interleave Arithmetic field above */ /* Values for Interleave Arithmetic field above */
#define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0) #define ACPI_CEDT_CFMWS_ARITHMETIC_MODULO (0)
#define ACPI_CEDT_CFMWS_ARITHMETIC_XOR (1)
/* Values for Restrictions field above */ /* Values for Restrictions field above */
@ -389,6 +506,36 @@ struct acpi_cedt_cfmws_target_element {
#define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3) #define ACPI_CEDT_CFMWS_RESTRICT_PMEM (1<<3)
#define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4) #define ACPI_CEDT_CFMWS_RESTRICT_FIXED (1<<4)
/* 2: CXL XOR Interleave Math Structure */
struct acpi_cedt_cxims {
struct acpi_cedt_header header;
u16 reserved1;
u8 hbig;
u8 nr_xormaps;
u64 xormap_list[];
};
/* 3: CXL RCEC Downstream Port Association Structure */
struct acpi_cedt_rdpas {
struct acpi_cedt_header header;
u8 reserved1;
u16 length;
u16 segment;
u16 bdf;
u8 protocol;
u64 address;
};
/* Masks for bdf field above */
#define ACPI_CEDT_RDPAS_BUS_MASK 0xff00
#define ACPI_CEDT_RDPAS_DEVICE_MASK 0x00f8
#define ACPI_CEDT_RDPAS_FUNCTION_MASK 0x0007
#define ACPI_CEDT_RDPAS_PROTOCOL_IO (0)
#define ACPI_CEDT_RDPAS_PROTOCOL_CACHEMEM (1)
/******************************************************************************* /*******************************************************************************
* *
* CPEP - Corrected Platform Error Polling table (ACPI 4.0) * CPEP - Corrected Platform Error Polling table (ACPI 4.0)

View File

@ -27,6 +27,8 @@
#define ACPI_SIG_AGDI "AGDI" /* Arm Generic Diagnostic Dump and Reset Device Interface */ #define ACPI_SIG_AGDI "AGDI" /* Arm Generic Diagnostic Dump and Reset Device Interface */
#define ACPI_SIG_APMT "APMT" /* Arm Performance Monitoring Unit table */ #define ACPI_SIG_APMT "APMT" /* Arm Performance Monitoring Unit table */
#define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */ #define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */
#define ACPI_SIG_CCEL "CCEL" /* CC Event Log Table */
#define ACPI_SIG_CDAT "CDAT" /* Coherent Device Attribute Table */
#define ACPI_SIG_IORT "IORT" /* IO Remapping Table */ #define ACPI_SIG_IORT "IORT" /* IO Remapping Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
#define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */ #define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */
@ -34,7 +36,6 @@
#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */
#define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */ #define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */
#define ACPI_SIG_MPST "MPST" /* Memory Power State Table */ #define ACPI_SIG_MPST "MPST" /* Memory Power State Table */
#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */
#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */ #define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */
#define ACPI_SIG_NFIT "NFIT" /* NVDIMM Firmware Interface Table */ #define ACPI_SIG_NFIT "NFIT" /* NVDIMM Firmware Interface Table */
#define ACPI_SIG_NHLT "NHLT" /* Non HD Audio Link Table */ #define ACPI_SIG_NHLT "NHLT" /* Non HD Audio Link Table */
@ -352,12 +353,29 @@ struct acpi_table_bdat {
struct acpi_generic_address gas; struct acpi_generic_address gas;
}; };
/*******************************************************************************
*
* CCEL - CC-Event Log
* From: "Guest-Host-Communication Interface (GHCI) for Intel
* Trust Domain Extensions (Intel TDX)". Feb 2022
*
******************************************************************************/
struct acpi_table_ccel {
struct acpi_table_header header; /* Common ACPI table header */
u8 CCtype;
u8 Ccsub_type;
u16 reserved;
u64 log_area_minimum_length;
u64 log_area_start_address;
};
/******************************************************************************* /*******************************************************************************
* *
* IORT - IO Remapping Table * IORT - IO Remapping Table
* *
* Conforms to "IO Remapping Table System Software on ARM Platforms", * Conforms to "IO Remapping Table System Software on ARM Platforms",
* Document number: ARM DEN 0049E.d, Feb 2022 * Document number: ARM DEN 0049E.e, Sep 2022
* *
******************************************************************************/ ******************************************************************************/
@ -528,6 +546,7 @@ struct acpi_iort_smmu_v3 {
#define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE (1) #define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE (1)
#define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE (3<<1) #define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE (3<<1)
#define ACPI_IORT_SMMU_V3_PXM_VALID (1<<3) #define ACPI_IORT_SMMU_V3_PXM_VALID (1<<3)
#define ACPI_IORT_SMMU_V3_DEVICEID_VALID (1<<4)
struct acpi_iort_pmcg { struct acpi_iort_pmcg {
u64 page0_base_address; u64 page0_base_address;
@ -865,7 +884,14 @@ enum acpi_madt_type {
ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14, ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15, ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
ACPI_MADT_TYPE_MULTIPROC_WAKEUP = 16, ACPI_MADT_TYPE_MULTIPROC_WAKEUP = 16,
ACPI_MADT_TYPE_RESERVED = 17, /* 17 to 0x7F are reserved */ ACPI_MADT_TYPE_CORE_PIC = 17,
ACPI_MADT_TYPE_LIO_PIC = 18,
ACPI_MADT_TYPE_HT_PIC = 19,
ACPI_MADT_TYPE_EIO_PIC = 20,
ACPI_MADT_TYPE_MSI_PIC = 21,
ACPI_MADT_TYPE_BIO_PIC = 22,
ACPI_MADT_TYPE_LPC_PIC = 23,
ACPI_MADT_TYPE_RESERVED = 24, /* 24 to 0x7F are reserved */
ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */ ACPI_MADT_TYPE_OEM_RESERVED = 0x80 /* 0x80 to 0xFF are reserved for OEM use */
}; };
@ -1096,7 +1122,135 @@ struct acpi_madt_multiproc_wakeup_mailbox {
#define ACPI_MP_WAKE_COMMAND_WAKEUP 1 #define ACPI_MP_WAKE_COMMAND_WAKEUP 1
/* 17: OEM data */ /* 17: CPU Core Interrupt Controller (ACPI 6.5) */
struct acpi_madt_core_pic {
struct acpi_subtable_header header;
u8 version;
u32 processor_id;
u32 core_id;
u32 flags;
};
/* Values for Version field above */
enum acpi_madt_core_pic_version {
ACPI_MADT_CORE_PIC_VERSION_NONE = 0,
ACPI_MADT_CORE_PIC_VERSION_V1 = 1,
ACPI_MADT_CORE_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 18: Legacy I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_lio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[2];
u32 cascade_map[2];
};
/* Values for Version field above */
enum acpi_madt_lio_pic_version {
ACPI_MADT_LIO_PIC_VERSION_NONE = 0,
ACPI_MADT_LIO_PIC_VERSION_V1 = 1,
ACPI_MADT_LIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 19: HT Interrupt Controller (ACPI 6.5) */
struct acpi_madt_ht_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade[8];
};
/* Values for Version field above */
enum acpi_madt_ht_pic_version {
ACPI_MADT_HT_PIC_VERSION_NONE = 0,
ACPI_MADT_HT_PIC_VERSION_V1 = 1,
ACPI_MADT_HT_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 20: Extend I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_eio_pic {
struct acpi_subtable_header header;
u8 version;
u8 cascade;
u8 node;
u64 node_map;
};
/* Values for Version field above */
enum acpi_madt_eio_pic_version {
ACPI_MADT_EIO_PIC_VERSION_NONE = 0,
ACPI_MADT_EIO_PIC_VERSION_V1 = 1,
ACPI_MADT_EIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 21: MSI Interrupt Controller (ACPI 6.5) */
struct acpi_madt_msi_pic {
struct acpi_subtable_header header;
u8 version;
u64 msg_address;
u32 start;
u32 count;
};
/* Values for Version field above */
enum acpi_madt_msi_pic_version {
ACPI_MADT_MSI_PIC_VERSION_NONE = 0,
ACPI_MADT_MSI_PIC_VERSION_V1 = 1,
ACPI_MADT_MSI_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 22: Bridge I/O Interrupt Controller (ACPI 6.5) */
struct acpi_madt_bio_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u16 id;
u16 gsi_base;
};
/* Values for Version field above */
enum acpi_madt_bio_pic_version {
ACPI_MADT_BIO_PIC_VERSION_NONE = 0,
ACPI_MADT_BIO_PIC_VERSION_V1 = 1,
ACPI_MADT_BIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 23: LPC Interrupt Controller (ACPI 6.5) */
struct acpi_madt_lpc_pic {
struct acpi_subtable_header header;
u8 version;
u64 address;
u16 size;
u8 cascade;
};
/* Values for Version field above */
enum acpi_madt_lpc_pic_version {
ACPI_MADT_LPC_PIC_VERSION_NONE = 0,
ACPI_MADT_LPC_PIC_VERSION_V1 = 1,
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
};
/* 80: OEM data */
struct acpi_madt_oem_data { struct acpi_madt_oem_data {
u8 oem_data[0]; u8 oem_data[0];

Some files were not shown because too many files have changed in this diff Show More