Commit d4b671d4 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ACPI updates from Rafael Wysocki:
 "These fix issues, add new quirks, rearrange the IRQ override quirk
  definitions, add new helpers and switch over code to using them,
  rework a couple of interfaces to be more flexible, eliminate strncpy()
  usage from PNP, extend the ACPI PCC mailbox driver and clean up code.

  This is based on ACPI thermal driver changes that are present in the
  thermal control updates for 6.7-rc1 pull request (they are depended on
  by the ACPI utilities updates). However, the ACPI thermal driver
  changes are not included in the list of specific ACPI changes below.

  Specifics:

   - Add symbol definitions related to CDAT to the ACPICA code (Dave
     Jiang)

   - Use the acpi_device_is_present() helper in more places and rename
     acpi_scan_device_not_present() to be about enumeration (James
     Morse)

   - Add __printf format attribute to acpi_os_vprintf() (Su Hui)

   - Clean up departures from kernel coding style in the low-level
     interface for ACPICA (Jonathan Bergh)

   - Replace strncpy() with strscpy() in acpi_osi_setup() (Justin Stitt)

   - Fail FPDT parsing on zero length records and add proper handling
     for fpdt_process_subtable() to acpi_init_fpdt() (Vasily Khoruzhick)

   - Rework acpi_handle_list handling so as to manage it dynamically,
     including size computation (Rafael Wysocki)

   - Clean up ACPI utilities code so as to make it follow the kernel
     coding style (Jonathan Bergh)

   - Consolidate IRQ trigger-type override DMI tables and drop .ident
     values from dmi_system_id tables used for ACPI resources management
     quirks (Hans de Goede)

   - Add ACPI IRQ override for TongFang GMxXGxx (Werner Sembach)

   - Allow _DSD buffer data only for byte accessors and document the
     _DSD data buffer GUID (Andy Shevchenko)

   - Drop BayTrail and Lynxpoint pinctrl device IDs from the ACPI LPSS
     driver, because it does not need them (Raag Jadav)

   - Add acpi_backlight=vendor quirk for Toshiba Portégé R100 (Ondrej
     Zary)

   - Add "vendor" backlight quirks for 3 Lenovo x86 Android tablets
     (Hans de Goede)

   - Move Xiaomi Mi Pad 2 backlight quirk to its own section (Hans de
     Goede)

   - Annotate struct prm_module_info with __counted_by (Kees Cook)

   - Fix AER info corruption in aer_recover_queue() when error status
     data has multiple sections (Shiju Jose)

   - Make APEI use ERST maximum execution time for slow devices (Jeshua
     Smith)

   - Add support for platform notification handling to the PCC mailbox
     driver and modify it to support shared interrupts for multiple
     subspaces (Huisong Li)

   - Define common macros to use when referring to various bitfields in
     the PCC generic communications channel command and status fields
     and use them in some drivers (Sudeep Holla)

   - Add EC GPE detection quirk for HP 250 G7 Notebook PC (Jonathan
     Denose)

   - Fix and clean up create_pnp_modalias() and create_of_modalias()
     (Christophe JAILLET)

   - Modify 2 pieces of code to use acpi_evaluate_dsm_typed() (Andy
     Shevchenko)

   - Define acpi_dev_uid_match() for matching _UID and use it in several
     places (Raag Jadav)

   - Use acpi_device_uid() for fetching _UID in 2 places (Raag Jadav)

   - Add context argument to acpi_dev_install_notify_handler() (Rafael
     Wysocki)

   - Clarify ACPI bus concepts in the ACPI device enumeration
     documentation (Rafael Wysocki)

   - Switch over the ACPI AC and ACPI PAD drivers to using the platform
     driver interface which, is more logically consistent than binding a
     driver directly to an ACPI device object, and clean them up (Michal
     Wilczynski)

   - Replace strncpy() in the PNP code with either memcpy() or strscpy()
     as appropriate (Justin Stitt)

   - Clean up coding style in pnp.h (GuoHua Cheng)"

* tag 'acpi-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (54 commits)
  ACPI: resource: Do IRQ override on TongFang GMxXGxx
  perf: arm_cspmu: use acpi_dev_hid_uid_match() for matching _HID and _UID
  ACPI: EC: Add quirk for HP 250 G7 Notebook PC
  ACPI: x86: use acpi_dev_uid_match() for matching _UID
  ACPI: utils: use acpi_dev_uid_match() for matching _UID
  pinctrl: intel: use acpi_dev_uid_match() for matching _UID
  ACPI: utils: Introduce acpi_dev_uid_match() for matching _UID
  ACPI: sysfs: Clean up create_pnp_modalias() and create_of_modalias()
  ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias()
  ACPI: acpi_pad: Rename ACPI device from device to adev
  ACPI: acpi_pad: Use dev groups for sysfs
  ACPI: acpi_pad: Replace acpi_driver with platform_driver
  ACPI: APEI: Use ERST timeout for slow devices
  ACPI: scan: Rename acpi_scan_device_not_present() to be about enumeration
  PNP: replace deprecated strncpy() with memcpy()
  PNP: ACPI: replace deprecated strncpy() with strscpy()
  perf: qcom: use acpi_device_uid() for fetching _UID
  ACPI: sysfs: use acpi_device_uid() for fetching _UID
  ACPI: scan: Use the acpi_device_is_present() helper in more places
  ACPI: AC: Rename ACPI device from device to adev
  ...
parents 4ac4677f f4cb34a7
...@@ -64,6 +64,49 @@ If the driver needs to perform more complex initialization like getting and ...@@ -64,6 +64,49 @@ If the driver needs to perform more complex initialization like getting and
configuring GPIOs it can get its ACPI handle and extract this information configuring GPIOs it can get its ACPI handle and extract this information
from ACPI tables. from ACPI tables.
ACPI device objects
===================
Generally speaking, there are two categories of devices in a system in which
ACPI is used as an interface between the platform firmware and the OS: Devices
that can be discovered and enumerated natively, through a protocol defined for
the specific bus that they are on (for example, configuration space in PCI),
without the platform firmware assistance, and devices that need to be described
by the platform firmware so that they can be discovered. Still, for any device
known to the platform firmware, regardless of which category it falls into,
there can be a corresponding ACPI device object in the ACPI Namespace in which
case the Linux kernel will create a struct acpi_device object based on it for
that device.
Those struct acpi_device objects are never used for binding drivers to natively
discoverable devices, because they are represented by other types of device
objects (for example, struct pci_dev for PCI devices) that are bound to by
device drivers (the corresponding struct acpi_device object is then used as
an additional source of information on the configuration of the given device).
Moreover, the core ACPI device enumeration code creates struct platform_device
objects for the majority of devices that are discovered and enumerated with the
help of the platform firmware and those platform device objects can be bound to
by platform drivers in direct analogy with the natively enumerable devices
case. Therefore it is logically inconsistent and so generally invalid to bind
drivers to struct acpi_device objects, including drivers for devices that are
discovered with the help of the platform firmware.
Historically, ACPI drivers that bound directly to struct acpi_device objects
were implemented for some devices enumerated with the help of the platform
firmware, but this is not recommended for any new drivers. As explained above,
platform device objects are created for those devices as a rule (with a few
exceptions that are not relevant here) and so platform drivers should be used
for handling them, even though the corresponding ACPI device objects are the
only source of device configuration information in that case.
For every device having a corresponding struct acpi_device object, the pointer
to it is returned by the ACPI_COMPANION() macro, so it is always possible to
get to the device configuration information stored in the ACPI device object
this way. Accordingly, struct acpi_device can be regarded as a part of the
interface between the kernel and the ACPI Namespace, whereas device objects of
other types (for example, struct pci_dev or struct platform_device) are used
for interacting with the rest of the system.
DMA support DMA support
=========== ===========
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/string_choices.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <acpi/battery.h> #include <acpi/battery.h>
...@@ -32,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh"); ...@@ -32,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI AC Adapter Driver"); 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_probe(struct platform_device *pdev);
static void acpi_ac_remove(struct acpi_device *device); static void acpi_ac_remove(struct platform_device *pdev);
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data); static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
static const struct acpi_device_id ac_device_ids[] = { static const struct acpi_device_id ac_device_ids[] = {
...@@ -50,17 +52,6 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); ...@@ -50,17 +52,6 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
static int ac_sleep_before_get_state_ms; static int ac_sleep_before_get_state_ms;
static int ac_only; static int ac_only;
static struct acpi_driver acpi_ac_driver = {
.name = "ac",
.class = ACPI_AC_CLASS,
.ids = ac_device_ids,
.ops = {
.add = acpi_ac_add,
.remove = acpi_ac_remove,
},
.drv.pm = &acpi_ac_pm,
};
struct acpi_ac { struct acpi_ac {
struct power_supply *charger; struct power_supply *charger;
struct power_supply_desc charger_desc; struct power_supply_desc charger_desc;
...@@ -128,15 +119,12 @@ static enum power_supply_property ac_props[] = { ...@@ -128,15 +119,12 @@ static enum power_supply_property ac_props[] = {
/* Driver Model */ /* Driver Model */
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
{ {
struct acpi_device *device = data; struct acpi_ac *ac = data;
struct acpi_ac *ac = acpi_driver_data(device); struct acpi_device *adev = ac->device;
if (!ac)
return;
switch (event) { switch (event) {
default: default:
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", acpi_handle_debug(adev->handle, "Unsupported event [0x%x]\n",
event); event);
fallthrough; fallthrough;
case ACPI_AC_NOTIFY_STATUS: case ACPI_AC_NOTIFY_STATUS:
...@@ -153,10 +141,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) ...@@ -153,10 +141,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
msleep(ac_sleep_before_get_state_ms); msleep(ac_sleep_before_get_state_ms);
acpi_ac_get_state(ac); acpi_ac_get_state(ac);
acpi_bus_generate_netlink_event(device->pnp.device_class, acpi_bus_generate_netlink_event(adev->pnp.device_class,
dev_name(&device->dev), event, dev_name(&adev->dev), event,
(u32) ac->state); (u32) ac->state);
acpi_notifier_call_chain(device, event, (u32) ac->state); acpi_notifier_call_chain(adev, event, (u32) ac->state);
kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
} }
} }
...@@ -213,24 +201,22 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = { ...@@ -213,24 +201,22 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = {
{}, {},
}; };
static int acpi_ac_add(struct acpi_device *device) static int acpi_ac_probe(struct platform_device *pdev)
{ {
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
struct power_supply_config psy_cfg = {}; struct power_supply_config psy_cfg = {};
int result = 0; struct acpi_ac *ac;
struct acpi_ac *ac = NULL; int result;
if (!device)
return -EINVAL;
ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
if (!ac) if (!ac)
return -ENOMEM; return -ENOMEM;
ac->device = device; ac->device = adev;
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_AC_CLASS); strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
device->driver_data = ac;
platform_set_drvdata(pdev, ac);
result = acpi_ac_get_state(ac); result = acpi_ac_get_state(ac);
if (result) if (result)
...@@ -238,26 +224,26 @@ static int acpi_ac_add(struct acpi_device *device) ...@@ -238,26 +224,26 @@ static int acpi_ac_add(struct acpi_device *device)
psy_cfg.drv_data = ac; psy_cfg.drv_data = ac;
ac->charger_desc.name = acpi_device_bid(device); ac->charger_desc.name = acpi_device_bid(adev);
ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS; ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger_desc.properties = ac_props; ac->charger_desc.properties = ac_props;
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props); ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
ac->charger_desc.get_property = get_ac_property; ac->charger_desc.get_property = get_ac_property;
ac->charger = power_supply_register(&ac->device->dev, ac->charger = power_supply_register(&pdev->dev,
&ac->charger_desc, &psy_cfg); &ac->charger_desc, &psy_cfg);
if (IS_ERR(ac->charger)) { if (IS_ERR(ac->charger)) {
result = PTR_ERR(ac->charger); result = PTR_ERR(ac->charger);
goto err_release_ac; goto err_release_ac;
} }
pr_info("%s [%s] (%s)\n", acpi_device_name(device), pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
acpi_device_bid(device), ac->state ? "on-line" : "off-line"); acpi_device_bid(adev), str_on_off(ac->state));
ac->battery_nb.notifier_call = acpi_ac_battery_notify; ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(&ac->battery_nb); register_acpi_notifier(&ac->battery_nb);
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY, result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
acpi_ac_notify); acpi_ac_notify, ac);
if (result) if (result)
goto err_unregister; goto err_unregister;
...@@ -275,16 +261,9 @@ static int acpi_ac_add(struct acpi_device *device) ...@@ -275,16 +261,9 @@ static int acpi_ac_add(struct acpi_device *device)
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int acpi_ac_resume(struct device *dev) static int acpi_ac_resume(struct device *dev)
{ {
struct acpi_ac *ac; struct acpi_ac *ac = dev_get_drvdata(dev);
unsigned int old_state; unsigned int old_state;
if (!dev)
return -EINVAL;
ac = acpi_driver_data(to_acpi_device(dev));
if (!ac)
return -EINVAL;
old_state = ac->state; old_state = ac->state;
if (acpi_ac_get_state(ac)) if (acpi_ac_get_state(ac))
return 0; return 0;
...@@ -297,16 +276,11 @@ static int acpi_ac_resume(struct device *dev) ...@@ -297,16 +276,11 @@ static int acpi_ac_resume(struct device *dev)
#define acpi_ac_resume NULL #define acpi_ac_resume NULL
#endif #endif
static void acpi_ac_remove(struct acpi_device *device) static void acpi_ac_remove(struct platform_device *pdev)
{ {
struct acpi_ac *ac = NULL; struct acpi_ac *ac = platform_get_drvdata(pdev);
if (!device || !acpi_driver_data(device)) acpi_dev_remove_notify_handler(ac->device, ACPI_ALL_NOTIFY,
return;
ac = acpi_driver_data(device);
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
acpi_ac_notify); acpi_ac_notify);
power_supply_unregister(ac->charger); power_supply_unregister(ac->charger);
unregister_acpi_notifier(&ac->battery_nb); unregister_acpi_notifier(&ac->battery_nb);
...@@ -314,6 +288,16 @@ static void acpi_ac_remove(struct acpi_device *device) ...@@ -314,6 +288,16 @@ static void acpi_ac_remove(struct acpi_device *device)
kfree(ac); kfree(ac);
} }
static struct platform_driver acpi_ac_driver = {
.probe = acpi_ac_probe,
.remove_new = acpi_ac_remove,
.driver = {
.name = "ac",
.acpi_match_table = ac_device_ids,
.pm = &acpi_ac_pm,
},
};
static int __init acpi_ac_init(void) static int __init acpi_ac_init(void)
{ {
int result; int result;
...@@ -326,7 +310,7 @@ static int __init acpi_ac_init(void) ...@@ -326,7 +310,7 @@ static int __init acpi_ac_init(void)
dmi_check_system(ac_dmi_table); dmi_check_system(ac_dmi_table);
result = acpi_bus_register_driver(&acpi_ac_driver); result = platform_driver_register(&acpi_ac_driver);
if (result < 0) if (result < 0)
return -ENODEV; return -ENODEV;
...@@ -335,7 +319,7 @@ static int __init acpi_ac_init(void) ...@@ -335,7 +319,7 @@ static int __init acpi_ac_init(void)
static void __exit acpi_ac_exit(void) static void __exit acpi_ac_exit(void)
{ {
acpi_bus_unregister_driver(&acpi_ac_driver); platform_driver_unregister(&acpi_ac_driver);
} }
module_init(acpi_ac_init); module_init(acpi_ac_init);
module_exit(acpi_ac_exit); module_exit(acpi_ac_exit);
...@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) ...@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
record_header = (void *)subtable_header + offset; record_header = (void *)subtable_header + offset;
offset += record_header->length; offset += record_header->length;
if (!record_header->length) {
pr_err(FW_BUG "Zero-length record found in FPTD.\n");
result = -EINVAL;
goto err;
}
switch (record_header->type) { switch (record_header->type) {
case RECORD_S3_RESUME: case RECORD_S3_RESUME:
if (subtable_type != SUBTABLE_S3PT) { if (subtable_type != SUBTABLE_S3PT) {
pr_err(FW_BUG "Invalid record %d for subtable %s\n", pr_err(FW_BUG "Invalid record %d for subtable %s\n",
record_header->type, signature); record_header->type, signature);
return -EINVAL; result = -EINVAL;
goto err;
} }
if (record_resume) { if (record_resume) {
pr_err("Duplicate resume performance record found.\n"); pr_err("Duplicate resume performance record found.\n");
...@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) ...@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
record_resume = (struct resume_performance_record *)record_header; record_resume = (struct resume_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &resume_attr_group); result = sysfs_create_group(fpdt_kobj, &resume_attr_group);
if (result) if (result)
return result; goto err;
break; break;
case RECORD_S3_SUSPEND: case RECORD_S3_SUSPEND:
if (subtable_type != SUBTABLE_S3PT) { if (subtable_type != SUBTABLE_S3PT) {
...@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) ...@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
record_suspend = (struct suspend_performance_record *)record_header; record_suspend = (struct suspend_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &suspend_attr_group); result = sysfs_create_group(fpdt_kobj, &suspend_attr_group);
if (result) if (result)
return result; goto err;
break; break;
case RECORD_BOOT: case RECORD_BOOT:
if (subtable_type != SUBTABLE_FBPT) { if (subtable_type != SUBTABLE_FBPT) {
pr_err(FW_BUG "Invalid %d for subtable %s\n", pr_err(FW_BUG "Invalid %d for subtable %s\n",
record_header->type, signature); record_header->type, signature);
return -EINVAL; result = -EINVAL;
goto err;
} }
if (record_boot) { if (record_boot) {
pr_err("Duplicate boot performance record found.\n"); pr_err("Duplicate boot performance record found.\n");
...@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) ...@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
record_boot = (struct boot_performance_record *)record_header; record_boot = (struct boot_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &boot_attr_group); result = sysfs_create_group(fpdt_kobj, &boot_attr_group);
if (result) if (result)
return result; goto err;
break; break;
default: default:
...@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) ...@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
} }
} }
return 0; return 0;
err:
if (record_boot)
sysfs_remove_group(fpdt_kobj, &boot_attr_group);
if (record_suspend)
sysfs_remove_group(fpdt_kobj, &suspend_attr_group);
if (record_resume)
sysfs_remove_group(fpdt_kobj, &resume_attr_group);
return result;
} }
static int __init acpi_init_fpdt(void) static int __init acpi_init_fpdt(void)
...@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void) ...@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void)
struct acpi_table_header *header; struct acpi_table_header *header;
struct fpdt_subtable_entry *subtable; struct fpdt_subtable_entry *subtable;
u32 offset = sizeof(*header); u32 offset = sizeof(*header);
int result;
status = acpi_get_table(ACPI_SIG_FPDT, 0, &header); status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);
...@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void) ...@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void)
fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj); fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
if (!fpdt_kobj) { if (!fpdt_kobj) {
acpi_put_table(header); result = -ENOMEM;
return -ENOMEM; goto err_nomem;
} }
while (offset < header->length) { while (offset < header->length) {
...@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void) ...@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void)
switch (subtable->type) { switch (subtable->type) {
case SUBTABLE_FBPT: case SUBTABLE_FBPT:
case SUBTABLE_S3PT: case SUBTABLE_S3PT:
fpdt_process_subtable(subtable->address, result = fpdt_process_subtable(subtable->address,
subtable->type); subtable->type);
if (result)
goto err_subtable;
break; break;
default: default:
/* Other types are reserved in ACPI 6.4 spec. */ /* Other types are reserved in ACPI 6.4 spec. */
...@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void) ...@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void)
offset += sizeof(*subtable); offset += sizeof(*subtable);
} }
return 0; return 0;
err_subtable:
kobject_put(fpdt_kobj);
err_nomem:
acpi_put_table(header);
return result;
} }
fs_initcall(acpi_init_fpdt); fs_initcall(acpi_init_fpdt);
...@@ -368,7 +368,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { ...@@ -368,7 +368,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) }, { "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) },
{ "INT33C5", LPSS_ADDR(lpt_uart_dev_desc) }, { "INT33C5", LPSS_ADDR(lpt_uart_dev_desc) },
{ "INT33C6", LPSS_ADDR(lpt_sdio_dev_desc) }, { "INT33C6", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT33C7", },
/* BayTrail LPSS devices */ /* BayTrail LPSS devices */
{ "80860F09", LPSS_ADDR(byt_pwm_dev_desc) }, { "80860F09", LPSS_ADDR(byt_pwm_dev_desc) },
...@@ -376,8 +375,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { ...@@ -376,8 +375,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "80860F0E", LPSS_ADDR(byt_spi_dev_desc) }, { "80860F0E", LPSS_ADDR(byt_spi_dev_desc) },
{ "80860F14", LPSS_ADDR(byt_sdio_dev_desc) }, { "80860F14", LPSS_ADDR(byt_sdio_dev_desc) },
{ "80860F41", LPSS_ADDR(byt_i2c_dev_desc) }, { "80860F41", LPSS_ADDR(byt_i2c_dev_desc) },
{ "INT33B2", },
{ "INT33FC", },
/* Braswell LPSS devices */ /* Braswell LPSS devices */
{ "80862286", LPSS_ADDR(lpss_dma_desc) }, { "80862286", LPSS_ADDR(lpss_dma_desc) },
...@@ -396,7 +393,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { ...@@ -396,7 +393,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INT3434", LPSS_ADDR(lpt_uart_dev_desc) }, { "INT3434", LPSS_ADDR(lpt_uart_dev_desc) },
{ "INT3435", LPSS_ADDR(lpt_uart_dev_desc) }, { "INT3435", LPSS_ADDR(lpt_uart_dev_desc) },
{ "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) }, { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT3437", },
/* Wildcat Point LPSS devices */ /* Wildcat Point LPSS devices */
{ "INT3438", LPSS_ADDR(lpt_spi_dev_desc) }, { "INT3438", LPSS_ADDR(lpt_spi_dev_desc) },
...@@ -578,6 +574,7 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) ...@@ -578,6 +574,7 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
{ {
struct acpi_handle_list dep_devices; struct acpi_handle_list dep_devices;
acpi_status status; acpi_status status;
bool ret = false;
int i; int i;
if (!acpi_has_method(adev->handle, "_DEP")) if (!acpi_has_method(adev->handle, "_DEP"))
...@@ -591,11 +588,14 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) ...@@ -591,11 +588,14 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
} }
for (i = 0; i < dep_devices.count; i++) { for (i = 0; i < dep_devices.count; i++) {
if (dep_devices.handles[i] == handle) if (dep_devices.handles[i] == handle) {
return true; ret = true;
break;
}
} }
return false; acpi_handle_list_free(&dep_devices);
return ret;
} }
static void acpi_lpss_link_consumer(struct device *dev1, static void acpi_lpss_link_consumer(struct device *dev1,
...@@ -657,10 +657,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev, ...@@ -657,10 +657,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
int ret; int ret;
dev_desc = (const struct lpss_device_desc *)id->driver_data; dev_desc = (const struct lpss_device_desc *)id->driver_data;
if (!dev_desc) { if (!dev_desc)
pdev = acpi_create_platform_device(adev, NULL); return -EINVAL;
return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
}
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) if (!pdata)
return -ENOMEM; return -ENOMEM;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <asm/mwait.h> #include <asm/mwait.h>
#include <xen/xen.h> #include <xen/xen.h>
...@@ -336,33 +337,14 @@ static ssize_t idlecpus_show(struct device *dev, ...@@ -336,33 +337,14 @@ static ssize_t idlecpus_show(struct device *dev,
static DEVICE_ATTR_RW(idlecpus); static DEVICE_ATTR_RW(idlecpus);
static int acpi_pad_add_sysfs(struct acpi_device *device) static struct attribute *acpi_pad_attrs[] = {
{ &dev_attr_idlecpus.attr,
int result; &dev_attr_idlepct.attr,
&dev_attr_rrtime.attr,
result = device_create_file(&device->dev, &dev_attr_idlecpus); NULL
if (result) };
return -ENODEV;
result = device_create_file(&device->dev, &dev_attr_idlepct);
if (result) {
device_remove_file(&device->dev, &dev_attr_idlecpus);
return -ENODEV;
}
result = device_create_file(&device->dev, &dev_attr_rrtime);
if (result) {
device_remove_file(&device->dev, &dev_attr_idlecpus);
device_remove_file(&device->dev, &dev_attr_idlepct);
return -ENODEV;
}
return 0;
}
static void acpi_pad_remove_sysfs(struct acpi_device *device) ATTRIBUTE_GROUPS(acpi_pad);
{
device_remove_file(&device->dev, &dev_attr_idlecpus);
device_remove_file(&device->dev, &dev_attr_idlepct);
device_remove_file(&device->dev, &dev_attr_rrtime);
}
/* /*
* Query firmware how many CPUs should be idle * Query firmware how many CPUs should be idle
...@@ -416,13 +398,13 @@ static void acpi_pad_handle_notify(acpi_handle handle) ...@@ -416,13 +398,13 @@ static void acpi_pad_handle_notify(acpi_handle handle)
static void acpi_pad_notify(acpi_handle handle, u32 event, static void acpi_pad_notify(acpi_handle handle, u32 event,
void *data) void *data)
{ {
struct acpi_device *device = data; struct acpi_device *adev = data;
switch (event) { switch (event) {
case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
acpi_pad_handle_notify(handle); acpi_pad_handle_notify(handle);
acpi_bus_generate_netlink_event(device->pnp.device_class, acpi_bus_generate_netlink_event(adev->pnp.device_class,
dev_name(&device->dev), event, 0); dev_name(&adev->dev), event, 0);
break; break;
default: default:
pr_warn("Unsupported event [0x%x]\n", event); pr_warn("Unsupported event [0x%x]\n", event);
...@@ -430,35 +412,33 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, ...@@ -430,35 +412,33 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
} }
} }
static int acpi_pad_add(struct acpi_device *device) static int acpi_pad_probe(struct platform_device *pdev)
{ {
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
acpi_status status; acpi_status status;
strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); strcpy(acpi_device_name(adev), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); strcpy(acpi_device_class(adev), ACPI_PROCESSOR_AGGREGATOR_CLASS);
if (acpi_pad_add_sysfs(device)) status = acpi_install_notify_handler(adev->handle,
return -ENODEV; ACPI_DEVICE_NOTIFY, acpi_pad_notify, adev);
status = acpi_install_notify_handler(device->handle, if (ACPI_FAILURE(status))
ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
if (ACPI_FAILURE(status)) {
acpi_pad_remove_sysfs(device);
return -ENODEV; return -ENODEV;
}
return 0; return 0;
} }
static void acpi_pad_remove(struct acpi_device *device) static void acpi_pad_remove(struct platform_device *pdev)
{ {
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
mutex_lock(&isolated_cpus_lock); mutex_lock(&isolated_cpus_lock);
acpi_pad_idle_cpus(0); acpi_pad_idle_cpus(0);
mutex_unlock(&isolated_cpus_lock); mutex_unlock(&isolated_cpus_lock);
acpi_remove_notify_handler(device->handle, acpi_remove_notify_handler(adev->handle,
ACPI_DEVICE_NOTIFY, acpi_pad_notify); ACPI_DEVICE_NOTIFY, acpi_pad_notify);
acpi_pad_remove_sysfs(device);
} }
static const struct acpi_device_id pad_device_ids[] = { static const struct acpi_device_id pad_device_ids[] = {
...@@ -467,13 +447,13 @@ static const struct acpi_device_id pad_device_ids[] = { ...@@ -467,13 +447,13 @@ static const struct acpi_device_id pad_device_ids[] = {
}; };
MODULE_DEVICE_TABLE(acpi, pad_device_ids); MODULE_DEVICE_TABLE(acpi, pad_device_ids);
static struct acpi_driver acpi_pad_driver = { static struct platform_driver acpi_pad_driver = {
.name = "processor_aggregator", .probe = acpi_pad_probe,
.class = ACPI_PROCESSOR_AGGREGATOR_CLASS, .remove_new = acpi_pad_remove,
.ids = pad_device_ids, .driver = {
.ops = { .dev_groups = acpi_pad_groups,
.add = acpi_pad_add, .name = "processor_aggregator",
.remove = acpi_pad_remove, .acpi_match_table = pad_device_ids,
}, },
}; };
...@@ -487,12 +467,12 @@ static int __init acpi_pad_init(void) ...@@ -487,12 +467,12 @@ static int __init acpi_pad_init(void)
if (power_saving_mwait_eax == 0) if (power_saving_mwait_eax == 0)
return -EINVAL; return -EINVAL;
return acpi_bus_register_driver(&acpi_pad_driver); return platform_driver_register(&acpi_pad_driver);
} }
static void __exit acpi_pad_exit(void) static void __exit acpi_pad_exit(void)
{ {
acpi_bus_unregister_driver(&acpi_pad_driver); platform_driver_unregister(&acpi_pad_driver);
} }
module_init(acpi_pad_init); module_init(acpi_pad_init);
......
...@@ -2062,7 +2062,7 @@ static int acpi_video_bus_add(struct acpi_device *device) ...@@ -2062,7 +2062,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
goto err_del; goto err_del;
error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_video_bus_notify); acpi_video_bus_notify, device);
if (error) if (error)
goto err_remove; goto err_remove;
......
...@@ -59,6 +59,10 @@ static struct acpi_table_erst *erst_tab; ...@@ -59,6 +59,10 @@ static struct acpi_table_erst *erst_tab;
#define ERST_RANGE_NVRAM 0x0002 #define ERST_RANGE_NVRAM 0x0002
#define ERST_RANGE_SLOW 0x0004 #define ERST_RANGE_SLOW 0x0004
/* ERST Exec max timings */
#define ERST_EXEC_TIMING_MAX_MASK 0xFFFFFFFF00000000
#define ERST_EXEC_TIMING_MAX_SHIFT 32
/* /*
* ERST Error Log Address Range, used as buffer for reading/writing * ERST Error Log Address Range, used as buffer for reading/writing
* error records. * error records.
...@@ -68,6 +72,7 @@ static struct erst_erange { ...@@ -68,6 +72,7 @@ static struct erst_erange {
u64 size; u64 size;
void __iomem *vaddr; void __iomem *vaddr;
u32 attr; u32 attr;
u64 timings;
} erst_erange; } erst_erange;
/* /*
...@@ -97,6 +102,19 @@ static inline int erst_errno(int command_status) ...@@ -97,6 +102,19 @@ static inline int erst_errno(int command_status)
} }
} }
static inline u64 erst_get_timeout(void)
{
u64 timeout = FIRMWARE_TIMEOUT;
if (erst_erange.attr & ERST_RANGE_SLOW) {
timeout = ((erst_erange.timings & ERST_EXEC_TIMING_MAX_MASK) >>
ERST_EXEC_TIMING_MAX_SHIFT) * NSEC_PER_MSEC;
if (timeout < FIRMWARE_TIMEOUT)
timeout = FIRMWARE_TIMEOUT;
}
return timeout;
}
static int erst_timedout(u64 *t, u64 spin_unit) static int erst_timedout(u64 *t, u64 spin_unit)
{ {
if ((s64)*t < spin_unit) { if ((s64)*t < spin_unit) {
...@@ -191,9 +209,11 @@ static int erst_exec_stall_while_true(struct apei_exec_context *ctx, ...@@ -191,9 +209,11 @@ static int erst_exec_stall_while_true(struct apei_exec_context *ctx,
{ {
int rc; int rc;
u64 val; u64 val;
u64 timeout = FIRMWARE_TIMEOUT; u64 timeout;
u64 stall_time; u64 stall_time;
timeout = erst_get_timeout();
if (ctx->var1 > FIRMWARE_MAX_STALL) { if (ctx->var1 > FIRMWARE_MAX_STALL) {
if (!in_nmi()) if (!in_nmi())
pr_warn(FW_WARN pr_warn(FW_WARN
...@@ -389,6 +409,13 @@ static int erst_get_erange(struct erst_erange *range) ...@@ -389,6 +409,13 @@ static int erst_get_erange(struct erst_erange *range)
if (rc) if (rc)
return rc; return rc;
range->attr = apei_exec_ctx_get_output(&ctx); range->attr = apei_exec_ctx_get_output(&ctx);
rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_TIMINGS);
if (rc == 0)
range->timings = apei_exec_ctx_get_output(&ctx);
else if (rc == -ENOENT)
range->timings = 0;
else
return rc;
return 0; return 0;
} }
...@@ -621,10 +648,12 @@ EXPORT_SYMBOL_GPL(erst_get_record_id_end); ...@@ -621,10 +648,12 @@ EXPORT_SYMBOL_GPL(erst_get_record_id_end);
static int __erst_write_to_storage(u64 offset) static int __erst_write_to_storage(u64 offset)
{ {
struct apei_exec_context ctx; struct apei_exec_context ctx;
u64 timeout = FIRMWARE_TIMEOUT; u64 timeout;
u64 val; u64 val;
int rc; int rc;
timeout = erst_get_timeout();
erst_exec_ctx_init(&ctx); erst_exec_ctx_init(&ctx);
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE); rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE);
if (rc) if (rc)
...@@ -660,10 +689,12 @@ static int __erst_write_to_storage(u64 offset) ...@@ -660,10 +689,12 @@ static int __erst_write_to_storage(u64 offset)
static int __erst_read_from_storage(u64 record_id, u64 offset) static int __erst_read_from_storage(u64 record_id, u64 offset)
{ {
struct apei_exec_context ctx; struct apei_exec_context ctx;
u64 timeout = FIRMWARE_TIMEOUT; u64 timeout;
u64 val; u64 val;
int rc; int rc;
timeout = erst_get_timeout();
erst_exec_ctx_init(&ctx); erst_exec_ctx_init(&ctx);
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ); rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ);
if (rc) if (rc)
...@@ -703,10 +734,12 @@ static int __erst_read_from_storage(u64 record_id, u64 offset) ...@@ -703,10 +734,12 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
static int __erst_clear_from_storage(u64 record_id) static int __erst_clear_from_storage(u64 record_id)
{ {
struct apei_exec_context ctx; struct apei_exec_context ctx;
u64 timeout = FIRMWARE_TIMEOUT; u64 timeout;
u64 val; u64 val;
int rc; int rc;
timeout = erst_get_timeout();
erst_exec_ctx_init(&ctx); erst_exec_ctx_init(&ctx);
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR); rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR);
if (rc) if (rc)
......
...@@ -209,6 +209,20 @@ int ghes_estatus_pool_init(unsigned int num_ghes) ...@@ -209,6 +209,20 @@ int ghes_estatus_pool_init(unsigned int num_ghes)
return -ENOMEM; return -ENOMEM;
} }
/**
* ghes_estatus_pool_region_free - free previously allocated memory
* from the ghes_estatus_pool.
* @addr: address of memory to free.
* @size: size of memory to free.
*
* Returns none.
*/
void ghes_estatus_pool_region_free(unsigned long addr, u32 size)
{
gen_pool_free(ghes_estatus_pool, addr, size);
}
EXPORT_SYMBOL_GPL(ghes_estatus_pool_region_free);
static int map_gen_v2(struct ghes *ghes) static int map_gen_v2(struct ghes *ghes)
{ {
return apei_map_generic_address(&ghes->generic_v2->read_ack_register); return apei_map_generic_address(&ghes->generic_v2->read_ack_register);
...@@ -564,6 +578,7 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) ...@@ -564,6 +578,7 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
unsigned int devfn; unsigned int devfn;
int aer_severity; int aer_severity;
u8 *aer_info;
devfn = PCI_DEVFN(pcie_err->device_id.device, devfn = PCI_DEVFN(pcie_err->device_id.device,
pcie_err->device_id.function); pcie_err->device_id.function);
...@@ -577,11 +592,17 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) ...@@ -577,11 +592,17 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
if (gdata->flags & CPER_SEC_RESET) if (gdata->flags & CPER_SEC_RESET)
aer_severity = AER_FATAL; aer_severity = AER_FATAL;
aer_info = (void *)gen_pool_alloc(ghes_estatus_pool,
sizeof(struct aer_capability_regs));
if (!aer_info)
return;
memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs));
aer_recover_queue(pcie_err->device_id.segment, aer_recover_queue(pcie_err->device_id.segment,
pcie_err->device_id.bus, pcie_err->device_id.bus,
devfn, aer_severity, devfn, aer_severity,
(struct aer_capability_regs *) (struct aer_capability_regs *)
pcie_err->aer_info); aer_info);
} }
#endif #endif
} }
......
...@@ -1214,7 +1214,7 @@ static int acpi_battery_add(struct acpi_device *device) ...@@ -1214,7 +1214,7 @@ static int acpi_battery_add(struct acpi_device *device)
device_init_wakeup(&device->dev, 1); device_init_wakeup(&device->dev, 1);
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY, result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
acpi_battery_notify); acpi_battery_notify, device);
if (result) if (result)
goto fail_pm; goto fail_pm;
......
...@@ -556,12 +556,12 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device, ...@@ -556,12 +556,12 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device,
int acpi_dev_install_notify_handler(struct acpi_device *adev, int acpi_dev_install_notify_handler(struct acpi_device *adev,
u32 handler_type, u32 handler_type,
acpi_notify_handler handler) acpi_notify_handler handler, void *context)
{ {
acpi_status status; acpi_status status;
status = acpi_install_notify_handler(adev->handle, handler_type, status = acpi_install_notify_handler(adev->handle, handler_type,
handler, adev); handler, context);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
......
...@@ -158,8 +158,8 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia ...@@ -158,8 +158,8 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
return 0; return 0;
len = snprintf(modalias, size, "acpi:"); len = snprintf(modalias, size, "acpi:");
if (len <= 0) if (len >= size)
return len; return -ENOMEM;
size -= len; size -= len;
...@@ -168,8 +168,6 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia ...@@ -168,8 +168,6 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
continue; continue;
count = snprintf(&modalias[len], size, "%s:", id->id); count = snprintf(&modalias[len], size, "%s:", id->id);
if (count < 0)
return -EINVAL;
if (count >= size) if (count >= size)
return -ENOMEM; return -ENOMEM;
...@@ -177,7 +175,7 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia ...@@ -177,7 +175,7 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
len += count; len += count;
size -= count; size -= count;
} }
modalias[len] = '\0';
return len; return len;
} }
...@@ -212,8 +210,10 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias ...@@ -212,8 +210,10 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias
len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
ACPI_FREE(buf.pointer); ACPI_FREE(buf.pointer);
if (len <= 0) if (len >= size)
return len; return -ENOMEM;
size -= len;
of_compatible = acpi_dev->data.of_compatible; of_compatible = acpi_dev->data.of_compatible;
if (of_compatible->type == ACPI_TYPE_PACKAGE) { if (of_compatible->type == ACPI_TYPE_PACKAGE) {
...@@ -226,8 +226,6 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias ...@@ -226,8 +226,6 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias
for (i = 0; i < nval; i++, obj++) { for (i = 0; i < nval; i++, obj++) {
count = snprintf(&modalias[len], size, "C%s", count = snprintf(&modalias[len], size, "C%s",
obj->string.pointer); obj->string.pointer);
if (count < 0)
return -EINVAL;
if (count >= size) if (count >= size)
return -ENOMEM; return -ENOMEM;
...@@ -235,7 +233,7 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias ...@@ -235,7 +233,7 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias
len += count; len += count;
size -= count; size -= count;
} }
modalias[len] = '\0';
return len; return len;
} }
...@@ -410,7 +408,7 @@ static ssize_t uid_show(struct device *dev, ...@@ -410,7 +408,7 @@ static ssize_t uid_show(struct device *dev,
{ {
struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_device *acpi_dev = to_acpi_device(dev);
return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); return sprintf(buf, "%s\n", acpi_device_uid(acpi_dev));
} }
static DEVICE_ATTR_RO(uid); static DEVICE_ATTR_RO(uid);
...@@ -554,7 +552,7 @@ int acpi_device_setup_files(struct acpi_device *dev) ...@@ -554,7 +552,7 @@ int acpi_device_setup_files(struct acpi_device *dev)
if (dev->pnp.type.bus_address) if (dev->pnp.type.bus_address)
result = device_create_file(&dev->dev, &dev_attr_adr); result = device_create_file(&dev->dev, &dev_attr_adr);
if (dev->pnp.unique_id) if (acpi_device_uid(dev))
result = device_create_file(&dev->dev, &dev_attr_uid); result = device_create_file(&dev->dev, &dev_attr_uid);
if (acpi_has_method(dev->handle, "_SUN")) { if (acpi_has_method(dev->handle, "_SUN")) {
...@@ -635,7 +633,7 @@ void acpi_device_remove_files(struct acpi_device *dev) ...@@ -635,7 +633,7 @@ void acpi_device_remove_files(struct acpi_device *dev)
if (acpi_has_method(dev->handle, "_HRV")) if (acpi_has_method(dev->handle, "_HRV"))
device_remove_file(&dev->dev, &dev_attr_hrv); device_remove_file(&dev->dev, &dev_attr_hrv);
if (dev->pnp.unique_id) if (acpi_device_uid(dev))
device_remove_file(&dev->dev, &dev_attr_uid); device_remove_file(&dev->dev, &dev_attr_uid);
if (dev->pnp.type.bus_address) if (dev->pnp.type.bus_address)
device_remove_file(&dev->dev, &dev_attr_adr); device_remove_file(&dev->dev, &dev_attr_adr);
......
...@@ -1924,6 +1924,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { ...@@ -1924,6 +1924,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"),
}, },
}, },
{
/*
* HP 250 G7 Notebook PC
*/
.callback = ec_honor_dsdt_gpe,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP 250 G7 Notebook PC"),
},
},
{ {
/* /*
* Samsung hardware * Samsung hardware
......
...@@ -57,7 +57,7 @@ static int acpi_hed_add(struct acpi_device *device) ...@@ -57,7 +57,7 @@ static int acpi_hed_add(struct acpi_device *device)
hed_handle = device->handle; hed_handle = device->handle;
err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_hed_notify); acpi_hed_notify, device);
if (err) if (err)
hed_handle = NULL; hed_handle = NULL;
......
...@@ -3340,7 +3340,7 @@ static int acpi_nfit_add(struct acpi_device *adev) ...@@ -3340,7 +3340,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
int rc = 0; int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY, rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
acpi_nfit_notify); acpi_nfit_notify, adev);
if (rc) if (rc)
return rc; return rc;
......
...@@ -110,7 +110,7 @@ void __init acpi_osi_setup(char *str) ...@@ -110,7 +110,7 @@ void __init acpi_osi_setup(char *str)
break; break;
} else if (osi->string[0] == '\0') { } else if (osi->string[0] == '\0') {
osi->enable = enable; osi->enable = enable;
strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); strscpy(osi->string, str, OSI_STRING_LENGTH_MAX);
break; break;
} }
} }
......
...@@ -149,7 +149,7 @@ void acpi_os_printf(const char *fmt, ...) ...@@ -149,7 +149,7 @@ void acpi_os_printf(const char *fmt, ...)
} }
EXPORT_SYMBOL(acpi_os_printf); EXPORT_SYMBOL(acpi_os_printf);
void acpi_os_vprintf(const char *fmt, va_list args) void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{ {
static char buffer[512]; static char buffer[512];
...@@ -493,7 +493,7 @@ EXPORT_SYMBOL(acpi_os_unmap_generic_address); ...@@ -493,7 +493,7 @@ EXPORT_SYMBOL(acpi_os_unmap_generic_address);
#ifdef ACPI_FUTURE_USAGE #ifdef ACPI_FUTURE_USAGE
acpi_status acpi_status
acpi_os_get_physical_address(void *virt, acpi_physical_address * phys) acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
{ {
if (!phys || !virt) if (!phys || !virt)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
...@@ -784,7 +784,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) ...@@ -784,7 +784,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
acpi_status acpi_status
acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
u64 *value, u32 width) u64 *value, u32 width)
{ {
int result, size; int result, size;
...@@ -816,7 +816,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, ...@@ -816,7 +816,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
} }
acpi_status acpi_status
acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
u64 value, u32 width) u64 value, u32 width)
{ {
int result, size; int result, size;
...@@ -1067,6 +1067,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, ...@@ -1067,6 +1067,7 @@ acpi_status acpi_os_execute(acpi_execute_type type,
struct acpi_os_dpc *dpc; struct acpi_os_dpc *dpc;
struct workqueue_struct *queue; struct workqueue_struct *queue;
int ret; int ret;
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Scheduling function [%p(%p)] for deferred execution.\n", "Scheduling function [%p(%p)] for deferred execution.\n",
function, context)); function, context));
...@@ -1197,7 +1198,7 @@ bool acpi_queue_hotplug_work(struct work_struct *work) ...@@ -1197,7 +1198,7 @@ bool acpi_queue_hotplug_work(struct work_struct *work)
} }
acpi_status acpi_status
acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle *handle)
{ {
struct semaphore *sem = NULL; struct semaphore *sem = NULL;
...@@ -1522,6 +1523,7 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp) ...@@ -1522,6 +1523,7 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
__acquires(lockp) __acquires(lockp)
{ {
acpi_cpu_flags flags; acpi_cpu_flags flags;
spin_lock_irqsave(lockp, flags); spin_lock_irqsave(lockp, flags);
return flags; return flags;
} }
...@@ -1554,7 +1556,7 @@ void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags) ...@@ -1554,7 +1556,7 @@ void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t **cache)
{ {
*cache = kmem_cache_create(name, size, 0, 0, NULL); *cache = kmem_cache_create(name, size, 0, 0, NULL);
if (*cache == NULL) if (*cache == NULL)
...@@ -1575,10 +1577,10 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) ...@@ -1575,10 +1577,10 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_os_purge_cache(acpi_cache_t * cache) acpi_status acpi_os_purge_cache(acpi_cache_t *cache)
{ {
kmem_cache_shrink(cache); kmem_cache_shrink(cache);
return (AE_OK); return AE_OK;
} }
/******************************************************************************* /*******************************************************************************
...@@ -1594,10 +1596,10 @@ acpi_status acpi_os_purge_cache(acpi_cache_t * cache) ...@@ -1594,10 +1596,10 @@ acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_os_delete_cache(acpi_cache_t * cache) acpi_status acpi_os_delete_cache(acpi_cache_t *cache)
{ {
kmem_cache_destroy(cache); kmem_cache_destroy(cache);
return (AE_OK); return AE_OK;
} }
/******************************************************************************* /*******************************************************************************
...@@ -1614,10 +1616,10 @@ acpi_status acpi_os_delete_cache(acpi_cache_t * cache) ...@@ -1614,10 +1616,10 @@ acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) acpi_status acpi_os_release_object(acpi_cache_t *cache, void *object)
{ {
kmem_cache_free(cache, object); kmem_cache_free(cache, object);
return (AE_OK); return AE_OK;
} }
#endif #endif
...@@ -1708,6 +1710,7 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, ...@@ -1708,6 +1710,7 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
u32 pm1b_control) u32 pm1b_control)
{ {
int rc = 0; int rc = 0;
if (__acpi_os_prepare_sleep) if (__acpi_os_prepare_sleep)
rc = __acpi_os_prepare_sleep(sleep_state, rc = __acpi_os_prepare_sleep(sleep_state,
pm1a_control, pm1b_control); pm1a_control, pm1b_control);
...@@ -1730,6 +1733,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a, ...@@ -1730,6 +1733,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
u32 val_b) u32 val_b)
{ {
int rc = 0; int rc = 0;
if (__acpi_os_prepare_extended_sleep) if (__acpi_os_prepare_extended_sleep)
rc = __acpi_os_prepare_extended_sleep(sleep_state, rc = __acpi_os_prepare_extended_sleep(sleep_state,
val_a, val_b); val_a, val_b);
......
...@@ -1055,9 +1055,9 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, ...@@ -1055,9 +1055,9 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
* exists and returns 0, we must preserve any PCI resource * exists and returns 0, we must preserve any PCI resource
* assignments made by firmware for this host bridge. * assignments made by firmware for this host bridge.
*/ */
obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1, obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
DSM_PCI_PRESERVE_BOOT_CONFIG, NULL); DSM_PCI_PRESERVE_BOOT_CONFIG, NULL, ACPI_TYPE_INTEGER);
if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0) if (obj && obj->integer.value == 0)
host_bridge->preserve_config = 1; host_bridge->preserve_config = 1;
ACPI_FREE(obj); ACPI_FREE(obj);
......
...@@ -69,7 +69,7 @@ struct prm_module_info { ...@@ -69,7 +69,7 @@ struct prm_module_info {
bool updatable; bool updatable;
struct list_head module_list; struct list_head module_list;
struct prm_handler_info handlers[]; struct prm_handler_info handlers[] __counted_by(handler_count);
}; };
static u64 efi_pa_va_lookup(u64 pa) static u64 efi_pa_va_lookup(u64 pa)
......
...@@ -55,6 +55,7 @@ static const guid_t ads_guid = ...@@ -55,6 +55,7 @@ static const guid_t ads_guid =
GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6, GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b); 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
/* ACPI _DSD data buffer GUID: edb12dd0-363d-4085-a3d2-49522ca160c4 */
static const guid_t buffer_prop_guid = static const guid_t buffer_prop_guid =
GUID_INIT(0xedb12dd0, 0x363d, 0x4085, GUID_INIT(0xedb12dd0, 0x363d, 0x4085,
0xa3, 0xd2, 0x49, 0x52, 0x2c, 0xa1, 0x60, 0xc4); 0xa3, 0xd2, 0x49, 0x52, 0x2c, 0xa1, 0x60, 0xc4);
...@@ -1102,25 +1103,26 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, ...@@ -1102,25 +1103,26 @@ static int acpi_data_prop_read(const struct acpi_device_data *data,
switch (proptype) { switch (proptype) {
case DEV_PROP_STRING: case DEV_PROP_STRING:
break; break;
case DEV_PROP_U8 ... DEV_PROP_U64: default:
if (obj->type == ACPI_TYPE_BUFFER) { if (obj->type == ACPI_TYPE_BUFFER) {
if (nval > obj->buffer.length) if (nval > obj->buffer.length)
return -EOVERFLOW; return -EOVERFLOW;
break; } else {
if (nval > obj->package.count)
return -EOVERFLOW;
} }
fallthrough;
default:
if (nval > obj->package.count)
return -EOVERFLOW;
break; break;
} }
if (nval == 0) if (nval == 0)
return -EINVAL; return -EINVAL;
if (obj->type != ACPI_TYPE_BUFFER) if (obj->type == ACPI_TYPE_BUFFER) {
items = obj->package.elements; if (proptype != DEV_PROP_U8)
else return -EPROTO;
items = obj; items = obj;
} else {
items = obj->package.elements;
}
switch (proptype) { switch (proptype) {
case DEV_PROP_U8: case DEV_PROP_U8:
......
...@@ -385,127 +385,144 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity) ...@@ -385,127 +385,144 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity)
} }
EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type); EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
static const struct dmi_system_id medion_laptop[] = { /*
* DMI matches for boards where the DSDT specifies the kbd IRQ as
* level active-low and using the override changes this to rising edge,
* stopping the keyboard from working.
*/
static const struct dmi_system_id irq1_level_low_skip_override[] = {
{ {
.ident = "MEDION P15651", /* MEDION P15651 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
DMI_MATCH(DMI_BOARD_NAME, "M15T"), DMI_MATCH(DMI_BOARD_NAME, "M15T"),
}, },
}, },
{ {
.ident = "MEDION S17405", /* MEDION S17405 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
DMI_MATCH(DMI_BOARD_NAME, "M17T"), DMI_MATCH(DMI_BOARD_NAME, "M17T"),
}, },
}, },
{ {
.ident = "MEDION S17413", /* MEDION S17413 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
DMI_MATCH(DMI_BOARD_NAME, "M1xA"), DMI_MATCH(DMI_BOARD_NAME, "M1xA"),
}, },
}, },
{ }
};
static const struct dmi_system_id asus_laptop[] = {
{ {
.ident = "Asus Vivobook K3402ZA", /* Asus Vivobook K3402ZA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"), DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
}, },
}, },
{ {
.ident = "Asus Vivobook K3502ZA", /* Asus Vivobook K3502ZA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"), DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
}, },
}, },
{ {
.ident = "Asus Vivobook S5402ZA", /* Asus Vivobook S5402ZA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"), DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"),
}, },
}, },
{ {
.ident = "Asus Vivobook S5602ZA", /* Asus Vivobook S5602ZA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
}, },
}, },
{ {
.ident = "Asus ExpertBook B1402CBA", /* Asus ExpertBook B1402CBA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
}, },
}, },
{ {
.ident = "Asus ExpertBook B1502CBA", /* Asus ExpertBook B1502CBA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"), DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"),
}, },
}, },
{ {
.ident = "Asus ExpertBook B2402CBA", /* Asus ExpertBook B2402CBA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
}, },
}, },
{ {
.ident = "Asus ExpertBook B2402FBA", /* Asus ExpertBook B2402FBA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"), DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"),
}, },
}, },
{ {
.ident = "Asus ExpertBook B2502", /* Asus ExpertBook B2502 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
}, },
}, },
{
/* LG Electronics 17U70P */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
},
},
{ } { }
}; };
static const struct dmi_system_id tongfang_gm_rg[] = { /*
* DMI matches for AMD Zen boards where the DSDT specifies the kbd IRQ
* as falling edge and this must be overridden to rising edge,
* to have a working keyboard.
*/
static const struct dmi_system_id irq1_edge_low_force_override[] = {
{ {
.ident = "TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD", /* TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD */
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
}, },
}, },
{ }
};
static const struct dmi_system_id maingear_laptop[] = {
{ {
.ident = "MAINGEAR Vector Pro 2 15", /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
},
},
{
/* TongFang GM6XGxX/TUXEDO Stellaris 16 Gen5 AMD */
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
},
},
{
/* MAINGEAR Vector Pro 2 15 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"), DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"),
DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"), DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"),
} }
}, },
{ {
.ident = "MAINGEAR Vector Pro 2 17", /* MAINGEAR Vector Pro 2 17 */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"), DMI_MATCH(DMI_SYS_VENDOR, "Micro Electronics Inc"),
DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-17A3070T"), DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-17A3070T"),
}, },
}, },
{ }
};
static const struct dmi_system_id pcspecialist_laptop[] = {
{ {
/* TongFang GM6BGEQ / PCSpecialist Elimina Pro 16 M, RTX 3050 */ /* TongFang GM6BGEQ / PCSpecialist Elimina Pro 16 M, RTX 3050 */
.matches = { .matches = {
...@@ -527,17 +544,6 @@ static const struct dmi_system_id pcspecialist_laptop[] = { ...@@ -527,17 +544,6 @@ static const struct dmi_system_id pcspecialist_laptop[] = {
{ } { }
}; };
static const struct dmi_system_id lg_laptop[] = {
{
.ident = "LG Electronics 17U70P",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
},
},
{ }
};
struct irq_override_cmp { struct irq_override_cmp {
const struct dmi_system_id *system; const struct dmi_system_id *system;
unsigned char irq; unsigned char irq;
...@@ -548,12 +554,8 @@ struct irq_override_cmp { ...@@ -548,12 +554,8 @@ struct irq_override_cmp {
}; };
static const struct irq_override_cmp override_table[] = { static const struct irq_override_cmp override_table[] = {
{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, { irq1_level_low_skip_override, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, { irq1_edge_low_force_override, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
{ tongfang_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
{ maingear_laptop, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
{ pcspecialist_laptop, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
{ lg_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
}; };
static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
......
...@@ -289,10 +289,10 @@ static int acpi_scan_hot_remove(struct acpi_device *device) ...@@ -289,10 +289,10 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
return 0; return 0;
} }
static int acpi_scan_device_not_present(struct acpi_device *adev) static int acpi_scan_device_not_enumerated(struct acpi_device *adev)
{ {
if (!acpi_device_enumerated(adev)) { if (!acpi_device_enumerated(adev)) {
dev_warn(&adev->dev, "Still not present\n"); dev_warn(&adev->dev, "Still not enumerated\n");
return -EALREADY; return -EALREADY;
} }
acpi_bus_trim(adev); acpi_bus_trim(adev);
...@@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev) ...@@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
int error; int error;
acpi_bus_get_status(adev); acpi_bus_get_status(adev);
if (adev->status.present || adev->status.functional) { if (acpi_device_is_present(adev)) {
/* /*
* This function is only called for device objects for which * This function is only called for device objects for which
* matching scan handlers exist. The only situation in which * matching scan handlers exist. The only situation in which
...@@ -327,7 +327,7 @@ static int acpi_scan_device_check(struct acpi_device *adev) ...@@ -327,7 +327,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
error = -ENODEV; error = -ENODEV;
} }
} else { } else {
error = acpi_scan_device_not_present(adev); error = acpi_scan_device_not_enumerated(adev);
} }
return error; return error;
} }
...@@ -338,8 +338,8 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used) ...@@ -338,8 +338,8 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
int error; int error;
acpi_bus_get_status(adev); acpi_bus_get_status(adev);
if (!(adev->status.present || adev->status.functional)) { if (!acpi_device_is_present(adev)) {
acpi_scan_device_not_present(adev); acpi_scan_device_not_enumerated(adev);
return 0; return 0;
} }
if (handler && handler->hotplug.scan_dependent) if (handler && handler->hotplug.scan_dependent)
...@@ -2032,6 +2032,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) ...@@ -2032,6 +2032,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
mutex_unlock(&acpi_dep_list_lock); mutex_unlock(&acpi_dep_list_lock);
} }
acpi_handle_list_free(&dep_devices);
return count; return count;
} }
......
...@@ -245,7 +245,7 @@ static bool update_trip_devices(struct acpi_thermal *tz, ...@@ -245,7 +245,7 @@ static bool update_trip_devices(struct acpi_thermal *tz,
struct acpi_thermal_trip *acpi_trip, struct acpi_thermal_trip *acpi_trip,
int index, bool compare) int index, bool compare)
{ {
struct acpi_handle_list devices; struct acpi_handle_list devices = { 0 };
char method[] = "_PSL"; char method[] = "_PSL";
acpi_status status; acpi_status status;
...@@ -255,18 +255,21 @@ static bool update_trip_devices(struct acpi_thermal *tz, ...@@ -255,18 +255,21 @@ static bool update_trip_devices(struct acpi_thermal *tz,
method[3] = '0' + index; method[3] = '0' + index;
} }
memset(&devices, 0, sizeof(devices));
status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices); status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method);
return false; return false;
} }
if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) {
acpi_handle_list_free(&devices);
return true;
}
if (compare)
ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device");
memcpy(&acpi_trip->devices, &devices, sizeof(devices)); acpi_handle_list_replace(&acpi_trip->devices, &devices);
return true; return true;
} }
...@@ -808,6 +811,17 @@ static void acpi_thermal_check_fn(struct work_struct *work) ...@@ -808,6 +811,17 @@ static void acpi_thermal_check_fn(struct work_struct *work)
mutex_unlock(&tz->thermal_check_lock); mutex_unlock(&tz->thermal_check_lock);
} }
static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz)
{
int i;
acpi_handle_list_free(&tz->trips.passive.trip.devices);
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
acpi_handle_list_free(&tz->trips.active[i].trip.devices);
kfree(tz);
}
static int acpi_thermal_add(struct acpi_device *device) static int acpi_thermal_add(struct acpi_device *device)
{ {
struct acpi_thermal_trip *acpi_trip; struct acpi_thermal_trip *acpi_trip;
...@@ -922,7 +936,7 @@ static int acpi_thermal_add(struct acpi_device *device) ...@@ -922,7 +936,7 @@ static int acpi_thermal_add(struct acpi_device *device)
acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk)); acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk));
result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_thermal_notify); acpi_thermal_notify, device);
if (result) if (result)
goto flush_wq; goto flush_wq;
...@@ -934,7 +948,7 @@ static int acpi_thermal_add(struct acpi_device *device) ...@@ -934,7 +948,7 @@ static int acpi_thermal_add(struct acpi_device *device)
free_trips: free_trips:
kfree(tz->trip_table); kfree(tz->trip_table);
free_memory: free_memory:
kfree(tz); acpi_thermal_free_thermal_zone(tz);
return result; return result;
} }
...@@ -954,7 +968,7 @@ static void acpi_thermal_remove(struct acpi_device *device) ...@@ -954,7 +968,7 @@ static void acpi_thermal_remove(struct acpi_device *device)
flush_workqueue(acpi_thermal_pm_queue); flush_workqueue(acpi_thermal_pm_queue);
acpi_thermal_unregister_thermal_zone(tz); acpi_thermal_unregister_thermal_zone(tz);
kfree(tz); acpi_thermal_free_thermal_zone(tz);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
......
...@@ -342,9 +342,8 @@ acpi_evaluate_reference(acpi_handle handle, ...@@ -342,9 +342,8 @@ acpi_evaluate_reference(acpi_handle handle,
u32 i = 0; u32 i = 0;
if (!list) { if (!list)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
}
/* Evaluate object. */ /* Evaluate object. */
...@@ -370,7 +369,8 @@ acpi_evaluate_reference(acpi_handle handle, ...@@ -370,7 +369,8 @@ acpi_evaluate_reference(acpi_handle handle,
goto end; goto end;
} }
if (package->package.count > ACPI_MAX_HANDLES) { list->handles = kcalloc(package->package.count, sizeof(*list->handles), GFP_KERNEL);
if (!list->handles) {
kfree(package); kfree(package);
return AE_NO_MEMORY; return AE_NO_MEMORY;
} }
...@@ -399,10 +399,11 @@ acpi_evaluate_reference(acpi_handle handle, ...@@ -399,10 +399,11 @@ acpi_evaluate_reference(acpi_handle handle,
acpi_handle_debug(list->handles[i], "Found in reference list\n"); acpi_handle_debug(list->handles[i], "Found in reference list\n");
} }
end: end:
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
list->count = 0; list->count = 0;
//kfree(list->handles); kfree(list->handles);
list->handles = NULL;
} }
kfree(buffer.pointer); kfree(buffer.pointer);
...@@ -412,6 +413,61 @@ acpi_evaluate_reference(acpi_handle handle, ...@@ -412,6 +413,61 @@ acpi_evaluate_reference(acpi_handle handle,
EXPORT_SYMBOL(acpi_evaluate_reference); EXPORT_SYMBOL(acpi_evaluate_reference);
/**
* acpi_handle_list_equal - Check if two ACPI handle lists are the same
* @list1: First list to compare.
* @list2: Second list to compare.
*
* Return true if the given ACPI handle lists are of the same size and
* contain the same ACPI handles in the same order. Otherwise, return false.
*/
bool acpi_handle_list_equal(struct acpi_handle_list *list1,
struct acpi_handle_list *list2)
{
return list1->count == list2->count &&
!memcmp(list1->handles, list2->handles,
list1->count * sizeof(acpi_handle));
}
EXPORT_SYMBOL_GPL(acpi_handle_list_equal);
/**
* acpi_handle_list_replace - Replace one ACPI handle list with another
* @dst: ACPI handle list to replace.
* @src: Source ACPI handle list.
*
* Free the handles table in @dst, move the handles table from @src to @dst,
* copy count from @src to @dst and clear @src.
*/
void acpi_handle_list_replace(struct acpi_handle_list *dst,
struct acpi_handle_list *src)
{
if (dst->count)
kfree(dst->handles);
dst->count = src->count;
dst->handles = src->handles;
src->handles = NULL;
src->count = 0;
}
EXPORT_SYMBOL_GPL(acpi_handle_list_replace);
/**
* acpi_handle_list_free - Free the handles table in an ACPI handle list
* @list: ACPI handle list to free.
*
* Free the handles table in @list and clear its count field.
*/
void acpi_handle_list_free(struct acpi_handle_list *list)
{
if (!list->count)
return;
kfree(list->handles);
list->count = 0;
}
EXPORT_SYMBOL_GPL(acpi_handle_list_free);
acpi_status acpi_status
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
{ {
...@@ -523,7 +579,7 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) ...@@ -523,7 +579,7 @@ acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
vaf.va = &args; vaf.va = &args;
path = acpi_handle_path(handle); path = acpi_handle_path(handle);
printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf); printk("%sACPI: %s: %pV", level, path ? path : "<n/a>", &vaf);
va_end(args); va_end(args);
kfree(path); kfree(path);
...@@ -768,20 +824,43 @@ bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs) ...@@ -768,20 +824,43 @@ bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs)
} }
EXPORT_SYMBOL(acpi_check_dsm); EXPORT_SYMBOL(acpi_check_dsm);
/**
* acpi_dev_uid_match - Match device by supplied UID
* @adev: ACPI device to match.
* @uid2: Unique ID of the device.
*
* Matches UID in @adev with given @uid2.
*
* Returns:
* - %true if matches.
* - %false otherwise.
*/
bool acpi_dev_uid_match(struct acpi_device *adev, const char *uid2)
{
const char *uid1 = acpi_device_uid(adev);
return uid1 && uid2 && !strcmp(uid1, uid2);
}
EXPORT_SYMBOL_GPL(acpi_dev_uid_match);
/** /**
* acpi_dev_hid_uid_match - Match device by supplied HID and UID * acpi_dev_hid_uid_match - Match device by supplied HID and UID
* @adev: ACPI device to match. * @adev: ACPI device to match.
* @hid2: Hardware ID of the device. * @hid2: Hardware ID of the device.
* @uid2: Unique ID of the device, pass NULL to not check _UID. * @uid2: Unique ID of the device, pass NULL to not check _UID.
* *
* Matches HID and UID in @adev with given @hid2 and @uid2. * Matches HID and UID in @adev with given @hid2 and @uid2. Absence of @uid2
* Returns true if matches. * will be treated as a match. If user wants to validate @uid2, it should be
* done before calling this function.
*
* Returns:
* - %true if matches or @uid2 is NULL.
* - %false otherwise.
*/ */
bool acpi_dev_hid_uid_match(struct acpi_device *adev, bool acpi_dev_hid_uid_match(struct acpi_device *adev,
const char *hid2, const char *uid2) const char *hid2, const char *uid2)
{ {
const char *hid1 = acpi_device_hid(adev); const char *hid1 = acpi_device_hid(adev);
const char *uid1 = acpi_device_uid(adev);
if (strcmp(hid1, hid2)) if (strcmp(hid1, hid2))
return false; return false;
...@@ -789,7 +868,7 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev, ...@@ -789,7 +868,7 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev,
if (!uid2) if (!uid2)
return true; return true;
return uid1 && !strcmp(uid1, uid2); return acpi_dev_uid_match(adev, uid2);
} }
EXPORT_SYMBOL(acpi_dev_hid_uid_match); EXPORT_SYMBOL(acpi_dev_hid_uid_match);
...@@ -863,8 +942,7 @@ static int acpi_dev_match_cb(struct device *dev, const void *data) ...@@ -863,8 +942,7 @@ static int acpi_dev_match_cb(struct device *dev, const void *data)
if (acpi_match_device_ids(adev, match->hid)) if (acpi_match_device_ids(adev, match->hid))
return 0; return 0;
if (match->uid && (!adev->pnp.unique_id || if (match->uid && !acpi_dev_uid_match(adev, match->uid))
strcmp(adev->pnp.unique_id, match->uid)))
return 0; return 0;
if (match->hrv == -1) if (match->hrv == -1)
......
...@@ -130,6 +130,16 @@ static int video_detect_force_native(const struct dmi_system_id *d) ...@@ -130,6 +130,16 @@ static int video_detect_force_native(const struct dmi_system_id *d)
return 0; return 0;
} }
static int video_detect_portege_r100(const struct dmi_system_id *d)
{
struct pci_dev *dev;
/* Search for Trident CyberBlade XP4m32 to confirm Portégé R100 */
dev = pci_get_device(PCI_VENDOR_ID_TRIDENT, 0x2100, NULL);
if (dev)
acpi_backlight_dmi = acpi_backlight_vendor;
return 0;
}
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, * Models which should use the vendor backlight interface,
...@@ -229,14 +239,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = { ...@@ -229,14 +239,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,
/* Xiaomi Mi Pad 2 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
},
},
/* /*
* Models which should use the vendor backlight interface, * Models which should use the vendor backlight interface,
...@@ -270,6 +272,22 @@ static const struct dmi_system_id video_detect_dmi_table[] = { ...@@ -270,6 +272,22 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
}, },
}, },
/*
* Toshiba Portégé R100 has working both acpi_video and toshiba_acpi
* vendor driver. But none of them gets activated as it has a VGA with
* no kernel driver (Trident CyberBlade XP4m32).
* The DMI strings are generic so check for the VGA chip in callback.
*/
{
.callback = video_detect_portege_r100,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
DMI_MATCH(DMI_BOARD_NAME, "Portable PC")
},
},
/* /*
* Models which need acpi_video backlight control where the GPU drivers * Models which need acpi_video backlight control where the GPU drivers
* do not call acpi_video_register_backlight() because no internal panel * do not call acpi_video_register_backlight() because no internal panel
...@@ -799,6 +817,56 @@ static const struct dmi_system_id video_detect_dmi_table[] = { ...@@ -799,6 +817,56 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"),
}, },
}, },
/*
* x86 android tablets which directly control the backlight through
* an external backlight controller, typically TI's LP8557.
* The backlight is directly controlled by the lp855x driver on these.
* This setup means that neither i915's native nor acpi_video backlight
* control works. Add a "vendor" quirk to disable both. Note these
* devices do not use vendor control in the typical meaning of
* vendor specific SMBIOS or ACPI calls being used.
*/
{
.callback = video_detect_force_vendor,
/* Lenovo Yoga Book X90F / X90L */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
},
},
{
.callback = video_detect_force_vendor,
/*
* Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
* Lenovo Yoga Tablet 2 use the same mainboard)
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
/* Partial match on beginning of BIOS version */
DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
},
},
{
.callback = video_detect_force_vendor,
/* Lenovo Yoga Tab 3 Pro YT3-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"),
},
},
{
.callback = video_detect_force_vendor,
/* Xiaomi Mi Pad 2 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
},
},
{ }, { },
}; };
......
...@@ -417,11 +417,10 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d ...@@ -417,11 +417,10 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d
int ret = -EINVAL; int ret = -EINVAL;
guid_parse(uuid, dsm_guid); guid_parse(uuid, dsm_guid);
obj = acpi_evaluate_dsm(handle, dsm_guid, rev, 0, NULL);
/* Check if the _DSM is present and as expected. */ /* Check if the _DSM is present and as expected. */
if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length == 0 || obj = acpi_evaluate_dsm_typed(handle, dsm_guid, rev, 0, NULL, ACPI_TYPE_BUFFER);
obj->buffer.length > sizeof(u32)) { if (!obj || obj->buffer.length == 0 || obj->buffer.length > sizeof(u32)) {
acpi_handle_debug(handle, acpi_handle_debug(handle,
"_DSM UUID %s rev %d function 0 evaluation failed\n", uuid, rev); "_DSM UUID %s rev %d function 0 evaluation failed\n", uuid, rev);
goto out; goto out;
......
...@@ -184,8 +184,7 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s ...@@ -184,8 +184,7 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s
if (acpi_match_device_ids(adev, override_status_ids[i].hid)) if (acpi_match_device_ids(adev, override_status_ids[i].hid))
continue; continue;
if (!adev->pnp.unique_id || if (!acpi_dev_uid_match(adev, override_status_ids[i].uid))
strcmp(adev->pnp.unique_id, override_status_ids[i].uid))
continue; continue;
} }
......
...@@ -57,12 +57,6 @@ ...@@ -57,12 +57,6 @@
(MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \ (MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \
MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type) MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type)
/* PCC defines */
#define PCC_SIGNATURE_MASK 0x50424300
#define PCCC_GENERATE_DB_INT BIT(15)
#define PCCS_CMD_COMPLETE BIT(0)
#define PCCS_SCI_DOORBEL BIT(1)
#define PCCS_PLATFORM_NOTIFICATION BIT(3)
/* /*
* Arbitrary retries in case the remote processor is slow to respond * Arbitrary retries in case the remote processor is slow to respond
* to PCC commands * to PCC commands
...@@ -142,15 +136,15 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg) ...@@ -142,15 +136,15 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
/* Write signature for subspace */ /* Write signature for subspace */
WRITE_ONCE(generic_comm_base->signature, WRITE_ONCE(generic_comm_base->signature,
cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx)); cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));
/* Write to the shared command region */ /* Write to the shared command region */
WRITE_ONCE(generic_comm_base->command, WRITE_ONCE(generic_comm_base->command,
cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT)); cpu_to_le16(MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));
/* Flip CMD COMPLETE bit */ /* Flip CMD COMPLETE bit */
val = le16_to_cpu(READ_ONCE(generic_comm_base->status)); val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
val &= ~PCCS_CMD_COMPLETE; val &= ~PCC_STATUS_CMD_COMPLETE;
WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val)); WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
/* Copy the message to the PCC comm space */ /* Copy the message to the PCC comm space */
...@@ -544,7 +538,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg) ...@@ -544,7 +538,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
msg = generic_comm_base + 1; msg = generic_comm_base + 1;
/* Check if platform sends interrupt */ /* Check if platform sends interrupt */
if (!xgene_word_tst_and_clr(&generic_comm_base->status, if (!xgene_word_tst_and_clr(&generic_comm_base->status,
PCCS_SCI_DOORBEL)) PCC_STATUS_SCI_DOORBELL))
return; return;
/* /*
...@@ -566,7 +560,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg) ...@@ -566,7 +560,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) { TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
/* Check if platform completes command */ /* Check if platform completes command */
if (xgene_word_tst_and_clr(&generic_comm_base->status, if (xgene_word_tst_and_clr(&generic_comm_base->status,
PCCS_CMD_COMPLETE)) { PCC_STATUS_CMD_COMPLETE)) {
ctx->sync_msg.msg = ((u32 *)msg)[0]; ctx->sync_msg.msg = ((u32 *)msg)[0];
ctx->sync_msg.param1 = ((u32 *)msg)[1]; ctx->sync_msg.param1 = ((u32 *)msg)[1];
ctx->sync_msg.param2 = ((u32 *)msg)[2]; ctx->sync_msg.param2 = ((u32 *)msg)[2];
......
...@@ -91,14 +91,6 @@ ...@@ -91,14 +91,6 @@
#define SLIMPRO_IIC_MSG_DWORD_COUNT 3 #define SLIMPRO_IIC_MSG_DWORD_COUNT 3
/* PCC related defines */
#define PCC_SIGNATURE 0x50424300
#define PCC_STS_CMD_COMPLETE BIT(0)
#define PCC_STS_SCI_DOORBELL BIT(1)
#define PCC_STS_ERR BIT(2)
#define PCC_STS_PLAT_NOTIFY BIT(3)
#define PCC_CMD_GENERATE_DB_INT BIT(15)
struct slimpro_i2c_dev { struct slimpro_i2c_dev {
struct i2c_adapter adapter; struct i2c_adapter adapter;
struct device *dev; struct device *dev;
...@@ -160,11 +152,11 @@ static void slimpro_i2c_pcc_rx_cb(struct mbox_client *cl, void *msg) ...@@ -160,11 +152,11 @@ static void slimpro_i2c_pcc_rx_cb(struct mbox_client *cl, void *msg)
/* Check if platform sends interrupt */ /* Check if platform sends interrupt */
if (!xgene_word_tst_and_clr(&generic_comm_base->status, if (!xgene_word_tst_and_clr(&generic_comm_base->status,
PCC_STS_SCI_DOORBELL)) PCC_STATUS_SCI_DOORBELL))
return; return;
if (xgene_word_tst_and_clr(&generic_comm_base->status, if (xgene_word_tst_and_clr(&generic_comm_base->status,
PCC_STS_CMD_COMPLETE)) { PCC_STATUS_CMD_COMPLETE)) {
msg = generic_comm_base + 1; msg = generic_comm_base + 1;
/* Response message msg[1] contains the return value. */ /* Response message msg[1] contains the return value. */
...@@ -186,10 +178,10 @@ static void slimpro_i2c_pcc_tx_prepare(struct slimpro_i2c_dev *ctx, u32 *msg) ...@@ -186,10 +178,10 @@ static void slimpro_i2c_pcc_tx_prepare(struct slimpro_i2c_dev *ctx, u32 *msg)
cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx)); cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));
WRITE_ONCE(generic_comm_base->command, WRITE_ONCE(generic_comm_base->command,
cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INT)); cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));
status = le16_to_cpu(READ_ONCE(generic_comm_base->status)); status = le16_to_cpu(READ_ONCE(generic_comm_base->status));
status &= ~PCC_STS_CMD_COMPLETE; status &= ~PCC_STATUS_CMD_COMPLETE;
WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status)); WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status));
/* Copy the message to the PCC comm space */ /* Copy the message to the PCC comm space */
......
...@@ -91,6 +91,14 @@ struct pcc_chan_reg { ...@@ -91,6 +91,14 @@ struct pcc_chan_reg {
* @cmd_update: PCC register bundle for the command complete update register * @cmd_update: PCC register bundle for the command complete update register
* @error: PCC register bundle for the error status register * @error: PCC register bundle for the error status register
* @plat_irq: platform interrupt * @plat_irq: platform interrupt
* @type: PCC subspace type
* @plat_irq_flags: platform interrupt flags
* @chan_in_use: this flag is used just to check if the interrupt needs
* handling when it is shared. Since only one transfer can occur
* at a time and mailbox takes care of locking, this flag can be
* accessed without a lock. Note: the type only support the
* communication from OSPM to Platform, like type3, use it, and
* other types completely ignore it.
*/ */
struct pcc_chan_info { struct pcc_chan_info {
struct pcc_mbox_chan chan; struct pcc_mbox_chan chan;
...@@ -100,12 +108,17 @@ struct pcc_chan_info { ...@@ -100,12 +108,17 @@ struct pcc_chan_info {
struct pcc_chan_reg cmd_update; struct pcc_chan_reg cmd_update;
struct pcc_chan_reg error; struct pcc_chan_reg error;
int plat_irq; int plat_irq;
u8 type;
unsigned int plat_irq_flags;
bool chan_in_use;
}; };
#define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan) #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
static struct pcc_chan_info *chan_info; static struct pcc_chan_info *chan_info;
static int pcc_chan_count; static int pcc_chan_count;
static int pcc_send_data(struct mbox_chan *chan, void *data);
/* /*
* PCC can be used with perf critical drivers such as CPPC * PCC can be used with perf critical drivers such as CPPC
* So it makes sense to locally cache the virtual address and * So it makes sense to locally cache the virtual address and
...@@ -221,6 +234,41 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags) ...@@ -221,6 +234,41 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
return acpi_register_gsi(NULL, interrupt, trigger, polarity); return acpi_register_gsi(NULL, interrupt, trigger, polarity);
} }
static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan)
{
return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) ==
ACPI_LEVEL_SENSITIVE;
}
static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
{
u64 val;
int ret;
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
if (ret)
return false;
if (!pchan->cmd_complete.gas)
return true;
/*
* Judge if the channel respond the interrupt based on the value of
* command complete.
*/
val &= pchan->cmd_complete.status_mask;
/*
* If this is PCC slave subspace channel, and the command complete
* bit 0 indicates that Platform is sending a notification and OSPM
* needs to respond this interrupt to process this command.
*/
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
return !val;
return !!val;
}
/** /**
* pcc_mbox_irq - PCC mailbox interrupt handler * pcc_mbox_irq - PCC mailbox interrupt handler
* @irq: interrupt number * @irq: interrupt number
...@@ -236,16 +284,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) ...@@ -236,16 +284,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
int ret; int ret;
pchan = chan->con_priv; pchan = chan->con_priv;
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val); !pchan->chan_in_use)
if (ret)
return IRQ_NONE; return IRQ_NONE;
if (val) { /* Ensure GAS exists and value is non-zero */ if (!pcc_mbox_cmd_complete_check(pchan))
val &= pchan->cmd_complete.status_mask; return IRQ_NONE;
if (!val)
return IRQ_NONE;
}
ret = pcc_chan_reg_read(&pchan->error, &val); ret = pcc_chan_reg_read(&pchan->error, &val);
if (ret) if (ret)
...@@ -262,6 +306,16 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) ...@@ -262,6 +306,16 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
mbox_chan_received_data(chan, NULL); mbox_chan_received_data(chan, NULL);
/*
* The PCC slave subspace channel needs to set the command complete bit
* and ring doorbell after processing message.
*
* The PCC master subspace channel clears chan_in_use to free channel.
*/
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
pcc_send_data(chan, NULL);
pchan->chan_in_use = false;
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -340,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) ...@@ -340,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
if (ret) if (ret)
return ret; return ret;
return pcc_chan_reg_read_modify_write(&pchan->db); ret = pcc_chan_reg_read_modify_write(&pchan->db);
if (!ret && pchan->plat_irq > 0)
pchan->chan_in_use = true;
return ret;
} }
/** /**
...@@ -353,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) ...@@ -353,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
static int pcc_startup(struct mbox_chan *chan) static int pcc_startup(struct mbox_chan *chan)
{ {
struct pcc_chan_info *pchan = chan->con_priv; struct pcc_chan_info *pchan = chan->con_priv;
unsigned long irqflags;
int rc; int rc;
if (pchan->plat_irq > 0) { if (pchan->plat_irq > 0) {
rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0, irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ?
MBOX_IRQ_NAME, chan); IRQF_SHARED | IRQF_ONESHOT : 0;
rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,
irqflags, MBOX_IRQ_NAME, chan);
if (unlikely(rc)) { if (unlikely(rc)) {
dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n", dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
pchan->plat_irq); pchan->plat_irq);
...@@ -463,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, ...@@ -463,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
pcct_ss->platform_interrupt); pcct_ss->platform_interrupt);
return -EINVAL; return -EINVAL;
} }
pchan->plat_irq_flags = pcct_ss->flags;
if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss; struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
...@@ -484,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, ...@@ -484,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
"PLAT IRQ ACK"); "PLAT IRQ ACK");
} }
if (pcc_chan_plat_irq_can_be_shared(pchan) &&
!pchan->plat_irq_ack.gas) {
pr_err("PCC subspace has level IRQ with no ACK register\n");
return -EINVAL;
}
return ret; return ret;
} }
...@@ -698,6 +766,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) ...@@ -698,6 +766,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)
pcc_parse_subspace_shmem(pchan, pcct_entry); pcc_parse_subspace_shmem(pchan, pcct_entry);
pchan->type = pcct_entry->type;
pcct_entry = (struct acpi_subtable_header *) pcct_entry = (struct acpi_subtable_header *)
((unsigned long) pcct_entry + pcct_entry->length); ((unsigned long) pcct_entry + pcct_entry->length);
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/kfifo.h> #include <linux/kfifo.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <acpi/apei.h> #include <acpi/apei.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h> #include <ras/ras_event.h>
#include "../pci.h" #include "../pci.h"
...@@ -997,6 +998,15 @@ static void aer_recover_work_func(struct work_struct *work) ...@@ -997,6 +998,15 @@ static void aer_recover_work_func(struct work_struct *work)
continue; continue;
} }
cper_print_aer(pdev, entry.severity, entry.regs); cper_print_aer(pdev, entry.severity, entry.regs);
/*
* Memory for aer_capability_regs(entry.regs) is being allocated from the
* ghes_estatus_pool to protect it from overwriting when multiple sections
* are present in the error status. Thus free the same after processing
* the data.
*/
ghes_estatus_pool_region_free((unsigned long)entry.regs,
sizeof(struct aer_capability_regs));
if (entry.severity == AER_NONFATAL) if (entry.severity == AER_NONFATAL)
pcie_do_recovery(pdev, pci_channel_io_normal, pcie_do_recovery(pdev, pci_channel_io_normal,
aer_root_reset); aer_root_reset);
......
...@@ -1061,7 +1061,7 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu) ...@@ -1061,7 +1061,7 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)
static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid) static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid)
{ {
u32 acpi_uid; u64 acpi_uid;
struct device *cpu_dev; struct device *cpu_dev;
struct acpi_device *acpi_dev; struct acpi_device *acpi_dev;
...@@ -1071,10 +1071,8 @@ static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid) ...@@ -1071,10 +1071,8 @@ static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid)
acpi_dev = ACPI_COMPANION(cpu_dev); acpi_dev = ACPI_COMPANION(cpu_dev);
while (acpi_dev) { while (acpi_dev) {
if (!strcmp(acpi_device_hid(acpi_dev), if (acpi_dev_hid_uid_match(acpi_dev, ACPI_PROCESSOR_CONTAINER_HID, NULL) &&
ACPI_PROCESSOR_CONTAINER_HID) && !acpi_dev_uid_to_integer(acpi_dev, &acpi_uid) && acpi_uid == container_uid)
!kstrtouint(acpi_device_uid(acpi_dev), 0, &acpi_uid) &&
acpi_uid == container_uid)
return 0; return 0;
acpi_dev = acpi_dev_parent(acpi_dev); acpi_dev = acpi_dev_parent(acpi_dev);
......
...@@ -742,8 +742,8 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev) ...@@ -742,8 +742,8 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev)
l3pmu = devm_kzalloc(&pdev->dev, sizeof(*l3pmu), GFP_KERNEL); l3pmu = devm_kzalloc(&pdev->dev, sizeof(*l3pmu), GFP_KERNEL);
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "l3cache_%s_%s", name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "l3cache_%s_%s",
acpi_dev_parent(acpi_dev)->pnp.unique_id, acpi_device_uid(acpi_dev_parent(acpi_dev)),
acpi_dev->pnp.unique_id); acpi_device_uid(acpi_dev));
if (!l3pmu || !name) if (!l3pmu || !name)
return -ENOMEM; return -ENOMEM;
......
...@@ -1694,7 +1694,7 @@ const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_ ...@@ -1694,7 +1694,7 @@ const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_
unsigned int i; unsigned int i;
for (i = 0; table[i]; i++) { for (i = 0; table[i]; i++) {
if (!strcmp(adev->pnp.unique_id, table[i]->uid)) { if (acpi_dev_uid_match(adev, table[i]->uid)) {
data = table[i]; data = table[i];
break; break;
} }
......
...@@ -741,6 +741,7 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) ...@@ -741,6 +741,7 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
struct acpi_handle_list dep_devices; struct acpi_handle_list dep_devices;
acpi_handle supplier = ACPI_HANDLE(&pdev->dev); acpi_handle supplier = ACPI_HANDLE(&pdev->dev);
acpi_status status; acpi_status status;
bool ret = false;
int i; int i;
if (!acpi_has_method(handle, "_DEP")) if (!acpi_has_method(handle, "_DEP"))
...@@ -753,11 +754,14 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) ...@@ -753,11 +754,14 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
} }
for (i = 0; i < dep_devices.count; i++) { for (i = 0; i < dep_devices.count; i++) {
if (dep_devices.handles[i] == supplier) if (dep_devices.handles[i] == supplier) {
return true; ret = true;
break;
}
} }
return false; acpi_handle_list_free(&dep_devices);
return ret;
} }
static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl, static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
......
...@@ -250,12 +250,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device) ...@@ -250,12 +250,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
dev->capabilities |= PNP_DISABLE; dev->capabilities |= PNP_DISABLE;
if (strlen(acpi_device_name(device))) if (strlen(acpi_device_name(device)))
strncpy(dev->name, acpi_device_name(device), sizeof(dev->name)); strscpy(dev->name, acpi_device_name(device), sizeof(dev->name));
else else
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); strscpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
/* Handle possible string truncation */
dev->name[sizeof(dev->name) - 1] = '\0';
if (dev->active) if (dev->active)
pnpacpi_parse_allocated_resource(dev); pnpacpi_parse_allocated_resource(dev);
......
...@@ -454,8 +454,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, ...@@ -454,8 +454,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
switch (tag) { switch (tag) {
case LARGE_TAG_ANSISTR: case LARGE_TAG_ANSISTR:
strncpy(dev->name, p + 3, memcpy(dev->name, p + 3,
len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len); len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len);
dev->name[len >= dev->name[len >=
PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0'; PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0';
break; break;
......
...@@ -31,10 +31,6 @@ ...@@ -31,10 +31,6 @@
#include "kunpeng_hccs.h" #include "kunpeng_hccs.h"
/* PCC defines */
#define HCCS_PCC_SIGNATURE_MASK 0x50434300
#define HCCS_PCC_STATUS_CMD_COMPLETE BIT(0)
/* /*
* Arbitrary retries in case the remote processor is slow to respond * Arbitrary retries in case the remote processor is slow to respond
* to PCC commands * to PCC commands
...@@ -187,7 +183,7 @@ static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev) ...@@ -187,7 +183,7 @@ static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev)
* deadline_us(timeout_us) until PCC command complete bit is set(cond) * deadline_us(timeout_us) until PCC command complete bit is set(cond)
*/ */
ret = readw_poll_timeout(&comm_base->status, status, ret = readw_poll_timeout(&comm_base->status, status,
status & HCCS_PCC_STATUS_CMD_COMPLETE, status & PCC_STATUS_CMD_COMPLETE,
HCCS_POLL_STATUS_TIME_INTERVAL_US, HCCS_POLL_STATUS_TIME_INTERVAL_US,
cl_info->deadline_us); cl_info->deadline_us);
if (unlikely(ret)) if (unlikely(ret))
...@@ -208,7 +204,7 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd, ...@@ -208,7 +204,7 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
int ret; int ret;
/* Write signature for this subspace */ /* Write signature for this subspace */
tmp.signature = HCCS_PCC_SIGNATURE_MASK | hdev->chan_id; tmp.signature = PCC_SIGNATURE | hdev->chan_id;
/* Write to the shared command region */ /* Write to the shared command region */
tmp.command = cmd; tmp.command = cmd;
/* Clear cmd complete bit */ /* Clear cmd complete bit */
......
...@@ -12,11 +12,9 @@ ...@@ -12,11 +12,9 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/property.h> #include <linux/property.h>
/* TBD: Make dynamic */
#define ACPI_MAX_HANDLES 10
struct acpi_handle_list { struct acpi_handle_list {
u32 count; u32 count;
acpi_handle handles[ACPI_MAX_HANDLES]; acpi_handle* handles;
}; };
/* acpi_utils.h */ /* acpi_utils.h */
...@@ -32,6 +30,11 @@ acpi_evaluate_reference(acpi_handle handle, ...@@ -32,6 +30,11 @@ acpi_evaluate_reference(acpi_handle handle,
acpi_string pathname, acpi_string pathname,
struct acpi_object_list *arguments, struct acpi_object_list *arguments,
struct acpi_handle_list *list); struct acpi_handle_list *list);
bool acpi_handle_list_equal(struct acpi_handle_list *list1,
struct acpi_handle_list *list2);
void acpi_handle_list_replace(struct acpi_handle_list *dst,
struct acpi_handle_list *src);
void acpi_handle_list_free(struct acpi_handle_list *list);
acpi_status acpi_status
acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
struct acpi_buffer *status_buf); struct acpi_buffer *status_buf);
...@@ -517,7 +520,7 @@ int acpi_bus_attach_private_data(acpi_handle, void *); ...@@ -517,7 +520,7 @@ int acpi_bus_attach_private_data(acpi_handle, void *);
void acpi_bus_detach_private_data(acpi_handle); void acpi_bus_detach_private_data(acpi_handle);
int acpi_dev_install_notify_handler(struct acpi_device *adev, int acpi_dev_install_notify_handler(struct acpi_device *adev,
u32 handler_type, u32 handler_type,
acpi_notify_handler handler); acpi_notify_handler handler, void *context);
void acpi_dev_remove_notify_handler(struct acpi_device *adev, void acpi_dev_remove_notify_handler(struct acpi_device *adev,
u32 handler_type, u32 handler_type,
acpi_notify_handler handler); acpi_notify_handler handler);
...@@ -760,6 +763,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev) ...@@ -760,6 +763,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set); adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
} }
bool acpi_dev_uid_match(struct acpi_device *adev, const char *uid2);
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2); bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer); int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer);
......
...@@ -465,6 +465,9 @@ struct acpi_cdat_sslbe { ...@@ -465,6 +465,9 @@ struct acpi_cdat_sslbe {
u16 reserved; u16 reserved;
}; };
#define ACPI_CDAT_SSLBIS_US_PORT 0x0100
#define ACPI_CDAT_SSLBIS_ANY_PORT 0xffff
/******************************************************************************* /*******************************************************************************
* *
* CEDT - CXL Early Discovery Table * CEDT - CXL Early Discovery Table
......
...@@ -73,8 +73,12 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb); ...@@ -73,8 +73,12 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb);
void ghes_unregister_vendor_record_notifier(struct notifier_block *nb); void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
struct list_head *ghes_get_devices(void); struct list_head *ghes_get_devices(void);
void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
#else #else
static inline struct list_head *ghes_get_devices(void) { return NULL; } static inline struct list_head *ghes_get_devices(void) { return NULL; }
static inline void ghes_estatus_pool_region_free(unsigned long addr, u32 size) { return; }
#endif #endif
int ghes_estatus_pool_init(unsigned int num_ghes); int ghes_estatus_pool_init(unsigned int num_ghes);
......
...@@ -18,7 +18,20 @@ struct pcc_mbox_chan { ...@@ -18,7 +18,20 @@ struct pcc_mbox_chan {
u16 min_turnaround_time; u16 min_turnaround_time;
}; };
/* Generic Communications Channel Shared Memory Region */
#define PCC_SIGNATURE 0x50434300
/* Generic Communications Channel Command Field */
#define PCC_CMD_GENERATE_DB_INTR BIT(15)
/* Generic Communications Channel Status Field */
#define PCC_STATUS_CMD_COMPLETE BIT(0)
#define PCC_STATUS_SCI_DOORBELL BIT(1)
#define PCC_STATUS_ERROR BIT(2)
#define PCC_STATUS_PLATFORM_NOTIFY BIT(3)
/* Initiator Responder Communications Channel Flags */
#define PCC_CMD_COMPLETION_NOTIFY BIT(0)
#define MAX_PCC_SUBSPACES 256 #define MAX_PCC_SUBSPACES 256
#ifdef CONFIG_PCC #ifdef CONFIG_PCC
extern struct pcc_mbox_chan * extern struct pcc_mbox_chan *
pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id); pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
......
...@@ -787,6 +787,11 @@ static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) ...@@ -787,6 +787,11 @@ static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
struct acpi_device; struct acpi_device;
static inline bool acpi_dev_uid_match(struct acpi_device *adev, const char *uid2)
{
return false;
}
static inline bool static inline bool
acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2) acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2)
{ {
......
...@@ -291,7 +291,7 @@ static inline void pnp_set_drvdata(struct pnp_dev *pdev, void *data) ...@@ -291,7 +291,7 @@ static inline void pnp_set_drvdata(struct pnp_dev *pdev, void *data)
struct pnp_fixup { struct pnp_fixup {
char id[7]; char id[7];
void (*quirk_function) (struct pnp_dev * dev); /* fixup function */ void (*quirk_function) (struct pnp_dev *dev); /* fixup function */
}; };
/* config parameters */ /* config parameters */
...@@ -419,8 +419,8 @@ struct pnp_protocol { ...@@ -419,8 +419,8 @@ struct pnp_protocol {
/* protocol specific suspend/resume */ /* protocol specific suspend/resume */
bool (*can_wakeup) (struct pnp_dev *dev); bool (*can_wakeup) (struct pnp_dev *dev);
int (*suspend) (struct pnp_dev * dev, pm_message_t state); int (*suspend) (struct pnp_dev *dev, pm_message_t state);
int (*resume) (struct pnp_dev * dev); int (*resume) (struct pnp_dev *dev);
/* used by pnp layer only (look but don't touch) */ /* used by pnp layer only (look but don't touch) */
unsigned char number; /* protocol number */ unsigned char number; /* protocol number */
...@@ -492,7 +492,7 @@ static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } ...@@ -492,7 +492,7 @@ static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_range_reserved(resource_size_t start, resource_size_t end) { return 0;} static inline int pnp_range_reserved(resource_size_t start, resource_size_t end) { return 0; }
/* protocol helpers */ /* protocol helpers */
static inline int pnp_is_active(struct pnp_dev *dev) { return 0; } static inline int pnp_is_active(struct pnp_dev *dev) { return 0; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment