aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/driver-api/acpi/acpi-drivers.rst80
-rw-r--r--Documentation/driver-api/acpi/index.rst1
-rw-r--r--drivers/acpi/acpi_platform.c40
-rw-r--r--drivers/acpi/acpi_video.c62
-rw-r--r--drivers/acpi/bus.c3
-rw-r--r--drivers/acpi/button.c128
-rw-r--r--drivers/acpi/device_pm.c9
-rw-r--r--drivers/acpi/ec.c54
-rw-r--r--drivers/acpi/hed.c23
-rw-r--r--drivers/acpi/nfit/core.c47
-rw-r--r--drivers/acpi/sbs.c48
-rw-r--r--drivers/acpi/sbshc.c43
-rw-r--r--drivers/acpi/scan.c65
-rw-r--r--drivers/acpi/thermal.c90
-rw-r--r--drivers/acpi/tiny-power-button.c25
15 files changed, 380 insertions, 338 deletions
diff --git a/Documentation/driver-api/acpi/acpi-drivers.rst b/Documentation/driver-api/acpi/acpi-drivers.rst
new file mode 100644
index 000000000000..b1fbbddb8b4f
--- /dev/null
+++ b/Documentation/driver-api/acpi/acpi-drivers.rst
@@ -0,0 +1,80 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: <isonum.txt>
+
+=========================================
+Why using ACPI drivers is not a good idea
+=========================================
+
+:Copyright: |copy| 2026, Intel Corporation
+
+:Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+Even though binding drivers directly to struct acpi_device objects, also
+referred to as "ACPI device nodes", allows basic functionality to be provided
+at least in some cases, there are problems with it, related to general
+consistency, sysfs layout, power management operation ordering, and code
+cleanliness.
+
+First of all, ACPI device nodes represent firmware entities rather than
+hardware and in many cases they provide auxiliary information on devices
+enumerated independently (like PCI devices or CPUs). It is therefore generally
+questionable to assign resources to them because the entities represented by
+them do not decode addresses in the memory or I/O address spaces and do not
+generate interrupts or similar (all of that is done by hardware).
+
+Second, as a general rule, a struct acpi_device can only be a parent of another
+struct acpi_device. If that is not the case, the location of the child device
+in the device hierarchy is at least confusing and it may not be straightforward
+to identify the piece of hardware providing functionality represented by it.
+However, binding a driver directly to an ACPI device node may cause that to
+happen if the given driver registers input devices or wakeup sources under it,
+for example.
+
+Next, using system suspend and resume callbacks directly on ACPI device nodes
+is also questionable because it may cause ordering problems to appear. Namely,
+ACPI device nodes are registered before enumerating hardware corresponding to
+them and they land on the PM list in front of the majority of other device
+objects. Consequently, the execution ordering of their PM callbacks may be
+different from what is generally expected. Also, in general, dependencies
+returned by _DEP objects do not affect ACPI device nodes themselves, but the
+"physical" devices associated with them, which potentially is one more source
+of inconsistency related to treating ACPI device nodes as "real" device
+representation.
+
+All of the above means that binding drivers to ACPI device nodes should
+generally be avoided and so struct acpi_driver objects should not be used.
+
+Moreover, a device ID is necessary to bind a driver directly to an ACPI device
+node, but device IDs are not generally associated with all of them. Some of
+them contain alternative information allowing the corresponding pieces of
+hardware to be identified, for example represeted by an _ADR object return
+value, and device IDs are not used in those cases. In consequence, confusingly
+enough, binding an ACPI driver to an ACPI device node may even be impossible.
+
+When that happens, the piece of hardware corresponding to the given ACPI device
+node is represented by another device object, like a struct pci_dev, and the
+ACPI device node is the "ACPI companion" of that device, accessible through its
+fwnode pointer used by the ACPI_COMPANION() macro. The ACPI companion holds
+additional information on the device configuration and possibly some "recipes"
+on device manipulation in the form of AML (ACPI Machine Language) bytecode
+provided by the platform firmware. Thus the role of the ACPI device node is
+similar to the role of a struct device_node on a system where Device Tree is
+used for platform description.
+
+For consistency, this approach has been extended to the cases in which ACPI
+device IDs are used. Namely, in those cases, an additional device object is
+created to represent the piece of hardware corresponding to a given ACPI device
+node. By default, it is a platform device, but it may also be a PNP device, a
+CPU device, or another type of device, depending on what the given piece of
+hardware actually is. There are even cases in which multiple devices are
+"backed" or "accompanied" by one ACPI device node (e.g. ACPI device nodes
+corresponding to GPUs that may provide firmware interfaces for backlight
+brightness control in addition to GPU configuration information).
+
+This means that it really should never be necessary to bind a driver directly to
+an ACPI device node because there is a "proper" device object representing the
+corresponding piece of hardware that can be bound to by a "proper" driver using
+the given ACPI device node as the device's ACPI companion. Thus, in principle,
+there is no reason to use ACPI drivers and if they all were replaced with other
+driver types (for example, platform drivers), some code could be dropped and
+some complexity would go away.
diff --git a/Documentation/driver-api/acpi/index.rst b/Documentation/driver-api/acpi/index.rst
index ace0008e54c2..2b10d83f9994 100644
--- a/Documentation/driver-api/acpi/index.rst
+++ b/Documentation/driver-api/acpi/index.rst
@@ -7,3 +7,4 @@ ACPI Support
linuxized-acpica
scan_handlers
+ acpi-drivers
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 48d15dd785f6..0ec1afc744f5 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -114,13 +114,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo;
const struct acpi_device_id *match;
- struct resource_entry *rentry;
- struct list_head resource_list;
struct resource *resources = NULL;
- int count;
+ int count = 0;
/* If the ACPI node already has a physical device attached, skip it. */
- if (adev->physical_node_count)
+ if (adev->physical_node_count && !adev->pnp.type.backlight)
return NULL;
match = acpi_match_acpi_device(forbidden_id_list, adev);
@@ -137,22 +135,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
}
}
- INIT_LIST_HEAD(&resource_list);
- count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
- if (count < 0)
- return NULL;
- if (count > 0) {
- resources = kcalloc(count, sizeof(*resources), GFP_KERNEL);
- if (!resources) {
+ if (adev->device_type == ACPI_BUS_TYPE_DEVICE && !adev->pnp.type.backlight) {
+ LIST_HEAD(resource_list);
+
+ count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+ if (count < 0)
+ return ERR_PTR(-ENODATA);
+
+ if (count > 0) {
+ struct resource_entry *rentry;
+
+ resources = kcalloc(count, sizeof(*resources), GFP_KERNEL);
+ if (!resources) {
+ acpi_dev_free_resource_list(&resource_list);
+ return ERR_PTR(-ENOMEM);
+ }
+ count = 0;
+ list_for_each_entry(rentry, &resource_list, node)
+ acpi_platform_fill_resource(adev, rentry->res,
+ &resources[count++]);
+
acpi_dev_free_resource_list(&resource_list);
- return ERR_PTR(-ENOMEM);
}
- count = 0;
- list_for_each_entry(rentry, &resource_list, node)
- acpi_platform_fill_resource(adev, rentry->res,
- &resources[count++]);
-
- acpi_dev_free_resource_list(&resource_list);
}
memset(&pdevinfo, 0, sizeof(pdevinfo));
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index be8e7e18abca..69469757b965 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -21,6 +21,7 @@
#include <linux/sort.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/suspend.h>
@@ -76,8 +77,8 @@ static int register_count;
static DEFINE_MUTEX(register_count_mutex);
static DEFINE_MUTEX(video_list_lock);
static LIST_HEAD(video_bus_head);
-static int acpi_video_bus_add(struct acpi_device *device);
-static void acpi_video_bus_remove(struct acpi_device *device);
+static int acpi_video_bus_probe(struct platform_device *pdev);
+static void acpi_video_bus_remove(struct platform_device *pdev);
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
/*
@@ -98,14 +99,13 @@ static const struct acpi_device_id video_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, video_device_ids);
-static struct acpi_driver acpi_video_bus = {
- .name = "video",
- .class = ACPI_VIDEO_CLASS,
- .ids = video_device_ids,
- .ops = {
- .add = acpi_video_bus_add,
- .remove = acpi_video_bus_remove,
- },
+static struct platform_driver acpi_video_bus = {
+ .probe = acpi_video_bus_probe,
+ .remove = acpi_video_bus_remove,
+ .driver = {
+ .name = "acpi-video",
+ .acpi_match_table = video_device_ids,
+ },
};
struct acpi_video_bus_flags {
@@ -1134,13 +1134,11 @@ static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg)
struct acpi_video_bus *video = arg;
struct acpi_video_device_attrib *attribute;
struct acpi_video_device *data;
- unsigned long long device_id;
- acpi_status status;
int device_type;
+ u64 device_id;
- status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
/* Skip devices without _ADR instead of failing. */
- if (ACPI_FAILURE(status))
+ if (acpi_get_local_u64_address(device->handle, &device_id))
goto exit;
data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
@@ -1540,14 +1538,11 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct acpi_video_bus *video = acpi_driver_data(device);
+ struct acpi_video_bus *video = data;
+ struct acpi_device *device = video->device;
struct input_dev *input;
int keycode = 0;
- if (!video || !video->input)
- return;
-
input = video->input;
switch (event) {
@@ -1891,7 +1886,8 @@ static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device)
device->flags.notify = 1;
}
-static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video)
+static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video,
+ struct platform_device *pdev)
{
struct input_dev *input;
struct acpi_video_device *dev;
@@ -1914,7 +1910,7 @@ static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video)
input->phys = video->phys;
input->id.bustype = BUS_HOST;
input->id.product = 0x06;
- input->dev.parent = &video->device->dev;
+ input->dev.parent = &pdev->dev;
input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
set_bit(KEY_VIDEO_NEXT, input->keybit);
@@ -1986,8 +1982,9 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
static int instance;
-static int acpi_video_bus_add(struct acpi_device *device)
+static int acpi_video_bus_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_video_bus *video;
bool auto_detect;
int error;
@@ -2024,6 +2021,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
instance++;
}
+ platform_set_drvdata(pdev, video);
+
video->device = device;
strscpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
strscpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -2071,12 +2070,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
!auto_detect)
acpi_video_bus_register_backlight(video);
- error = acpi_video_bus_add_notify_handler(video);
+ error = acpi_video_bus_add_notify_handler(video, pdev);
if (error)
goto err_del;
error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify, device);
+ acpi_video_bus_notify, video);
if (error)
goto err_remove;
@@ -2099,15 +2098,10 @@ err_free_video:
return error;
}
-static void acpi_video_bus_remove(struct acpi_device *device)
+static void acpi_video_bus_remove(struct platform_device *pdev)
{
- struct acpi_video_bus *video = NULL;
-
-
- if (!device || !acpi_driver_data(device))
- return;
-
- video = acpi_driver_data(device);
+ struct acpi_video_bus *video = platform_get_drvdata(pdev);
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_video_bus_notify);
@@ -2170,7 +2164,7 @@ int acpi_video_register(void)
dmi_check_system(video_dmi_table);
- ret = acpi_bus_register_driver(&acpi_video_bus);
+ ret = platform_driver_register(&acpi_video_bus);
if (ret)
goto leave;
@@ -2190,7 +2184,7 @@ void acpi_video_unregister(void)
{
mutex_lock(&register_count_mutex);
if (register_count) {
- acpi_bus_unregister_driver(&acpi_video_bus);
+ platform_driver_unregister(&acpi_video_bus);
register_count = 0;
may_report_brightness_keys = false;
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 2ec095e2009e..f6707325f582 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -818,6 +818,9 @@ const struct acpi_device *acpi_companion_match(const struct device *dev)
if (list_empty(&adev->pnp.ids))
return NULL;
+ if (adev->pnp.type.backlight)
+ return adev;
+
return acpi_primary_dev_companion(adev, dev);
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 3c6dd9b4ba0a..b899b8745fed 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
+#include <linux/platform_device.h>
#include <acpi/button.h>
#define ACPI_BUTTON_CLASS "button"
@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
{}
};
-static int acpi_button_add(struct acpi_device *device);
-static void acpi_button_remove(struct acpi_device *device);
+static int acpi_button_probe(struct platform_device *pdev);
+static void acpi_button_remove(struct platform_device *pdev);
#ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev);
@@ -157,18 +158,19 @@ static int acpi_button_resume(struct device *dev);
#endif
static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
-static struct acpi_driver acpi_button_driver = {
- .name = "button",
- .class = ACPI_BUTTON_CLASS,
- .ids = button_device_ids,
- .ops = {
- .add = acpi_button_add,
- .remove = acpi_button_remove,
+static struct platform_driver acpi_button_driver = {
+ .probe = acpi_button_probe,
+ .remove = acpi_button_remove,
+ .driver = {
+ .name = "acpi-button",
+ .acpi_match_table = button_device_ids,
+ .pm = &acpi_button_pm,
},
- .drv.pm = &acpi_button_pm,
};
struct acpi_button {
+ struct acpi_device *adev;
+ struct platform_device *pdev;
unsigned int type;
struct input_dev *input;
char phys[32]; /* for input device */
@@ -202,9 +204,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device)
return lid_state ? 1 : 0;
}
-static int acpi_lid_notify_state(struct acpi_device *device, int state)
+static int acpi_lid_notify_state(struct acpi_button *button, int state)
{
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_device *device = button->adev;
ktime_t next_report;
bool do_update;
@@ -287,18 +289,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
void *offset)
{
- struct acpi_device *device = seq->private;
+ struct acpi_button *button = seq->private;
int state;
- state = acpi_lid_evaluate_state(device);
+ state = acpi_lid_evaluate_state(button->adev);
seq_printf(seq, "state: %s\n",
state < 0 ? "unsupported" : (state ? "open" : "closed"));
return 0;
}
-static int acpi_button_add_fs(struct acpi_device *device)
+static int acpi_button_add_fs(struct acpi_button *button)
{
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_device *device = button->adev;
struct proc_dir_entry *entry = NULL;
int ret = 0;
@@ -333,7 +335,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
/* create /proc/acpi/button/lid/LID/state */
entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO,
acpi_device_dir(device), acpi_button_state_seq_show,
- device);
+ button);
if (!entry) {
ret = -ENODEV;
goto remove_dev_dir;
@@ -355,9 +357,9 @@ remove_button_dir:
goto done;
}
-static int acpi_button_remove_fs(struct acpi_device *device)
+static int acpi_button_remove_fs(struct acpi_button *button)
{
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_device *device = button->adev;
if (button->type != ACPI_BUTTON_TYPE_LID)
return 0;
@@ -385,9 +387,10 @@ int acpi_lid_open(void)
}
EXPORT_SYMBOL(acpi_lid_open);
-static int acpi_lid_update_state(struct acpi_device *device,
+static int acpi_lid_update_state(struct acpi_button *button,
bool signal_wakeup)
{
+ struct acpi_device *device = button->adev;
int state;
state = acpi_lid_evaluate_state(device);
@@ -395,21 +398,19 @@ static int acpi_lid_update_state(struct acpi_device *device,
return state;
if (state && signal_wakeup)
- acpi_pm_wakeup_event(&device->dev);
+ acpi_pm_wakeup_event(&button->pdev->dev);
- return acpi_lid_notify_state(device, state);
+ return acpi_lid_notify_state(button, state);
}
-static void acpi_lid_initialize_state(struct acpi_device *device)
+static void acpi_lid_initialize_state(struct acpi_button *button)
{
- struct acpi_button *button = acpi_driver_data(device);
-
switch (lid_init_state) {
case ACPI_BUTTON_LID_INIT_OPEN:
- (void)acpi_lid_notify_state(device, 1);
+ (void)acpi_lid_notify_state(button, 1);
break;
case ACPI_BUTTON_LID_INIT_METHOD:
- (void)acpi_lid_update_state(device, false);
+ (void)acpi_lid_update_state(button, false);
break;
case ACPI_BUTTON_LID_INIT_IGNORE:
default:
@@ -421,8 +422,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct acpi_button *button;
+ struct acpi_button *button = data;
+ struct acpi_device *device = button->adev;
if (event != ACPI_BUTTON_NOTIFY_STATUS) {
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
@@ -430,17 +431,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
return;
}
- button = acpi_driver_data(device);
if (!button->lid_state_initialized)
return;
- acpi_lid_update_state(device, true);
+ acpi_lid_update_state(button, true);
}
static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct acpi_button *button;
+ struct acpi_button *button = data;
+ struct acpi_device *device = button->adev;
struct input_dev *input;
int keycode;
@@ -455,9 +455,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
return;
}
- acpi_pm_wakeup_event(&device->dev);
+ acpi_pm_wakeup_event(&button->pdev->dev);
- button = acpi_driver_data(device);
if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
return;
@@ -488,8 +487,7 @@ static u32 acpi_button_event(void *data)
#ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev)
{
- struct acpi_device *device = to_acpi_device(dev);
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_button *button = dev_get_drvdata(dev);
button->suspended = true;
return 0;
@@ -497,15 +495,15 @@ static int acpi_button_suspend(struct device *dev)
static int acpi_button_resume(struct device *dev)
{
+ struct acpi_button *button = dev_get_drvdata(dev);
+ struct acpi_device *device = ACPI_COMPANION(dev);
struct input_dev *input;
- struct acpi_device *device = to_acpi_device(dev);
- struct acpi_button *button = acpi_driver_data(device);
button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID) {
button->last_state = !!acpi_lid_evaluate_state(device);
button->last_time = ktime_get();
- acpi_lid_initialize_state(device);
+ acpi_lid_initialize_state(button);
}
if (button->type == ACPI_BUTTON_TYPE_POWER) {
@@ -521,18 +519,19 @@ static int acpi_button_resume(struct device *dev)
static int acpi_lid_input_open(struct input_dev *input)
{
- struct acpi_device *device = input_get_drvdata(input);
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_button *button = input_get_drvdata(input);
+ struct acpi_device *device = button->adev;
button->last_state = !!acpi_lid_evaluate_state(device);
button->last_time = ktime_get();
- acpi_lid_initialize_state(device);
+ acpi_lid_initialize_state(button);
return 0;
}
-static int acpi_button_add(struct acpi_device *device)
+static int acpi_button_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_notify_handler handler;
struct acpi_button *button;
struct input_dev *input;
@@ -549,8 +548,10 @@ static int acpi_button_add(struct acpi_device *device)
if (!button)
return -ENOMEM;
- device->driver_data = button;
+ platform_set_drvdata(pdev, button);
+ button->pdev = pdev;
+ button->adev = device;
button->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
@@ -587,7 +588,7 @@ static int acpi_button_add(struct acpi_device *device)
}
if (!error)
- error = acpi_button_add_fs(device);
+ error = acpi_button_add_fs(button);
if (error) {
input_free_device(input);
@@ -600,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device)
input->phys = button->phys;
input->id.bustype = BUS_HOST;
input->id.product = button->type;
- input->dev.parent = &device->dev;
+ input->dev.parent = &pdev->dev;
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
@@ -617,7 +618,7 @@ static int acpi_button_add(struct acpi_device *device)
break;
}
- input_set_drvdata(input, device);
+ input_set_drvdata(input, button);
error = input_register_device(input);
if (error) {
input_free_device(input);
@@ -628,17 +629,17 @@ static int acpi_button_add(struct acpi_device *device)
case ACPI_BUS_TYPE_POWER_BUTTON:
status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
acpi_button_event,
- device);
+ button);
break;
case ACPI_BUS_TYPE_SLEEP_BUTTON:
status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
acpi_button_event,
- device);
+ button);
break;
default:
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY, handler,
- device);
+ button);
break;
}
if (ACPI_FAILURE(status)) {
@@ -654,22 +655,23 @@ static int acpi_button_add(struct acpi_device *device)
lid_device = device;
}
- device_init_wakeup(&device->dev, true);
+ device_init_wakeup(&pdev->dev, true);
pr_info("%s [%s]\n", name, acpi_device_bid(device));
return 0;
err_input_unregister:
input_unregister_device(input);
err_remove_fs:
- acpi_button_remove_fs(device);
+ acpi_button_remove_fs(button);
err_free_button:
kfree(button);
return error;
}
-static void acpi_button_remove(struct acpi_device *device)
+static void acpi_button_remove(struct platform_device *pdev)
{
- struct acpi_button *button = acpi_driver_data(device);
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ struct acpi_button *button = platform_get_drvdata(pdev);
switch (device->device_type) {
case ACPI_BUS_TYPE_POWER_BUTTON:
@@ -689,7 +691,7 @@ static void acpi_button_remove(struct acpi_device *device)
}
acpi_os_wait_events_complete();
- acpi_button_remove_fs(device);
+ acpi_button_remove_fs(button);
input_unregister_device(button->input);
kfree(button);
}
@@ -728,7 +730,7 @@ module_param_call(lid_init_state,
NULL, 0644);
MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
-static int acpi_button_register_driver(struct acpi_driver *driver)
+static int __init acpi_button_init(void)
{
const struct dmi_system_id *dmi_id;
@@ -744,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver)
* Modules such as nouveau.ko and i915.ko have a link time dependency
* on acpi_lid_open(), and would therefore not be loadable on ACPI
* capable kernels booted in non-ACPI mode if the return value of
- * acpi_bus_register_driver() is returned from here with ACPI disabled
+ * platform_driver_register() is returned from here with ACPI disabled
* when this driver is built as a module.
*/
if (acpi_disabled)
return 0;
- return acpi_bus_register_driver(driver);
+ return platform_driver_register(&acpi_button_driver);
}
-static void acpi_button_unregister_driver(struct acpi_driver *driver)
+static void __exit acpi_button_exit(void)
{
if (!acpi_disabled)
- acpi_bus_unregister_driver(driver);
+ platform_driver_unregister(&acpi_button_driver);
}
-module_driver(acpi_button_driver, acpi_button_register_driver,
- acpi_button_unregister_driver);
+module_init(acpi_button_init);
+module_exit(acpi_button_exit);
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index aa55ecfc2923..f2579611e0a5 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1457,6 +1457,15 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
return 0;
/*
+ * Skip devices whose ACPI companions don't support power management and
+ * don't have a wakeup GPE.
+ */
+ if (!acpi_device_power_manageable(adev) && !acpi_device_can_wakeup(adev)) {
+ dev_dbg(dev, "No ACPI power management or wakeup GPE\n");
+ return 0;
+ }
+
+ /*
* Only attach the power domain to the first device if the
* companion is shared by multiple. This is to prevent doing power
* management twice.
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 59b3d50ff01e..197970339edc 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -1674,8 +1675,9 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool ca
return ret;
}
-static int acpi_ec_add(struct acpi_device *device)
+static int acpi_ec_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_ec *ec;
int ret;
@@ -1730,7 +1732,7 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_handle_info(ec->handle,
"EC: Used to handle transactions and events\n");
- device->driver_data = ec;
+ platform_set_drvdata(pdev, ec);
ret = !!request_region(ec->data_addr, 1, "EC data");
WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr);
@@ -1750,14 +1752,11 @@ err:
return ret;
}
-static void acpi_ec_remove(struct acpi_device *device)
+static void acpi_ec_remove(struct platform_device *pdev)
{
- struct acpi_ec *ec;
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ struct acpi_ec *ec = platform_get_drvdata(pdev);
- if (!device)
- return;
-
- ec = acpi_driver_data(device);
release_region(ec->data_addr, 1);
release_region(ec->command_addr, 1);
device->driver_data = NULL;
@@ -2095,8 +2094,7 @@ out:
#ifdef CONFIG_PM_SLEEP
static int acpi_ec_suspend(struct device *dev)
{
- struct acpi_ec *ec =
- acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
if (!pm_suspend_no_platform() && ec_freeze_events)
acpi_ec_disable_event(ec);
@@ -2105,7 +2103,7 @@ static int acpi_ec_suspend(struct device *dev)
static int acpi_ec_suspend_noirq(struct device *dev)
{
- struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
/*
* The SCI handler doesn't run at this point, so the GPE can be
@@ -2122,7 +2120,7 @@ static int acpi_ec_suspend_noirq(struct device *dev)
static int acpi_ec_resume_noirq(struct device *dev)
{
- struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
acpi_ec_leave_noirq(ec);
@@ -2135,8 +2133,7 @@ static int acpi_ec_resume_noirq(struct device *dev)
static int acpi_ec_resume(struct device *dev)
{
- struct acpi_ec *ec =
- acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
acpi_ec_enable_event(ec);
return 0;
@@ -2265,15 +2262,14 @@ module_param_call(ec_event_clearing, param_set_event_clearing, param_get_event_c
NULL, 0644);
MODULE_PARM_DESC(ec_event_clearing, "Assumed SCI_EVT clearing timing");
-static struct acpi_driver acpi_ec_driver = {
- .name = "ec",
- .class = ACPI_EC_CLASS,
- .ids = ec_device_ids,
- .ops = {
- .add = acpi_ec_add,
- .remove = acpi_ec_remove,
- },
- .drv.pm = &acpi_ec_pm,
+static struct platform_driver acpi_ec_driver = {
+ .probe = acpi_ec_probe,
+ .remove = acpi_ec_remove,
+ .driver = {
+ .name = "acpi-ec",
+ .acpi_match_table = ec_device_ids,
+ .pm = &acpi_ec_pm,
+ },
};
static void acpi_ec_destroy_workqueues(void)
@@ -2378,17 +2374,7 @@ void __init acpi_ec_init(void)
}
/* Driver must be registered after acpi_ec_init_workqueues(). */
- acpi_bus_register_driver(&acpi_ec_driver);
+ platform_driver_register(&acpi_ec_driver);
acpi_ec_ecdt_start();
}
-
-/* EC driver currently not unloadable */
-#if 0
-static void __exit acpi_ec_exit(void)
-{
-
- acpi_bus_unregister_driver(&acpi_ec_driver);
- acpi_ec_destroy_workqueues();
-}
-#endif /* 0 */
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index 3499f86c411e..4d5e12ed6f3c 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#include <acpi/hed.h>
static const struct acpi_device_id acpi_hed_ids[] = {
@@ -47,8 +48,9 @@ static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
}
-static int acpi_hed_add(struct acpi_device *device)
+static int acpi_hed_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
int err;
/* Only one hardware error device */
@@ -64,26 +66,27 @@ static int acpi_hed_add(struct acpi_device *device)
return err;
}
-static void acpi_hed_remove(struct acpi_device *device)
+static void acpi_hed_remove(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_hed_notify);
hed_handle = NULL;
}
-static struct acpi_driver acpi_hed_driver = {
- .name = "hardware_error_device",
- .class = "hardware_error",
- .ids = acpi_hed_ids,
- .ops = {
- .add = acpi_hed_add,
- .remove = acpi_hed_remove,
+static struct platform_driver acpi_hed_driver = {
+ .probe = acpi_hed_probe,
+ .remove = acpi_hed_remove,
+ .driver = {
+ .name = "acpi-hardware-error-device",
+ .acpi_match_table = acpi_hed_ids,
},
};
static int __init acpi_hed_driver_init(void)
{
- return acpi_bus_register_driver(&acpi_hed_driver);
+ return platform_driver_register(&acpi_hed_driver);
}
subsys_initcall(acpi_hed_driver_init);
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 3eb56b77cb6d..e19aba02b800 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2,6 +2,7 @@
/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/platform_device.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
@@ -89,15 +90,22 @@ static const guid_t *to_nfit_bus_uuid(int family)
static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
{
struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
+ struct acpi_device *adev;
- /*
- * If provider == 'ACPI.NFIT' we can assume 'dev' is a struct
- * acpi_device.
- */
+ /* If provider == 'ACPI.NFIT', a struct acpi_device is there. */
if (!nd_desc->provider_name
|| strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
return NULL;
+ /*
+ * But it can be the ACPI companion of acpi_desc->dev when it cones from
+ * acpi_nfit_probe().
+ */
+ adev = ACPI_COMPANION(acpi_desc->dev);
+ if (adev)
+ return adev;
+
+ /* Or it is acpi_desc->dev itself when it comes from nfit_ctl_test(). */
return to_acpi_device(acpi_desc->dev);
}
@@ -3283,11 +3291,11 @@ static void acpi_nfit_put_table(void *table)
static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *adev = data;
+ struct device *dev = data;
- device_lock(&adev->dev);
- __acpi_nfit_notify(&adev->dev, handle, event);
- device_unlock(&adev->dev);
+ device_lock(dev);
+ __acpi_nfit_notify(dev, handle, event);
+ device_unlock(dev);
}
static void acpi_nfit_remove_notify_handler(void *data)
@@ -3328,18 +3336,19 @@ void acpi_nfit_shutdown(void *data)
}
EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
-static int acpi_nfit_add(struct acpi_device *adev)
+static int acpi_nfit_probe(struct platform_device *pdev)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_nfit_desc *acpi_desc;
- struct device *dev = &adev->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
- acpi_nfit_notify, adev);
+ acpi_nfit_notify, dev);
if (rc)
return rc;
@@ -3369,7 +3378,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
- acpi_nfit_desc_init(acpi_desc, &adev->dev);
+ acpi_nfit_desc_init(acpi_desc, dev);
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3474,11 +3483,11 @@ static const struct acpi_device_id acpi_nfit_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
-static struct acpi_driver acpi_nfit_driver = {
- .name = KBUILD_MODNAME,
- .ids = acpi_nfit_ids,
- .ops = {
- .add = acpi_nfit_add,
+static struct platform_driver acpi_nfit_driver = {
+ .probe = acpi_nfit_probe,
+ .driver = {
+ .name = "acpi-nfit",
+ .acpi_match_table = acpi_nfit_ids,
},
};
@@ -3516,7 +3525,7 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
- ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3529,7 +3538,7 @@ static __init int nfit_init(void)
static __exit void nfit_exit(void)
{
nfit_mce_unregister();
- acpi_bus_unregister_driver(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index d3edc3bcbf01..85160e475c97 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/platform_data/x86/apple.h>
#include <acpi/battery.h>
@@ -95,7 +96,7 @@ struct acpi_sbs {
#define to_acpi_sbs(x) power_supply_get_drvdata(x)
-static void acpi_sbs_remove(struct acpi_device *device);
+static void acpi_sbs_remove(struct platform_device *pdev);
static int acpi_battery_get_state(struct acpi_battery *battery);
static inline int battery_scale(int log)
@@ -628,8 +629,9 @@ static void acpi_sbs_callback(void *context)
}
}
-static int acpi_sbs_add(struct acpi_device *device)
+static int acpi_sbs_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_sbs *sbs;
int result = 0;
int id;
@@ -642,11 +644,12 @@ static int acpi_sbs_add(struct acpi_device *device)
mutex_init(&sbs->lock);
- sbs->hc = acpi_driver_data(acpi_dev_parent(device));
+ platform_set_drvdata(pdev, sbs);
+
+ sbs->hc = dev_get_drvdata(pdev->dev.parent);
sbs->device = device;
strscpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
strscpy(acpi_device_class(device), ACPI_SBS_CLASS);
- device->driver_data = sbs;
result = acpi_charger_add(sbs);
if (result && result != -ENODEV)
@@ -670,20 +673,15 @@ static int acpi_sbs_add(struct acpi_device *device)
acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end:
if (result)
- acpi_sbs_remove(device);
+ acpi_sbs_remove(pdev);
return result;
}
-static void acpi_sbs_remove(struct acpi_device *device)
+static void acpi_sbs_remove(struct platform_device *pdev)
{
- struct acpi_sbs *sbs;
+ struct acpi_sbs *sbs = platform_get_drvdata(pdev);
int id;
- if (!device)
- return;
- sbs = acpi_driver_data(device);
- if (!sbs)
- return;
mutex_lock(&sbs->lock);
acpi_smbus_unregister_callback(sbs->hc);
for (id = 0; id < MAX_SBS_BAT; ++id)
@@ -697,11 +695,7 @@ static void acpi_sbs_remove(struct acpi_device *device)
#ifdef CONFIG_PM_SLEEP
static int acpi_sbs_resume(struct device *dev)
{
- struct acpi_sbs *sbs;
- if (!dev)
- return -EINVAL;
- sbs = to_acpi_device(dev)->driver_data;
- acpi_sbs_callback(sbs);
+ acpi_sbs_callback(dev_get_drvdata(dev));
return 0;
}
#else
@@ -710,14 +704,14 @@ static int acpi_sbs_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume);
-static struct acpi_driver acpi_sbs_driver = {
- .name = "sbs",
- .class = ACPI_SBS_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_sbs_add,
- .remove = acpi_sbs_remove,
- },
- .drv.pm = &acpi_sbs_pm,
+static struct platform_driver acpi_sbs_driver = {
+ .probe = acpi_sbs_probe,
+ .remove = acpi_sbs_remove,
+ .driver = {
+ .name = "acpi-sbs",
+ .acpi_match_table = sbs_device_ids,
+ .pm = &acpi_sbs_pm,
+ },
};
-module_acpi_driver(acpi_sbs_driver);
+
+module_platform_driver(acpi_sbs_driver);
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index 1a2bf520be23..7fc8ae7396d3 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -13,6 +13,8 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
#include "sbshc.h"
#include "internal.h"
@@ -30,8 +32,8 @@ struct acpi_smb_hc {
bool done;
};
-static int acpi_smbus_hc_add(struct acpi_device *device);
-static void acpi_smbus_hc_remove(struct acpi_device *device);
+static int acpi_smbus_hc_probe(struct platform_device *pdev);
+static void acpi_smbus_hc_remove(struct platform_device *pdev);
static const struct acpi_device_id sbs_device_ids[] = {
{"ACPI0001", 0},
@@ -41,14 +43,13 @@ static const struct acpi_device_id sbs_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
-static struct acpi_driver acpi_smb_hc_driver = {
- .name = "smbus_hc",
- .class = ACPI_SMB_HC_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_smbus_hc_add,
- .remove = acpi_smbus_hc_remove,
- },
+static struct platform_driver acpi_smb_hc_driver = {
+ .probe = acpi_smbus_hc_probe,
+ .remove = acpi_smbus_hc_remove,
+ .driver = {
+ .name = "acpi-smbus-hc",
+ .acpi_match_table = sbs_device_ids,
+ },
};
union acpi_smb_status {
@@ -237,15 +238,13 @@ static int smbus_alarm(void *context)
return 0;
}
-static int acpi_smbus_hc_add(struct acpi_device *device)
+static int acpi_smbus_hc_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
int status;
unsigned long long val;
struct acpi_smb_hc *hc;
- if (!device)
- return -EINVAL;
-
status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
if (ACPI_FAILURE(status)) {
pr_err("error obtaining _EC.\n");
@@ -261,10 +260,11 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
mutex_init(&hc->lock);
init_waitqueue_head(&hc->wait);
- hc->ec = acpi_driver_data(acpi_dev_parent(device));
+ platform_set_drvdata(pdev, hc);
+
+ hc->ec = dev_get_drvdata(pdev->dev.parent);
hc->offset = (val >> 8) & 0xff;
hc->query_bit = val & 0xff;
- device->driver_data = hc;
acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n",
@@ -273,21 +273,18 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
return 0;
}
-static void acpi_smbus_hc_remove(struct acpi_device *device)
+static void acpi_smbus_hc_remove(struct platform_device *pdev)
{
- struct acpi_smb_hc *hc;
-
- if (!device)
- return;
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ struct acpi_smb_hc *hc = platform_get_drvdata(pdev);
- hc = acpi_driver_data(device);
acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
acpi_os_wait_events_complete();
kfree(hc);
device->driver_data = NULL;
}
-module_acpi_driver(acpi_smb_hc_driver);
+module_platform_driver(acpi_smb_hc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexey Starikovskiy");
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fc40dcfa5ffc..565a84a7d7bc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1000,15 +1000,11 @@ static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev)
return err;
}
-/* Do not use a button for S5 wakeup */
-#define ACPI_AVOID_WAKE_FROM_S5 BIT(0)
-
static bool acpi_wakeup_gpe_init(struct acpi_device *device)
{
static const struct acpi_device_id button_device_ids[] = {
- {"PNP0C0C", 0}, /* Power button */
- {"PNP0C0D", ACPI_AVOID_WAKE_FROM_S5}, /* Lid */
- {"PNP0C0E", ACPI_AVOID_WAKE_FROM_S5}, /* Sleep button */
+ {"PNP0C0D", 0}, /* Lid */
+ {"PNP0C0E", 0}, /* Sleep button */
{"", 0},
};
struct acpi_device_wakeup *wakeup = &device->wakeup;
@@ -1017,16 +1013,9 @@ static bool acpi_wakeup_gpe_init(struct acpi_device *device)
wakeup->flags.notifier_present = 0;
- /* Power button, Lid switch always enable wakeup */
match = acpi_match_acpi_device(button_device_ids, device);
- if (match) {
- if ((match->driver_data & ACPI_AVOID_WAKE_FROM_S5) &&
- wakeup->sleep_state == ACPI_STATE_S5)
- wakeup->sleep_state = ACPI_STATE_S4;
- acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
- device_set_wakeup_capable(&device->dev, true);
- return true;
- }
+ if (match && wakeup->sleep_state == ACPI_STATE_S5)
+ wakeup->sleep_state = ACPI_STATE_S4;
status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
wakeup->gpe_number);
@@ -1469,6 +1458,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
break;
case ACPI_BUS_TYPE_THERMAL:
acpi_add_id(pnp, ACPI_THERMAL_HID);
+ pnp->type.platform_id = 1;
break;
case ACPI_BUS_TYPE_POWER_BUTTON:
acpi_add_id(pnp, ACPI_BUTTON_HID_POWERF);
@@ -2349,7 +2339,8 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
if (ret < 0)
return 0;
- if (device->pnp.type.platform_id || device->flags.enumeration_by_parent)
+ if (device->pnp.type.platform_id || device->pnp.type.backlight ||
+ device->flags.enumeration_by_parent)
acpi_default_enumeration(device);
else
acpi_device_set_enumerated(device);
@@ -2590,8 +2581,8 @@ static void acpi_scan_postponed(void)
static void acpi_scan_claim_resources(struct acpi_device *adev)
{
- struct list_head resource_list = LIST_HEAD_INIT(resource_list);
struct resource_entry *rentry;
+ LIST_HEAD(resource_list);
unsigned int count = 0;
const char *regionid;
@@ -2648,7 +2639,6 @@ exit:
acpi_dev_free_resource_list(&resource_list);
}
-
static int __init acpi_reserve_motherboard_resources(void)
{
struct acpi_scan_system_dev *sd, *tmp;
@@ -2741,38 +2731,27 @@ int acpi_bus_register_early_device(int type)
if (result)
return result;
- device->flags.match_driver = true;
- return device_attach(&device->dev);
+ acpi_default_enumeration(device);
+ return 0;
}
EXPORT_SYMBOL_GPL(acpi_bus_register_early_device);
-static void acpi_bus_scan_fixed(void)
+static void acpi_bus_add_fixed_device_object(enum acpi_bus_device_type type)
{
- if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
- struct acpi_device *adev = NULL;
+ struct acpi_device *adev = NULL;
- acpi_add_single_object(&adev, NULL, ACPI_BUS_TYPE_POWER_BUTTON,
- false);
- if (adev) {
- adev->flags.match_driver = true;
- if (device_attach(&adev->dev) >= 0)
- device_init_wakeup(&adev->dev, true);
- else
- dev_dbg(&adev->dev, "No driver\n");
- }
- }
+ acpi_add_single_object(&adev, NULL, type, false);
+ if (adev)
+ acpi_default_enumeration(adev);
+}
- if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) {
- struct acpi_device *adev = NULL;
+static void acpi_bus_scan_fixed(void)
+{
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON))
+ acpi_bus_add_fixed_device_object(ACPI_BUS_TYPE_POWER_BUTTON);
- acpi_add_single_object(&adev, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON,
- false);
- if (adev) {
- adev->flags.match_driver = true;
- if (device_attach(&adev->dev) < 0)
- dev_dbg(&adev->dev, "No driver\n");
- }
- }
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON))
+ acpi_bus_add_fixed_device_object(ACPI_BUS_TYPE_SLEEP_BUTTON);
}
static void __init acpi_get_spcr_uart_addr(void)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index a511f9ea0267..e9d3ab18b404 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -25,6 +25,7 @@
#include <linux/kmod.h>
#include <linux/reboot.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/acpi.h>
#include <linux/workqueue.h>
@@ -670,8 +671,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct acpi_thermal *tz = acpi_driver_data(device);
+ struct acpi_thermal *tz = data;
if (!tz)
return;
@@ -685,8 +685,8 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
acpi_thermal_trips_update(tz, event);
break;
default:
- acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
- event);
+ acpi_handle_debug(tz->device->handle,
+ "Unsupported event [0x%x]\n", event);
break;
}
}
@@ -777,9 +777,10 @@ static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz)
kfree(tz);
}
-static int acpi_thermal_add(struct acpi_device *device)
+static int acpi_thermal_probe(struct platform_device *pdev)
{
struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 };
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_thermal_trip *acpi_trip;
struct thermal_trip *trip;
struct acpi_thermal *tz;
@@ -795,11 +796,12 @@ static int acpi_thermal_add(struct acpi_device *device)
if (!tz)
return -ENOMEM;
+ platform_set_drvdata(pdev, tz);
+
tz->device = device;
strscpy(tz->name, device->pnp.bus_id);
strscpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
strscpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
- device->driver_data = tz;
acpi_thermal_aml_dependency_fix(tz);
@@ -881,7 +883,7 @@ static int acpi_thermal_add(struct acpi_device *device)
acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk));
result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify, device);
+ acpi_thermal_notify, tz);
if (result)
goto flush_wq;
@@ -896,16 +898,11 @@ free_memory:
return result;
}
-static void acpi_thermal_remove(struct acpi_device *device)
+static void acpi_thermal_remove(struct platform_device *pdev)
{
- struct acpi_thermal *tz;
-
- if (!device || !acpi_driver_data(device))
- return;
+ struct acpi_thermal *tz = platform_get_drvdata(pdev);
- tz = acpi_driver_data(device);
-
- acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ acpi_dev_remove_notify_handler(tz->device, ACPI_DEVICE_NOTIFY,
acpi_thermal_notify);
flush_workqueue(acpi_thermal_pm_queue);
@@ -914,44 +911,26 @@ static void acpi_thermal_remove(struct acpi_device *device)
}
#ifdef CONFIG_PM_SLEEP
-static int acpi_thermal_suspend(struct device *dev)
+static int acpi_thermal_prepare(struct device *dev)
{
/* Make sure the previously queued thermal check work has been done */
flush_workqueue(acpi_thermal_pm_queue);
return 0;
}
-static int acpi_thermal_resume(struct device *dev)
+static void acpi_thermal_complete(struct device *dev)
{
- struct acpi_thermal *tz;
- int i, j;
-
- if (!dev)
- return -EINVAL;
-
- tz = acpi_driver_data(to_acpi_device(dev));
- if (!tz)
- return -EINVAL;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip;
-
- if (!acpi_thermal_trip_valid(acpi_trip))
- break;
-
- for (j = 0; j < acpi_trip->devices.count; j++)
- acpi_bus_update_power(acpi_trip->devices.handles[j], NULL);
- }
-
- acpi_queue_thermal_check(tz);
-
- return AE_OK;
+ acpi_queue_thermal_check(dev_get_drvdata(dev));
}
-#else
-#define acpi_thermal_suspend NULL
-#define acpi_thermal_resume NULL
-#endif
-static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume);
+
+static const struct dev_pm_ops acpi_thermal_pm_ops = {
+ .prepare = acpi_thermal_prepare,
+ .complete = acpi_thermal_complete,
+};
+#define ACPI_THERMAL_PM &acpi_thermal_pm_ops
+#else /* !CONFIG_PM_SLEEP */
+#define ACPI_THERMAL_PM NULL
+#endif /* CONFIG_PM_SLEEP */
static const struct acpi_device_id thermal_device_ids[] = {
{ACPI_THERMAL_HID, 0},
@@ -959,15 +938,14 @@ static const struct acpi_device_id thermal_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
-static struct acpi_driver acpi_thermal_driver = {
- .name = "thermal",
- .class = ACPI_THERMAL_CLASS,
- .ids = thermal_device_ids,
- .ops = {
- .add = acpi_thermal_add,
- .remove = acpi_thermal_remove,
- },
- .drv.pm = &acpi_thermal_pm,
+static struct platform_driver acpi_thermal_driver = {
+ .probe = acpi_thermal_probe,
+ .remove = acpi_thermal_remove,
+ .driver = {
+ .name = "acpi-thermal",
+ .acpi_match_table = thermal_device_ids,
+ .pm = ACPI_THERMAL_PM,
+ },
};
static int thermal_act(const struct dmi_system_id *d)
@@ -1065,7 +1043,7 @@ static int __init acpi_thermal_init(void)
if (!acpi_thermal_pm_queue)
return -ENODEV;
- result = acpi_bus_register_driver(&acpi_thermal_driver);
+ result = platform_driver_register(&acpi_thermal_driver);
if (result < 0) {
destroy_workqueue(acpi_thermal_pm_queue);
return -ENODEV;
@@ -1076,7 +1054,7 @@ static int __init acpi_thermal_init(void)
static void __exit acpi_thermal_exit(void)
{
- acpi_bus_unregister_driver(&acpi_thermal_driver);
+ platform_driver_unregister(&acpi_thermal_driver);
destroy_workqueue(acpi_thermal_pm_queue);
}
diff --git a/drivers/acpi/tiny-power-button.c b/drivers/acpi/tiny-power-button.c
index 6353be6fec69..531e65b01bcb 100644
--- a/drivers/acpi/tiny-power-button.c
+++ b/drivers/acpi/tiny-power-button.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/acpi.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/sched/signal.h>
-#include <linux/acpi.h>
#include <acpi/button.h>
MODULE_AUTHOR("Josh Triplett");
@@ -35,8 +36,9 @@ static u32 acpi_tiny_power_button_event(void *not_used)
return ACPI_INTERRUPT_HANDLED;
}
-static int acpi_tiny_power_button_add(struct acpi_device *device)
+static int acpi_tiny_power_button_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_status status;
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
@@ -55,8 +57,10 @@ static int acpi_tiny_power_button_add(struct acpi_device *device)
return 0;
}
-static void acpi_tiny_power_button_remove(struct acpi_device *device)
+static void acpi_tiny_power_button_remove(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+
if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) {
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
acpi_tiny_power_button_event);
@@ -67,14 +71,13 @@ static void acpi_tiny_power_button_remove(struct acpi_device *device)
acpi_os_wait_events_complete();
}
-static struct acpi_driver acpi_tiny_power_button_driver = {
- .name = "tiny-power-button",
- .class = "tiny-power-button",
- .ids = tiny_power_button_device_ids,
- .ops = {
- .add = acpi_tiny_power_button_add,
- .remove = acpi_tiny_power_button_remove,
+static struct platform_driver acpi_tiny_power_button_driver = {
+ .probe = acpi_tiny_power_button_probe,
+ .remove = acpi_tiny_power_button_remove,
+ .driver = {
+ .name = "acpi-tiny-power-button",
+ .acpi_match_table = tiny_power_button_device_ids,
},
};
-module_acpi_driver(acpi_tiny_power_button_driver);
+module_platform_driver(acpi_tiny_power_button_driver);