@@ -126,7 +126,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
126126
127127static int acpi_button_add (struct acpi_device * device );
128128static void acpi_button_remove (struct acpi_device * device );
129- static void acpi_button_notify (struct acpi_device * device , u32 event );
130129
131130#ifdef CONFIG_PM_SLEEP
132131static int acpi_button_suspend (struct device * dev );
@@ -144,7 +143,6 @@ static struct acpi_driver acpi_button_driver = {
144143 .ops = {
145144 .add = acpi_button_add ,
146145 .remove = acpi_button_remove ,
147- .notify = acpi_button_notify ,
148146 },
149147 .drv .pm = & acpi_button_pm ,
150148};
@@ -400,45 +398,55 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
400398 button -> lid_state_initialized = true;
401399}
402400
403- static void acpi_button_notify (struct acpi_device * device , u32 event )
401+ static void acpi_button_notify (acpi_handle handle , u32 event , void * data )
404402{
405- struct acpi_button * button = acpi_driver_data (device );
403+ struct acpi_device * device = data ;
404+ struct acpi_button * button ;
406405 struct input_dev * input ;
406+ int keycode ;
407407
408- switch (event ) {
409- case ACPI_FIXED_HARDWARE_EVENT :
410- event = ACPI_BUTTON_NOTIFY_STATUS ;
411- fallthrough ;
412- case ACPI_BUTTON_NOTIFY_STATUS :
413- input = button -> input ;
414- if (button -> type == ACPI_BUTTON_TYPE_LID ) {
415- if (button -> lid_state_initialized )
416- acpi_lid_update_state (device , true);
417- } else {
418- int keycode ;
419-
420- acpi_pm_wakeup_event (& device -> dev );
421- if (button -> suspended )
422- break ;
423-
424- keycode = test_bit (KEY_SLEEP , input -> keybit ) ?
425- KEY_SLEEP : KEY_POWER ;
426- input_report_key (input , keycode , 1 );
427- input_sync (input );
428- input_report_key (input , keycode , 0 );
429- input_sync (input );
430-
431- acpi_bus_generate_netlink_event (
432- device -> pnp .device_class ,
433- dev_name (& device -> dev ),
434- event , ++ button -> pushed );
435- }
436- break ;
437- default :
408+ if (event != ACPI_BUTTON_NOTIFY_STATUS ) {
438409 acpi_handle_debug (device -> handle , "Unsupported event [0x%x]\n" ,
439410 event );
440- break ;
411+ return ;
441412 }
413+
414+ button = acpi_driver_data (device );
415+
416+ if (button -> type == ACPI_BUTTON_TYPE_LID ) {
417+ if (button -> lid_state_initialized )
418+ acpi_lid_update_state (device , true);
419+
420+ return ;
421+ }
422+
423+ acpi_pm_wakeup_event (& device -> dev );
424+
425+ if (button -> suspended )
426+ return ;
427+
428+ input = button -> input ;
429+ keycode = test_bit (KEY_SLEEP , input -> keybit ) ? KEY_SLEEP : KEY_POWER ;
430+
431+ input_report_key (input , keycode , 1 );
432+ input_sync (input );
433+ input_report_key (input , keycode , 0 );
434+ input_sync (input );
435+
436+ acpi_bus_generate_netlink_event (device -> pnp .device_class ,
437+ dev_name (& device -> dev ),
438+ event , ++ button -> pushed );
439+ }
440+
441+ static void acpi_button_notify_run (void * data )
442+ {
443+ acpi_button_notify (NULL , ACPI_BUTTON_NOTIFY_STATUS , data );
444+ }
445+
446+ static u32 acpi_button_event (void * data )
447+ {
448+ acpi_os_execute (OSL_NOTIFY_HANDLER , acpi_button_notify_run , data );
449+ return ACPI_INTERRUPT_HANDLED ;
442450}
443451
444452#ifdef CONFIG_PM_SLEEP
@@ -483,8 +491,9 @@ static int acpi_button_add(struct acpi_device *device)
483491 struct acpi_button * button ;
484492 struct input_dev * input ;
485493 const char * hid = acpi_device_hid (device );
494+ acpi_status status ;
486495 char * name , * class ;
487- int error ;
496+ int error = 0 ;
488497
489498 if (!strcmp (hid , ACPI_BUTTON_HID_LID ) &&
490499 lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED )
@@ -526,12 +535,15 @@ static int acpi_button_add(struct acpi_device *device)
526535 } else {
527536 pr_info ("Unsupported hid [%s]\n" , hid );
528537 error = - ENODEV ;
529- goto err_free_input ;
530538 }
531539
532- error = acpi_button_add_fs (device );
533- if (error )
534- goto err_free_input ;
540+ if (!error )
541+ error = acpi_button_add_fs (device );
542+
543+ if (error ) {
544+ input_free_device (input );
545+ goto err_free_button ;
546+ }
535547
536548 snprintf (button -> phys , sizeof (button -> phys ), "%s/button/input0" , hid );
537549
@@ -559,6 +571,30 @@ static int acpi_button_add(struct acpi_device *device)
559571 error = input_register_device (input );
560572 if (error )
561573 goto err_remove_fs ;
574+
575+ switch (device -> device_type ) {
576+ case ACPI_BUS_TYPE_POWER_BUTTON :
577+ status = acpi_install_fixed_event_handler (ACPI_EVENT_POWER_BUTTON ,
578+ acpi_button_event ,
579+ device );
580+ break ;
581+ case ACPI_BUS_TYPE_SLEEP_BUTTON :
582+ status = acpi_install_fixed_event_handler (ACPI_EVENT_SLEEP_BUTTON ,
583+ acpi_button_event ,
584+ device );
585+ break ;
586+ default :
587+ status = acpi_install_notify_handler (device -> handle ,
588+ ACPI_DEVICE_NOTIFY ,
589+ acpi_button_notify ,
590+ device );
591+ break ;
592+ }
593+ if (ACPI_FAILURE (status )) {
594+ error = - ENODEV ;
595+ goto err_input_unregister ;
596+ }
597+
562598 if (button -> type == ACPI_BUTTON_TYPE_LID ) {
563599 /*
564600 * This assumes there's only one lid device, or if there are
@@ -571,11 +607,11 @@ static int acpi_button_add(struct acpi_device *device)
571607 pr_info ("%s [%s]\n" , name , acpi_device_bid (device ));
572608 return 0 ;
573609
574- err_remove_fs :
610+ err_input_unregister :
611+ input_unregister_device (input );
612+ err_remove_fs :
575613 acpi_button_remove_fs (device );
576- err_free_input :
577- input_free_device (input );
578- err_free_button :
614+ err_free_button :
579615 kfree (button );
580616 return error ;
581617}
@@ -584,6 +620,22 @@ static void acpi_button_remove(struct acpi_device *device)
584620{
585621 struct acpi_button * button = acpi_driver_data (device );
586622
623+ switch (device -> device_type ) {
624+ case ACPI_BUS_TYPE_POWER_BUTTON :
625+ acpi_remove_fixed_event_handler (ACPI_EVENT_POWER_BUTTON ,
626+ acpi_button_event );
627+ break ;
628+ case ACPI_BUS_TYPE_SLEEP_BUTTON :
629+ acpi_remove_fixed_event_handler (ACPI_EVENT_SLEEP_BUTTON ,
630+ acpi_button_event );
631+ break ;
632+ default :
633+ acpi_remove_notify_handler (device -> handle , ACPI_DEVICE_NOTIFY ,
634+ acpi_button_notify );
635+ break ;
636+ }
637+ acpi_os_wait_events_complete ();
638+
587639 acpi_button_remove_fs (device );
588640 input_unregister_device (button -> input );
589641 kfree (button );
0 commit comments