@@ -3186,10 +3186,74 @@ static void print_supported_features(struct toshiba_acpi_dev *dev)
pr_cont("\n");
}
+static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_device *acpi_dev = data;
+ struct toshiba_acpi_dev *dev;
+
+ dev = acpi_driver_data(acpi_dev);
+
+ switch (event) {
+ case 0x80: /* Hotkeys and some system events */
+ /*
+ * Machines with this WMI GUID aren't supported due to bugs in
+ * their AML.
+ *
+ * Return silently to avoid triggering a netlink event.
+ */
+ if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
+ return;
+ toshiba_acpi_process_hotkeys(dev);
+ break;
+ case 0x81: /* Dock events */
+ case 0x82:
+ case 0x83:
+ pr_info("Dock event received %x\n", event);
+ break;
+ case 0x88: /* Thermal events */
+ pr_info("Thermal event received\n");
+ break;
+ case 0x8f: /* LID closed */
+ case 0x90: /* LID is closed and Dock has been ejected */
+ break;
+ case 0x8c: /* SATA power events */
+ case 0x8b:
+ pr_info("SATA power event received %x\n", event);
+ break;
+ case 0x92: /* Keyboard backlight mode changed */
+ dev->kbd_event_generated = true;
+ /* Update sysfs entries */
+ if (sysfs_update_group(&acpi_dev->dev.kobj,
+ &toshiba_attr_group))
+ pr_err("Unable to update sysfs entries\n");
+ /* Notify LED subsystem about keyboard backlight change */
+ if (dev->kbd_type == 2 && dev->kbd_mode != SCI_KBD_MODE_AUTO)
+ led_classdev_notify_brightness_hw_changed(&dev->kbd_led,
+ (dev->kbd_mode == SCI_KBD_MODE_ON) ?
+ LED_FULL : LED_OFF);
+ break;
+ case 0x85: /* Unknown */
+ case 0x8d: /* Unknown */
+ case 0x8e: /* Unknown */
+ case 0x94: /* Unknown */
+ case 0x95: /* Unknown */
+ default:
+ pr_info("Unknown event received %x\n", event);
+ break;
+ }
+
+ acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class,
+ dev_name(&acpi_dev->dev),
+ event, (event == 0x80) ?
+ dev->last_key_event : 0);
+}
+
static void toshiba_acpi_remove(struct acpi_device *acpi_dev)
{
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
+ acpi_device_remove_event_handler(acpi_dev, ACPI_ALL_NOTIFY, toshiba_acpi_notify);
+
misc_deregister(&dev->miscdev);
remove_toshiba_proc_entries(dev);
@@ -3473,72 +3537,17 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
if (dev->battery_charge_mode_supported)
battery_hook_register(&battery_hook);
- return 0;
+ ret = acpi_device_install_event_handler(acpi_dev, ACPI_ALL_NOTIFY, toshiba_acpi_notify);
+ if (ret)
+ goto error;
+
+ return ret;
error:
toshiba_acpi_remove(acpi_dev);
return ret;
}
-static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
-{
- struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
-
- switch (event) {
- case 0x80: /* Hotkeys and some system events */
- /*
- * Machines with this WMI GUID aren't supported due to bugs in
- * their AML.
- *
- * Return silently to avoid triggering a netlink event.
- */
- if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
- return;
- toshiba_acpi_process_hotkeys(dev);
- break;
- case 0x81: /* Dock events */
- case 0x82:
- case 0x83:
- pr_info("Dock event received %x\n", event);
- break;
- case 0x88: /* Thermal events */
- pr_info("Thermal event received\n");
- break;
- case 0x8f: /* LID closed */
- case 0x90: /* LID is closed and Dock has been ejected */
- break;
- case 0x8c: /* SATA power events */
- case 0x8b:
- pr_info("SATA power event received %x\n", event);
- break;
- case 0x92: /* Keyboard backlight mode changed */
- dev->kbd_event_generated = true;
- /* Update sysfs entries */
- if (sysfs_update_group(&acpi_dev->dev.kobj,
- &toshiba_attr_group))
- pr_err("Unable to update sysfs entries\n");
- /* Notify LED subsystem about keyboard backlight change */
- if (dev->kbd_type == 2 && dev->kbd_mode != SCI_KBD_MODE_AUTO)
- led_classdev_notify_brightness_hw_changed(&dev->kbd_led,
- (dev->kbd_mode == SCI_KBD_MODE_ON) ?
- LED_FULL : LED_OFF);
- break;
- case 0x85: /* Unknown */
- case 0x8d: /* Unknown */
- case 0x8e: /* Unknown */
- case 0x94: /* Unknown */
- case 0x95: /* Unknown */
- default:
- pr_info("Unknown event received %x\n", event);
- break;
- }
-
- acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class,
- dev_name(&acpi_dev->dev),
- event, (event == 0x80) ?
- dev->last_key_event : 0);
-}
-
#ifdef CONFIG_PM_SLEEP
static int toshiba_acpi_suspend(struct device *device)
{
@@ -3583,11 +3592,9 @@ static struct acpi_driver toshiba_acpi_driver = {
.name = "Toshiba ACPI driver",
.owner = THIS_MODULE,
.ids = toshiba_device_ids,
- .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = toshiba_acpi_add,
.remove = toshiba_acpi_remove,
- .notify = toshiba_acpi_notify,
},
.drv.pm = &toshiba_acpi_pm,
};
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@intel.com> --- drivers/platform/x86/toshiba_acpi.c | 131 +++++++++++++++------------- 1 file changed, 69 insertions(+), 62 deletions(-)