Currently logic for installing notifications from ACPI devices is implemented using notify callback in struct acpi_driver. Preparations are being made to replace acpi_driver with more generic struct platform_driver, which doesn't contain notify callback. Furthermore as of now handlers are being called indirectly through acpi_notify_device(), which decreases performance. Call acpi_device_install_event_handler() at the end of .add() callback. Call acpi_device_remove_event_handler() at the beginning of .remove() callback. Change arguments passed to the notify callback to match with what's required by acpi_device_install_event_handler(). Signed-off-by: Michal Wilczynski <michal.wilczynski@xxxxxxxxx> --- drivers/platform/x86/toshiba_bluetooth.c | 30 +++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index d8f81962a240..a717bd5fcc88 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -37,7 +37,7 @@ struct toshiba_bluetooth_dev { static int toshiba_bt_rfkill_add(struct acpi_device *device); static void toshiba_bt_rfkill_remove(struct acpi_device *device); -static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); +static void toshiba_bt_rfkill_notify(acpi_handle handle, u32 event, void *data); static const struct acpi_device_id bt_device_ids[] = { { "TOS6205", 0}, @@ -57,7 +57,6 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { .ops = { .add = toshiba_bt_rfkill_add, .remove = toshiba_bt_rfkill_remove, - .notify = toshiba_bt_rfkill_notify, }, .owner = THIS_MODULE, .drv.pm = &toshiba_bt_pm, @@ -204,9 +203,12 @@ static const struct rfkill_ops rfk_ops = { }; /* ACPI driver functions */ -static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) +static void toshiba_bt_rfkill_notify(acpi_handle handle, u32 event, void *data) { - struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); + struct toshiba_bluetooth_dev *bt_dev; + struct acpi_device *device = data; + + bt_dev = acpi_driver_data(device); if (toshiba_bluetooth_sync_status(bt_dev)) return; @@ -263,8 +265,8 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) bt_dev); if (!bt_dev->rfk) { pr_err("Unable to allocate rfkill device\n"); - kfree(bt_dev); - return -ENOMEM; + result = -ENOMEM; + goto fail_allocate; } rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); @@ -272,10 +274,20 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) result = rfkill_register(bt_dev->rfk); if (result) { pr_err("Unable to register rfkill device\n"); - rfkill_destroy(bt_dev->rfk); - kfree(bt_dev); + goto fail_register; } + result = acpi_device_install_event_handler(device, ACPI_DEVICE_NOTIFY, + toshiba_bt_rfkill_notify); + if (result) + goto fail_register; + + return 0; + +fail_register: + rfkill_destroy(bt_dev->rfk); +fail_allocate: + kfree(bt_dev); return result; } @@ -283,6 +295,8 @@ static void toshiba_bt_rfkill_remove(struct acpi_device *device) { struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); + acpi_device_remove_event_handler(device, ACPI_DEVICE_NOTIFY, toshiba_bt_rfkill_notify); + /* clean up */ if (bt_dev->rfk) { rfkill_unregister(bt_dev->rfk); -- 2.40.1