Commit d4b671d4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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
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
===========

+41 −57
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/string_choices.h>
#include <linux/acpi.h>
#include <acpi/battery.h>

@@ -32,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI AC Adapter Driver");
MODULE_LICENSE("GPL");

static int acpi_ac_add(struct acpi_device *device);
static void acpi_ac_remove(struct acpi_device *device);
static int acpi_ac_probe(struct platform_device *pdev);
static void acpi_ac_remove(struct platform_device *pdev);

static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);

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);
static int ac_sleep_before_get_state_ms;
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 power_supply *charger;
	struct power_supply_desc charger_desc;
@@ -128,15 +119,12 @@ static enum power_supply_property ac_props[] = {
/* Driver Model */
static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
{
	struct acpi_device *device = data;
	struct acpi_ac *ac = acpi_driver_data(device);

	if (!ac)
		return;
	struct acpi_ac *ac = data;
	struct acpi_device *adev = ac->device;

	switch (event) {
	default:
		acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
		acpi_handle_debug(adev->handle, "Unsupported event [0x%x]\n",
				  event);
		fallthrough;
	case ACPI_AC_NOTIFY_STATUS:
@@ -153,10 +141,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
			msleep(ac_sleep_before_get_state_ms);

		acpi_ac_get_state(ac);
		acpi_bus_generate_netlink_event(device->pnp.device_class,
						  dev_name(&device->dev), event,
		acpi_bus_generate_netlink_event(adev->pnp.device_class,
						  dev_name(&adev->dev), event,
						  (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);
	}
}
@@ -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 = {};
	int result = 0;
	struct acpi_ac *ac = NULL;


	if (!device)
		return -EINVAL;
	struct acpi_ac *ac;
	int result;

	ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
	if (!ac)
		return -ENOMEM;

	ac->device = device;
	strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_AC_CLASS);
	device->driver_data = ac;
	ac->device = adev;
	strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
	strcpy(acpi_device_class(adev), ACPI_AC_CLASS);

	platform_set_drvdata(pdev, ac);

	result = acpi_ac_get_state(ac);
	if (result)
@@ -238,26 +224,26 @@ static int acpi_ac_add(struct acpi_device *device)

	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.properties = ac_props;
	ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
	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);
	if (IS_ERR(ac->charger)) {
		result = PTR_ERR(ac->charger);
		goto err_release_ac;
	}

	pr_info("%s [%s] (%s)\n", acpi_device_name(device),
		acpi_device_bid(device), ac->state ? "on-line" : "off-line");
	pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
		acpi_device_bid(adev), str_on_off(ac->state));

	ac->battery_nb.notifier_call = acpi_ac_battery_notify;
	register_acpi_notifier(&ac->battery_nb);

	result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
						 acpi_ac_notify);
	result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
						 acpi_ac_notify, ac);
	if (result)
		goto err_unregister;

@@ -275,16 +261,9 @@ static int acpi_ac_add(struct acpi_device *device)
#ifdef CONFIG_PM_SLEEP
static int acpi_ac_resume(struct device *dev)
{
	struct acpi_ac *ac;
	struct acpi_ac *ac = dev_get_drvdata(dev);
	unsigned int old_state;

	if (!dev)
		return -EINVAL;

	ac = acpi_driver_data(to_acpi_device(dev));
	if (!ac)
		return -EINVAL;

	old_state = ac->state;
	if (acpi_ac_get_state(ac))
		return 0;
@@ -297,16 +276,11 @@ static int acpi_ac_resume(struct device *dev)
#define acpi_ac_resume NULL
#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))
		return;

	ac = acpi_driver_data(device);

	acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
	acpi_dev_remove_notify_handler(ac->device, ACPI_ALL_NOTIFY,
				       acpi_ac_notify);
	power_supply_unregister(ac->charger);
	unregister_acpi_notifier(&ac->battery_nb);
@@ -314,6 +288,16 @@ static void acpi_ac_remove(struct acpi_device *device)
	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)
{
	int result;
@@ -326,7 +310,7 @@ static int __init acpi_ac_init(void)

	dmi_check_system(ac_dmi_table);

	result = acpi_bus_register_driver(&acpi_ac_driver);
	result = platform_driver_register(&acpi_ac_driver);
	if (result < 0)
		return -ENODEV;

@@ -335,7 +319,7 @@ static int __init acpi_ac_init(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_exit(acpi_ac_exit);
+37 −8
Original line number Diff line number Diff line
@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
		record_header = (void *)subtable_header + offset;
		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) {
		case RECORD_S3_RESUME:
			if (subtable_type != SUBTABLE_S3PT) {
				pr_err(FW_BUG "Invalid record %d for subtable %s\n",
				     record_header->type, signature);
				return -EINVAL;
				result = -EINVAL;
				goto err;
			}
			if (record_resume) {
				pr_err("Duplicate resume performance record found.\n");
@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
			record_resume = (struct resume_performance_record *)record_header;
			result = sysfs_create_group(fpdt_kobj, &resume_attr_group);
			if (result)
				return result;
				goto err;
			break;
		case RECORD_S3_SUSPEND:
			if (subtable_type != SUBTABLE_S3PT) {
@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
			record_suspend = (struct suspend_performance_record *)record_header;
			result = sysfs_create_group(fpdt_kobj, &suspend_attr_group);
			if (result)
				return result;
				goto err;
			break;
		case RECORD_BOOT:
			if (subtable_type != SUBTABLE_FBPT) {
				pr_err(FW_BUG "Invalid %d for subtable %s\n",
				     record_header->type, signature);
				return -EINVAL;
				result = -EINVAL;
				goto err;
			}
			if (record_boot) {
				pr_err("Duplicate boot performance record found.\n");
@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
			record_boot = (struct boot_performance_record *)record_header;
			result = sysfs_create_group(fpdt_kobj, &boot_attr_group);
			if (result)
				return result;
				goto err;
			break;

		default:
@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
		}
	}
	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)
@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void)
	struct acpi_table_header *header;
	struct fpdt_subtable_entry *subtable;
	u32 offset = sizeof(*header);
	int result;

	status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);

@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void)

	fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
	if (!fpdt_kobj) {
		acpi_put_table(header);
		return -ENOMEM;
		result = -ENOMEM;
		goto err_nomem;
	}

	while (offset < header->length) {
@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void)
		switch (subtable->type) {
		case SUBTABLE_FBPT:
		case SUBTABLE_S3PT:
			fpdt_process_subtable(subtable->address,
			result = fpdt_process_subtable(subtable->address,
					      subtable->type);
			if (result)
				goto err_subtable;
			break;
		default:
			/* Other types are reserved in ACPI 6.4 spec. */
@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void)
		offset += sizeof(*subtable);
	}
	return 0;
err_subtable:
	kobject_put(fpdt_kobj);

err_nomem:
	acpi_put_table(header);
	return result;
}

fs_initcall(acpi_init_fpdt);
+10 −11
Original line number Diff line number Diff line
@@ -368,7 +368,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
	{ "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) },
	{ "INT33C5", LPSS_ADDR(lpt_uart_dev_desc) },
	{ "INT33C6", LPSS_ADDR(lpt_sdio_dev_desc) },
	{ "INT33C7", },

	/* BayTrail LPSS devices */
	{ "80860F09", LPSS_ADDR(byt_pwm_dev_desc) },
@@ -376,8 +375,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
	{ "80860F0E", LPSS_ADDR(byt_spi_dev_desc) },
	{ "80860F14", LPSS_ADDR(byt_sdio_dev_desc) },
	{ "80860F41", LPSS_ADDR(byt_i2c_dev_desc) },
	{ "INT33B2", },
	{ "INT33FC", },

	/* Braswell LPSS devices */
	{ "80862286", LPSS_ADDR(lpss_dma_desc) },
@@ -396,7 +393,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
	{ "INT3434", LPSS_ADDR(lpt_uart_dev_desc) },
	{ "INT3435", LPSS_ADDR(lpt_uart_dev_desc) },
	{ "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
	{ "INT3437", },

	/* Wildcat Point LPSS devices */
	{ "INT3438", LPSS_ADDR(lpt_spi_dev_desc) },
@@ -578,6 +574,7 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
{
	struct acpi_handle_list dep_devices;
	acpi_status status;
	bool ret = false;
	int i;

	if (!acpi_has_method(adev->handle, "_DEP"))
@@ -591,11 +588,14 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle)
	}

	for (i = 0; i < dep_devices.count; i++) {
		if (dep_devices.handles[i] == handle)
			return true;
		if (dep_devices.handles[i] == handle) {
			ret = true;
			break;
		}
	}

	return false;
	acpi_handle_list_free(&dep_devices);
	return ret;
}

static void acpi_lpss_link_consumer(struct device *dev1,
@@ -657,10 +657,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
	int ret;

	dev_desc = (const struct lpss_device_desc *)id->driver_data;
	if (!dev_desc) {
		pdev = acpi_create_platform_device(adev, NULL);
		return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
	}
	if (!dev_desc)
		return -EINVAL;

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
+31 −51
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <asm/mwait.h>
#include <xen/xen.h>

@@ -336,33 +337,14 @@ static ssize_t idlecpus_show(struct device *dev,

static DEVICE_ATTR_RW(idlecpus);

static int acpi_pad_add_sysfs(struct acpi_device *device)
{
	int result;

	result = device_create_file(&device->dev, &dev_attr_idlecpus);
	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 struct attribute *acpi_pad_attrs[] = {
	&dev_attr_idlecpus.attr,
	&dev_attr_idlepct.attr,
	&dev_attr_rrtime.attr,
	NULL
};

static void acpi_pad_remove_sysfs(struct acpi_device *device)
{
	device_remove_file(&device->dev, &dev_attr_idlecpus);
	device_remove_file(&device->dev, &dev_attr_idlepct);
	device_remove_file(&device->dev, &dev_attr_rrtime);
}
ATTRIBUTE_GROUPS(acpi_pad);

/*
 * Query firmware how many CPUs should be idle
@@ -416,13 +398,13 @@ static void acpi_pad_handle_notify(acpi_handle handle)
static void acpi_pad_notify(acpi_handle handle, u32 event,
	void *data)
{
	struct acpi_device *device = data;
	struct acpi_device *adev = data;

	switch (event) {
	case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
		acpi_pad_handle_notify(handle);
		acpi_bus_generate_netlink_event(device->pnp.device_class,
			dev_name(&device->dev), event, 0);
		acpi_bus_generate_netlink_event(adev->pnp.device_class,
			dev_name(&adev->dev), event, 0);
		break;
	default:
		pr_warn("Unsupported event [0x%x]\n", 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;

	strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);
	strcpy(acpi_device_name(adev), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
	strcpy(acpi_device_class(adev), ACPI_PROCESSOR_AGGREGATOR_CLASS);

	if (acpi_pad_add_sysfs(device))
		return -ENODEV;
	status = acpi_install_notify_handler(adev->handle,
		ACPI_DEVICE_NOTIFY, acpi_pad_notify, adev);

	status = acpi_install_notify_handler(device->handle,
		ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
	if (ACPI_FAILURE(status)) {
		acpi_pad_remove_sysfs(device);
	if (ACPI_FAILURE(status))
		return -ENODEV;
	}

	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);
	acpi_pad_idle_cpus(0);
	mutex_unlock(&isolated_cpus_lock);

	acpi_remove_notify_handler(device->handle,
	acpi_remove_notify_handler(adev->handle,
		ACPI_DEVICE_NOTIFY, acpi_pad_notify);
	acpi_pad_remove_sysfs(device);
}

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

static struct acpi_driver acpi_pad_driver = {
static struct platform_driver acpi_pad_driver = {
	.probe = acpi_pad_probe,
	.remove_new = acpi_pad_remove,
	.driver = {
		.dev_groups = acpi_pad_groups,
		.name = "processor_aggregator",
	.class = ACPI_PROCESSOR_AGGREGATOR_CLASS,
	.ids = pad_device_ids,
	.ops = {
		.add = acpi_pad_add,
		.remove = acpi_pad_remove,
		.acpi_match_table = pad_device_ids,
	},
};

@@ -487,12 +467,12 @@ static int __init acpi_pad_init(void)
	if (power_saving_mwait_eax == 0)
		return -EINVAL;

	return acpi_bus_register_driver(&acpi_pad_driver);
	return platform_driver_register(&acpi_pad_driver);
}

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