mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
Merge branch 'acpi-driver-devm'
Merge updates that introduce devm_acpi_install_notify_handler() and convert some drivers for core ACPI devices previously using acpi_dev_install_notify_handler() to devres-based resource management. * acpi-driver-devm: ACPI: video: Switch over to devres-based resource management ACPI: video: Use devm for video->entry and backlight cleanup ACPI: video: Use devm action for freeing video devices ACPI: video: Use devm action for video bus object cleanup ACPI: video: Rearrange probe and remove code ACPI: video: Reduce the number of auxiliary device dereferences ACPI: PAD: Switch over to devres-based resource management ACPI: PAD: Fix teardown ordering in acpi_pad_remove() ACPI: PAD: Pass struct device pointer to acpi_pad_notify() ACPI: PAD: Rearrange acpi_pad_notify() ACPI: thermal: Switch over to devres-based resource management ACPI: HED: Switch over to devres-based resource management ACPI: HED: Refine guarding against adding a second instance ACPI: battery: Switch over to devres-based resource management ACPI: AC: Switch over to devres-based resource management ACPI: NFIT: core: Use devm_acpi_install_notify_handler() ACPI: bus: Introduce devm_acpi_install_notify_handler()
This commit is contained in:
@@ -193,6 +193,7 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = {
|
||||
static int acpi_ac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct power_supply_config psy_cfg = {};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *adev;
|
||||
struct acpi_ac *ac;
|
||||
int result;
|
||||
@@ -201,7 +202,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
ac = kzalloc_obj(struct acpi_ac);
|
||||
ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
|
||||
if (!ac)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -211,7 +212,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
|
||||
|
||||
result = acpi_ac_get_state(ac);
|
||||
if (result)
|
||||
goto err_release_ac;
|
||||
return result;
|
||||
|
||||
psy_cfg.drv_data = ac;
|
||||
|
||||
@@ -220,33 +221,22 @@ static int acpi_ac_probe(struct platform_device *pdev)
|
||||
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(&pdev->dev,
|
||||
&ac->charger_desc, &psy_cfg);
|
||||
if (IS_ERR(ac->charger)) {
|
||||
result = PTR_ERR(ac->charger);
|
||||
goto err_release_ac;
|
||||
}
|
||||
ac->charger = devm_power_supply_register(dev, &ac->charger_desc, &psy_cfg);
|
||||
if (IS_ERR(ac->charger))
|
||||
return PTR_ERR(ac->charger);
|
||||
|
||||
pr_info("AC Adapter [%s] (%s-line)\n", acpi_device_bid(adev),
|
||||
str_on_off(ac->state));
|
||||
|
||||
result = devm_acpi_install_notify_handler(dev, ACPI_ALL_NOTIFY,
|
||||
acpi_ac_notify, ac);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
|
||||
register_acpi_notifier(&ac->battery_nb);
|
||||
|
||||
result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
|
||||
acpi_ac_notify, ac);
|
||||
if (result)
|
||||
goto err_unregister;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
power_supply_unregister(ac->charger);
|
||||
unregister_acpi_notifier(&ac->battery_nb);
|
||||
err_release_ac:
|
||||
kfree(ac);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -271,12 +261,7 @@ static void acpi_ac_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_ac *ac = platform_get_drvdata(pdev);
|
||||
|
||||
acpi_dev_remove_notify_handler(ac->device, ACPI_ALL_NOTIFY,
|
||||
acpi_ac_notify);
|
||||
power_supply_unregister(ac->charger);
|
||||
unregister_acpi_notifier(&ac->battery_nb);
|
||||
|
||||
kfree(ac);
|
||||
}
|
||||
|
||||
static struct platform_driver acpi_ac_driver = {
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
static DEFINE_MUTEX(isolated_cpus_lock);
|
||||
static DEFINE_MUTEX(round_robin_lock);
|
||||
|
||||
static bool acpi_pad_teardown;
|
||||
|
||||
static unsigned int power_saving_mwait_eax;
|
||||
|
||||
static unsigned char tsc_detected_unstable;
|
||||
@@ -359,6 +361,9 @@ static int acpi_pad_pur(acpi_handle handle)
|
||||
union acpi_object *package;
|
||||
int num = -1;
|
||||
|
||||
if (unlikely(acpi_pad_teardown))
|
||||
return -1;
|
||||
|
||||
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
|
||||
return num;
|
||||
|
||||
@@ -407,40 +412,29 @@ static void acpi_pad_handle_notify(acpi_handle handle)
|
||||
|
||||
static void acpi_pad_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_device *adev = data;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
|
||||
acpi_pad_handle_notify(handle);
|
||||
acpi_bus_generate_netlink_event("acpi_pad",
|
||||
dev_name(&adev->dev), event, 0);
|
||||
break;
|
||||
default:
|
||||
if (event != ACPI_PROCESSOR_AGGREGATOR_NOTIFY) {
|
||||
pr_warn("Unsupported event [0x%x]\n", event);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
acpi_pad_handle_notify(handle);
|
||||
acpi_bus_generate_netlink_event("acpi_pad", dev_name(data), event, 0);
|
||||
}
|
||||
|
||||
static int acpi_pad_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
acpi_pad_teardown = false;
|
||||
|
||||
adev = ACPI_COMPANION(&pdev->dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
return acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_pad_notify, adev);
|
||||
return devm_acpi_install_notify_handler(&pdev->dev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_pad_notify, &pdev->dev);
|
||||
}
|
||||
|
||||
static void acpi_pad_remove(struct platform_device *pdev)
|
||||
{
|
||||
mutex_lock(&isolated_cpus_lock);
|
||||
acpi_pad_teardown = true;
|
||||
acpi_pad_idle_cpus(0);
|
||||
mutex_unlock(&isolated_cpus_lock);
|
||||
|
||||
acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
|
||||
ACPI_DEVICE_NOTIFY, acpi_pad_notify);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id pad_device_ids[] = {
|
||||
|
||||
@@ -76,7 +76,6 @@ static DEFINE_MUTEX(video_list_lock);
|
||||
static LIST_HEAD(video_bus_head);
|
||||
static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
const struct auxiliary_device_id *id);
|
||||
static void acpi_video_bus_remove(struct auxiliary_device *aux);
|
||||
static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
|
||||
|
||||
/*
|
||||
@@ -99,7 +98,6 @@ MODULE_DEVICE_TABLE(auxiliary, video_bus_auxiliary_id_table);
|
||||
|
||||
static struct auxiliary_driver acpi_video_bus = {
|
||||
.probe = acpi_video_bus_probe,
|
||||
.remove = acpi_video_bus_remove,
|
||||
.id_table = video_bus_auxiliary_id_table,
|
||||
};
|
||||
|
||||
@@ -1494,10 +1492,31 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_get_edid);
|
||||
|
||||
static int
|
||||
acpi_video_bus_get_devices(struct acpi_video_bus *video,
|
||||
struct acpi_device *device)
|
||||
static void acpi_video_bus_put_devices(void *data)
|
||||
{
|
||||
struct acpi_video_bus *video = data;
|
||||
struct acpi_video_device *dev, *next;
|
||||
|
||||
mutex_lock(&video->device_list_lock);
|
||||
list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
|
||||
list_del(&dev->entry);
|
||||
kfree(dev);
|
||||
}
|
||||
mutex_unlock(&video->device_list_lock);
|
||||
|
||||
kfree(video->attached_array);
|
||||
video->attached_array = NULL;
|
||||
}
|
||||
|
||||
static int devm_acpi_video_bus_get_devices(struct device *dev,
|
||||
struct acpi_video_bus *video)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devm_add_action(dev, acpi_video_bus_put_devices, video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* There are systems where video module known to work fine regardless
|
||||
* of broken _DOD and ignoring returned value here doesn't cause
|
||||
@@ -1505,7 +1524,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
|
||||
*/
|
||||
acpi_video_device_enumerate(video);
|
||||
|
||||
return acpi_dev_for_each_child(device, acpi_video_bus_get_one_device, video);
|
||||
return acpi_dev_for_each_child(video->device,
|
||||
acpi_video_bus_get_one_device, video);
|
||||
}
|
||||
|
||||
/* acpi_video interface */
|
||||
@@ -1923,8 +1943,9 @@ static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)
|
||||
static void acpi_video_bus_remove_notify_handler(void *data)
|
||||
{
|
||||
struct acpi_video_bus *video = data;
|
||||
struct acpi_video_device *dev;
|
||||
|
||||
mutex_lock(&video->device_list_lock);
|
||||
@@ -1939,18 +1960,23 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)
|
||||
video->input = NULL;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
|
||||
static void acpi_video_bus_free(void *data)
|
||||
{
|
||||
struct acpi_video_device *dev, *next;
|
||||
struct acpi_video_bus *video = data;
|
||||
|
||||
mutex_lock(&video->device_list_lock);
|
||||
list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
|
||||
list_del(&dev->entry);
|
||||
kfree(dev);
|
||||
}
|
||||
mutex_unlock(&video->device_list_lock);
|
||||
video->device->driver_data = NULL;
|
||||
kfree(video);
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void acpi_video_bus_del(void *data)
|
||||
{
|
||||
struct acpi_video_bus *video = data;
|
||||
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
}
|
||||
|
||||
static int duplicate_dev_check(struct device *sibling, void *data)
|
||||
@@ -1978,7 +2004,8 @@ static bool acpi_video_bus_dev_is_duplicate(struct device *dev)
|
||||
static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
const struct auxiliary_device_id *id_unused)
|
||||
{
|
||||
struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev);
|
||||
struct device *dev = &aux_dev->dev;
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
static DEFINE_MUTEX(probe_lock);
|
||||
struct acpi_video_bus *video;
|
||||
static int instance;
|
||||
@@ -1988,7 +2015,7 @@ static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
/* Probe one video bus device at a time in case there are duplicates. */
|
||||
guard(mutex)(&probe_lock);
|
||||
|
||||
if (!allow_duplicates && acpi_video_bus_dev_is_duplicate(&aux_dev->dev)) {
|
||||
if (!allow_duplicates && acpi_video_bus_dev_is_duplicate(dev)) {
|
||||
pr_info(FW_BUG
|
||||
"Duplicate ACPI video bus devices for the"
|
||||
" same VGA controller, please try module "
|
||||
@@ -2001,6 +2028,13 @@ static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
if (!video)
|
||||
return -ENOMEM;
|
||||
|
||||
video->device = device;
|
||||
device->driver_data = video;
|
||||
|
||||
error = devm_add_action_or_reset(dev, acpi_video_bus_free, video);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* A hack to fix the duplicate name "VID" problem on T61 and the
|
||||
* duplicate name "VGA" problem on Pa 3553.
|
||||
@@ -2015,20 +2049,17 @@ static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
|
||||
auxiliary_set_drvdata(aux_dev, video);
|
||||
|
||||
video->device = device;
|
||||
device->driver_data = video;
|
||||
|
||||
acpi_video_bus_find_cap(video);
|
||||
error = acpi_video_bus_check(video);
|
||||
if (error)
|
||||
goto err_free_video;
|
||||
return error;
|
||||
|
||||
mutex_init(&video->device_list_lock);
|
||||
INIT_LIST_HEAD(&video->video_device_list);
|
||||
|
||||
error = acpi_video_bus_get_devices(video, device);
|
||||
error = devm_acpi_video_bus_get_devices(dev, video);
|
||||
if (error)
|
||||
goto err_put_video;
|
||||
return error;
|
||||
|
||||
/*
|
||||
* HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0
|
||||
@@ -2040,10 +2071,6 @@ static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
acpi_device_bid(device), str_yes_no(video->flags.multihead),
|
||||
str_yes_no(video->flags.rom), str_yes_no(video->flags.post));
|
||||
|
||||
mutex_lock(&video_list_lock);
|
||||
list_add_tail(&video->entry, &video_bus_head);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
/*
|
||||
* If backlight-type auto-detection is used then a native backlight may
|
||||
* show up later and this may change the result from video to native.
|
||||
@@ -2059,53 +2086,25 @@ static int acpi_video_bus_probe(struct auxiliary_device *aux_dev,
|
||||
!auto_detect)
|
||||
acpi_video_bus_register_backlight(video);
|
||||
|
||||
error = acpi_video_bus_add_notify_handler(video, &aux_dev->dev);
|
||||
if (error)
|
||||
goto err_del;
|
||||
mutex_lock(&video_list_lock);
|
||||
list_add_tail(&video->entry, &video_bus_head);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
error = devm_add_action_or_reset(dev, acpi_video_bus_del, video);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = acpi_video_bus_add_notify_handler(video, dev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = devm_add_action_or_reset(dev, acpi_video_bus_remove_notify_handler,
|
||||
video);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return devm_acpi_install_notify_handler(dev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_bus_notify, video);
|
||||
if (error)
|
||||
goto err_remove;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove:
|
||||
acpi_video_bus_remove_notify_handler(video);
|
||||
err_del:
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
err_put_video:
|
||||
acpi_video_bus_put_devices(video);
|
||||
kfree(video->attached_array);
|
||||
err_free_video:
|
||||
kfree(video);
|
||||
device->driver_data = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void acpi_video_bus_remove(struct auxiliary_device *aux_dev)
|
||||
{
|
||||
struct acpi_video_bus *video = auxiliary_get_drvdata(aux_dev);
|
||||
struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev);
|
||||
|
||||
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_bus_notify);
|
||||
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
acpi_video_bus_remove_notify_handler(video);
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
|
||||
kfree(video->attached_array);
|
||||
kfree(video);
|
||||
device->driver_data = NULL;
|
||||
}
|
||||
|
||||
static int __init is_i740(struct pci_dev *dev)
|
||||
|
||||
@@ -1182,6 +1182,26 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
|
||||
{},
|
||||
};
|
||||
|
||||
static void acpi_battery_wakeup_cleanup(void *data)
|
||||
{
|
||||
device_init_wakeup(data, false);
|
||||
}
|
||||
|
||||
static int devm_acpi_battery_init_wakeup(struct device *dev)
|
||||
{
|
||||
device_init_wakeup(dev, true);
|
||||
return devm_add_action_or_reset(dev, acpi_battery_wakeup_cleanup, dev);
|
||||
}
|
||||
|
||||
static void sysfs_battery_cleanup(void *data)
|
||||
{
|
||||
struct acpi_battery *battery = data;
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
sysfs_remove_battery(battery);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some machines'(E,G Lenovo Z480) ECs are not stable
|
||||
* during boot up and this causes battery driver fails to be
|
||||
@@ -1190,10 +1210,15 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
|
||||
* may work. So add retry code here and 20ms sleep between
|
||||
* every retries.
|
||||
*/
|
||||
static int acpi_battery_update_retry(struct acpi_battery *battery)
|
||||
static int devm_acpi_battery_update_retry(struct device *dev,
|
||||
struct acpi_battery *battery)
|
||||
{
|
||||
int retry, ret;
|
||||
|
||||
ret = devm_add_action(dev, sysfs_battery_cleanup, battery);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
for (retry = 5; retry; retry--) {
|
||||
@@ -1206,27 +1231,21 @@ static int acpi_battery_update_retry(struct acpi_battery *battery)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sysfs_battery_cleanup(struct acpi_battery *battery)
|
||||
{
|
||||
guard(mutex)(&battery->update_lock);
|
||||
|
||||
sysfs_remove_battery(battery);
|
||||
}
|
||||
|
||||
static int acpi_battery_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_battery *battery;
|
||||
struct acpi_device *device;
|
||||
int result;
|
||||
|
||||
device = ACPI_COMPANION(&pdev->dev);
|
||||
device = ACPI_COMPANION(dev);
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
|
||||
if (device->dep_unmet)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
battery = devm_kzalloc(&pdev->dev, sizeof(*battery), GFP_KERNEL);
|
||||
battery = devm_kzalloc(dev, sizeof(*battery), GFP_KERNEL);
|
||||
if (!battery)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1235,54 +1254,38 @@ static int acpi_battery_probe(struct platform_device *pdev)
|
||||
battery->phys_dev = &pdev->dev;
|
||||
battery->device = device;
|
||||
|
||||
result = devm_mutex_init(&pdev->dev, &battery->update_lock);
|
||||
result = devm_mutex_init(dev, &battery->update_lock);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (acpi_has_method(battery->device->handle, "_BIX"))
|
||||
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
|
||||
result = acpi_battery_update_retry(battery);
|
||||
result = devm_acpi_battery_update_retry(dev, battery);
|
||||
if (result)
|
||||
goto fail;
|
||||
return result;
|
||||
|
||||
pr_info("Slot [%s] (battery %s)\n", acpi_device_bid(device),
|
||||
device->status.battery_present ? "present" : "absent");
|
||||
|
||||
result = devm_acpi_battery_init_wakeup(dev);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = devm_acpi_install_notify_handler(dev, ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify, battery);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
battery->pm_nb.notifier_call = battery_notify;
|
||||
result = register_pm_notifier(&battery->pm_nb);
|
||||
if (result)
|
||||
goto fail;
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
||||
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify, battery);
|
||||
if (result)
|
||||
goto fail_pm;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_pm:
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
fail:
|
||||
sysfs_battery_cleanup(battery);
|
||||
|
||||
return result;
|
||||
return register_pm_notifier(&battery->pm_nb);
|
||||
}
|
||||
|
||||
static void acpi_battery_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_battery *battery = platform_get_drvdata(pdev);
|
||||
|
||||
acpi_dev_remove_notify_handler(battery->device, ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify);
|
||||
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
|
||||
sysfs_battery_cleanup(battery);
|
||||
}
|
||||
|
||||
/* this is needed to learn about changes made in suspended state */
|
||||
|
||||
@@ -679,6 +679,72 @@ void acpi_dev_remove_notify_handler(struct acpi_device *adev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_remove_notify_handler);
|
||||
|
||||
struct acpi_notify_handler_devres {
|
||||
acpi_notify_handler handler;
|
||||
u32 handler_type;
|
||||
};
|
||||
|
||||
static void devm_acpi_notify_handler_release(struct device *dev, void *res)
|
||||
{
|
||||
struct acpi_notify_handler_devres *dr = res;
|
||||
|
||||
acpi_dev_remove_notify_handler(ACPI_COMPANION(dev), dr->handler_type,
|
||||
dr->handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_acpi_install_notify_handler - Install an ACPI notify handler for a
|
||||
* managed device
|
||||
* @dev: Device to install a notify handler for
|
||||
* @handler_type: Type of the notify handler
|
||||
* @handler: Handler function to install
|
||||
* @context: Data passed back to the handler function
|
||||
*
|
||||
* This function performs the same function as acpi_dev_install_notify_handler()
|
||||
* called for the ACPI companion of @dev with the same @handler_type, @handler,
|
||||
* and @context arguments, but the ACPI notify handler installed by it will be
|
||||
* automatically removed on driver detach.
|
||||
*
|
||||
* Callers should ensure that all resources used by @handler have been allocated
|
||||
* prior to invoking this function, in which case those resources should be
|
||||
* devres-managed so that they won't be released before the notify handler
|
||||
* removal. Otherwise, special synchronization between @handler and the
|
||||
* management of those resources is required.
|
||||
*
|
||||
* When the request fails, an error message is printed. Don't add extra error
|
||||
* messages at the call sites.
|
||||
*
|
||||
* Return: 0 on success or a negative error number.
|
||||
*/
|
||||
int devm_acpi_install_notify_handler(struct device *dev, u32 handler_type,
|
||||
acpi_notify_handler handler, void *context)
|
||||
{
|
||||
struct acpi_notify_handler_devres *dr;
|
||||
struct acpi_device *adev;
|
||||
int ret;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
return dev_err_probe(dev, -ENODEV, "No ACPI companion in %s()\n", __func__);
|
||||
|
||||
dr = devres_alloc(devm_acpi_notify_handler_release, sizeof(*dr), GFP_KERNEL);
|
||||
if (!dr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = acpi_dev_install_notify_handler(adev, handler_type, handler, context);
|
||||
if (ret) {
|
||||
devres_free(dr);
|
||||
return dev_err_probe(dev, ret, "Failed to install an ACPI notify handler\n");
|
||||
}
|
||||
|
||||
dr->handler = handler;
|
||||
dr->handler_type = handler_type;
|
||||
devres_add(dev, dr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_acpi_install_notify_handler);
|
||||
|
||||
/* Handle events targeting \_SB device (at present only graceful shutdown) */
|
||||
|
||||
#define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
|
||||
|
||||
@@ -22,7 +22,7 @@ static const struct acpi_device_id acpi_hed_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, acpi_hed_ids);
|
||||
|
||||
static acpi_handle hed_handle;
|
||||
static bool hed_present;
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list);
|
||||
|
||||
@@ -50,33 +50,24 @@ static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
|
||||
|
||||
static int acpi_hed_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
int err;
|
||||
|
||||
device = ACPI_COMPANION(&pdev->dev);
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
|
||||
/* Only one hardware error device */
|
||||
if (hed_handle)
|
||||
if (hed_present)
|
||||
return -EINVAL;
|
||||
hed_handle = device->handle;
|
||||
|
||||
err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_hed_notify, device);
|
||||
err = devm_acpi_install_notify_handler(&pdev->dev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_hed_notify, NULL);
|
||||
if (err)
|
||||
hed_handle = NULL;
|
||||
return err;
|
||||
|
||||
return err;
|
||||
hed_present = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
hed_present = false;
|
||||
}
|
||||
|
||||
static struct platform_driver acpi_hed_driver = {
|
||||
|
||||
@@ -3298,14 +3298,6 @@ static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
|
||||
device_unlock(dev);
|
||||
}
|
||||
|
||||
static void acpi_nfit_remove_notify_handler(void *data)
|
||||
{
|
||||
struct acpi_device *adev = data;
|
||||
|
||||
acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_nfit_notify);
|
||||
}
|
||||
|
||||
void acpi_nfit_shutdown(void *data)
|
||||
{
|
||||
struct acpi_nfit_desc *acpi_desc = data;
|
||||
@@ -3342,22 +3334,12 @@ static int acpi_nfit_probe(struct platform_device *pdev)
|
||||
struct acpi_nfit_desc *acpi_desc;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_table_header *tbl;
|
||||
struct acpi_device *adev;
|
||||
acpi_status status = AE_OK;
|
||||
acpi_size sz;
|
||||
int rc = 0;
|
||||
|
||||
adev = ACPI_COMPANION(&pdev->dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_nfit_notify, dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler,
|
||||
adev);
|
||||
rc = devm_acpi_install_notify_handler(dev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_nfit_notify, dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -3388,7 +3370,7 @@ static int acpi_nfit_probe(struct platform_device *pdev)
|
||||
acpi_desc->acpi_header = *tbl;
|
||||
|
||||
/* Evaluate _FIT and override with that if present */
|
||||
status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf);
|
||||
status = acpi_evaluate_object(ACPI_HANDLE(dev), "_FIT", NULL, &buf);
|
||||
if (ACPI_SUCCESS(status) && buf.length > 0) {
|
||||
union acpi_object *obj = buf.pointer;
|
||||
|
||||
|
||||
@@ -655,8 +655,12 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
|
||||
static void acpi_thermal_zone_unregister(void *data)
|
||||
{
|
||||
struct acpi_thermal *tz = data;
|
||||
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
|
||||
thermal_zone_device_disable(tz->thermal_zone);
|
||||
acpi_thermal_zone_sysfs_remove(tz);
|
||||
thermal_zone_device_unregister(tz->thermal_zone);
|
||||
@@ -765,8 +769,9 @@ static void acpi_thermal_check_fn(struct work_struct *work)
|
||||
mutex_unlock(&tz->thermal_check_lock);
|
||||
}
|
||||
|
||||
static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz)
|
||||
static void acpi_thermal_zone_free(void *data)
|
||||
{
|
||||
struct acpi_thermal *tz = data;
|
||||
int i;
|
||||
|
||||
acpi_handle_list_free(&tz->trips.passive.trip.devices);
|
||||
@@ -779,7 +784,8 @@ static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz)
|
||||
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 device *dev = &pdev->dev;
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
struct acpi_thermal_trip *acpi_trip;
|
||||
struct thermal_trip *trip;
|
||||
struct acpi_thermal *tz;
|
||||
@@ -795,6 +801,10 @@ static int acpi_thermal_probe(struct platform_device *pdev)
|
||||
if (!tz)
|
||||
return -ENOMEM;
|
||||
|
||||
result = devm_add_action_or_reset(dev, acpi_thermal_zone_free, tz);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
platform_set_drvdata(pdev, tz);
|
||||
|
||||
tz->device = device;
|
||||
@@ -817,7 +827,7 @@ static int acpi_thermal_probe(struct platform_device *pdev)
|
||||
/* Get temperature [_TMP] (required). */
|
||||
result = acpi_thermal_get_temperature(tz);
|
||||
if (result)
|
||||
goto free_memory;
|
||||
return result;
|
||||
|
||||
/* Determine the default polling frequency [_TZP]. */
|
||||
if (tzp)
|
||||
@@ -870,7 +880,11 @@ static int acpi_thermal_probe(struct platform_device *pdev)
|
||||
trip - trip_table,
|
||||
passive_delay);
|
||||
if (result)
|
||||
goto free_memory;
|
||||
return result;
|
||||
|
||||
result = devm_add_action_or_reset(dev, acpi_thermal_zone_unregister, tz);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
refcount_set(&tz->thermal_check_count, 3);
|
||||
mutex_init(&tz->thermal_check_lock);
|
||||
@@ -879,32 +893,8 @@ static int acpi_thermal_probe(struct platform_device *pdev)
|
||||
pr_info("Thermal Zone [%s] (%ld C)\n", acpi_device_bid(device),
|
||||
deci_kelvin_to_celsius(tz->temp_dk));
|
||||
|
||||
result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_thermal_notify, tz);
|
||||
if (result)
|
||||
goto flush_wq;
|
||||
|
||||
return 0;
|
||||
|
||||
flush_wq:
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
free_memory:
|
||||
acpi_thermal_free_thermal_zone(tz);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void acpi_thermal_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_thermal *tz = platform_get_drvdata(pdev);
|
||||
|
||||
acpi_dev_remove_notify_handler(tz->device, ACPI_DEVICE_NOTIFY,
|
||||
acpi_thermal_notify);
|
||||
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
acpi_thermal_free_thermal_zone(tz);
|
||||
return devm_acpi_install_notify_handler(dev, ACPI_DEVICE_NOTIFY,
|
||||
acpi_thermal_notify, tz);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -937,7 +927,6 @@ MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
|
||||
|
||||
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,
|
||||
|
||||
@@ -629,6 +629,8 @@ int acpi_dev_install_notify_handler(struct acpi_device *adev,
|
||||
void acpi_dev_remove_notify_handler(struct acpi_device *adev,
|
||||
u32 handler_type,
|
||||
acpi_notify_handler handler);
|
||||
int devm_acpi_install_notify_handler(struct device *dev, u32 handler_type,
|
||||
acpi_notify_handler handler, void *context);
|
||||
extern int acpi_notifier_call_chain(const char *device_class,
|
||||
const char *bus_id, u32 type, u32 data);
|
||||
extern int register_acpi_notifier(struct notifier_block *);
|
||||
|
||||
Reference in New Issue
Block a user