@@ -135,7 +135,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
135135
136136static int acpi_button_add (struct acpi_device * device );
137137static void acpi_button_remove (struct acpi_device * device );
138- static void acpi_button_notify (struct acpi_device * device , u32 event );
139138
140139#ifdef CONFIG_PM_SLEEP
141140static int acpi_button_suspend (struct device * dev );
@@ -153,7 +152,6 @@ static struct acpi_driver acpi_button_driver = {
153152 .ops = {
154153 .add = acpi_button_add ,
155154 .remove = acpi_button_remove ,
156- .notify = acpi_button_notify ,
157155 },
158156 .drv .pm = & acpi_button_pm ,
159157};
@@ -409,45 +407,65 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
409407 button -> lid_state_initialized = true;
410408}
411409
412- static void acpi_button_notify ( struct acpi_device * device , u32 event )
410+ static void acpi_lid_notify ( acpi_handle handle , u32 event , void * data )
413411{
414- struct acpi_button * button = acpi_driver_data (device );
412+ struct acpi_device * device = data ;
413+ struct acpi_button * button ;
414+
415+ if (event != ACPI_BUTTON_NOTIFY_STATUS ) {
416+ acpi_handle_debug (device -> handle , "Unsupported event [0x%x]\n" ,
417+ event );
418+ return ;
419+ }
420+
421+ button = acpi_driver_data (device );
422+ if (!button -> lid_state_initialized )
423+ return ;
424+
425+ acpi_lid_update_state (device , true);
426+ }
427+
428+ static void acpi_button_notify (acpi_handle handle , u32 event , void * data )
429+ {
430+ struct acpi_device * device = data ;
431+ struct acpi_button * button ;
415432 struct input_dev * input ;
433+ int keycode ;
416434
417- switch (event ) {
418- case ACPI_FIXED_HARDWARE_EVENT :
419- event = ACPI_BUTTON_NOTIFY_STATUS ;
420- fallthrough ;
421- case ACPI_BUTTON_NOTIFY_STATUS :
422- input = button -> input ;
423- if (button -> type == ACPI_BUTTON_TYPE_LID ) {
424- if (button -> lid_state_initialized )
425- acpi_lid_update_state (device , true);
426- } else {
427- int keycode ;
428-
429- acpi_pm_wakeup_event (& device -> dev );
430- if (button -> suspended )
431- break ;
432-
433- keycode = test_bit (KEY_SLEEP , input -> keybit ) ?
434- KEY_SLEEP : KEY_POWER ;
435- input_report_key (input , keycode , 1 );
436- input_sync (input );
437- input_report_key (input , keycode , 0 );
438- input_sync (input );
439-
440- acpi_bus_generate_netlink_event (
441- device -> pnp .device_class ,
442- dev_name (& device -> dev ),
443- event , ++ button -> pushed );
444- }
445- break ;
446- default :
435+ if (event != ACPI_BUTTON_NOTIFY_STATUS ) {
447436 acpi_handle_debug (device -> handle , "Unsupported event [0x%x]\n" ,
448437 event );
449- break ;
438+ return ;
450439 }
440+
441+ acpi_pm_wakeup_event (& device -> dev );
442+
443+ button = acpi_driver_data (device );
444+ if (button -> suspended )
445+ return ;
446+
447+ input = button -> input ;
448+ keycode = test_bit (KEY_SLEEP , input -> keybit ) ? KEY_SLEEP : KEY_POWER ;
449+
450+ input_report_key (input , keycode , 1 );
451+ input_sync (input );
452+ input_report_key (input , keycode , 0 );
453+ input_sync (input );
454+
455+ acpi_bus_generate_netlink_event (device -> pnp .device_class ,
456+ dev_name (& device -> dev ),
457+ event , ++ button -> pushed );
458+ }
459+
460+ static void acpi_button_notify_run (void * data )
461+ {
462+ acpi_button_notify (NULL , ACPI_BUTTON_NOTIFY_STATUS , data );
463+ }
464+
465+ static u32 acpi_button_event (void * data )
466+ {
467+ acpi_os_execute (OSL_NOTIFY_HANDLER , acpi_button_notify_run , data );
468+ return ACPI_INTERRUPT_HANDLED ;
451469}
452470
453471#ifdef CONFIG_PM_SLEEP
@@ -489,11 +507,13 @@ static int acpi_lid_input_open(struct input_dev *input)
489507
490508static int acpi_button_add (struct acpi_device * device )
491509{
510+ acpi_notify_handler handler ;
492511 struct acpi_button * button ;
493512 struct input_dev * input ;
494513 const char * hid = acpi_device_hid (device );
514+ acpi_status status ;
495515 char * name , * class ;
496- int error ;
516+ int error = 0 ;
497517
498518 if (!strcmp (hid , ACPI_BUTTON_HID_LID ) &&
499519 lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED )
@@ -517,30 +537,36 @@ static int acpi_button_add(struct acpi_device *device)
517537 if (!strcmp (hid , ACPI_BUTTON_HID_POWER ) ||
518538 !strcmp (hid , ACPI_BUTTON_HID_POWERF )) {
519539 button -> type = ACPI_BUTTON_TYPE_POWER ;
540+ handler = acpi_button_notify ;
520541 strcpy (name , ACPI_BUTTON_DEVICE_NAME_POWER );
521542 sprintf (class , "%s/%s" ,
522543 ACPI_BUTTON_CLASS , ACPI_BUTTON_SUBCLASS_POWER );
523544 } else if (!strcmp (hid , ACPI_BUTTON_HID_SLEEP ) ||
524545 !strcmp (hid , ACPI_BUTTON_HID_SLEEPF )) {
525546 button -> type = ACPI_BUTTON_TYPE_SLEEP ;
547+ handler = acpi_button_notify ;
526548 strcpy (name , ACPI_BUTTON_DEVICE_NAME_SLEEP );
527549 sprintf (class , "%s/%s" ,
528550 ACPI_BUTTON_CLASS , ACPI_BUTTON_SUBCLASS_SLEEP );
529551 } else if (!strcmp (hid , ACPI_BUTTON_HID_LID )) {
530552 button -> type = ACPI_BUTTON_TYPE_LID ;
553+ handler = acpi_lid_notify ;
531554 strcpy (name , ACPI_BUTTON_DEVICE_NAME_LID );
532555 sprintf (class , "%s/%s" ,
533556 ACPI_BUTTON_CLASS , ACPI_BUTTON_SUBCLASS_LID );
534557 input -> open = acpi_lid_input_open ;
535558 } else {
536559 pr_info ("Unsupported hid [%s]\n" , hid );
537560 error = - ENODEV ;
538- goto err_free_input ;
539561 }
540562
541- error = acpi_button_add_fs (device );
542- if (error )
543- goto err_free_input ;
563+ if (!error )
564+ error = acpi_button_add_fs (device );
565+
566+ if (error ) {
567+ input_free_device (input );
568+ goto err_free_button ;
569+ }
544570
545571 snprintf (button -> phys , sizeof (button -> phys ), "%s/button/input0" , hid );
546572
@@ -568,6 +594,29 @@ static int acpi_button_add(struct acpi_device *device)
568594 error = input_register_device (input );
569595 if (error )
570596 goto err_remove_fs ;
597+
598+ switch (device -> device_type ) {
599+ case ACPI_BUS_TYPE_POWER_BUTTON :
600+ status = acpi_install_fixed_event_handler (ACPI_EVENT_POWER_BUTTON ,
601+ acpi_button_event ,
602+ device );
603+ break ;
604+ case ACPI_BUS_TYPE_SLEEP_BUTTON :
605+ status = acpi_install_fixed_event_handler (ACPI_EVENT_SLEEP_BUTTON ,
606+ acpi_button_event ,
607+ device );
608+ break ;
609+ default :
610+ status = acpi_install_notify_handler (device -> handle ,
611+ ACPI_DEVICE_NOTIFY , handler ,
612+ device );
613+ break ;
614+ }
615+ if (ACPI_FAILURE (status )) {
616+ error = - ENODEV ;
617+ goto err_input_unregister ;
618+ }
619+
571620 if (button -> type == ACPI_BUTTON_TYPE_LID ) {
572621 /*
573622 * This assumes there's only one lid device, or if there are
@@ -580,11 +629,11 @@ static int acpi_button_add(struct acpi_device *device)
580629 pr_info ("%s [%s]\n" , name , acpi_device_bid (device ));
581630 return 0 ;
582631
583- err_remove_fs :
632+ err_input_unregister :
633+ input_unregister_device (input );
634+ err_remove_fs :
584635 acpi_button_remove_fs (device );
585- err_free_input :
586- input_free_device (input );
587- err_free_button :
636+ err_free_button :
588637 kfree (button );
589638 return error ;
590639}
@@ -593,6 +642,24 @@ static void acpi_button_remove(struct acpi_device *device)
593642{
594643 struct acpi_button * button = acpi_driver_data (device );
595644
645+ switch (device -> device_type ) {
646+ case ACPI_BUS_TYPE_POWER_BUTTON :
647+ acpi_remove_fixed_event_handler (ACPI_EVENT_POWER_BUTTON ,
648+ acpi_button_event );
649+ break ;
650+ case ACPI_BUS_TYPE_SLEEP_BUTTON :
651+ acpi_remove_fixed_event_handler (ACPI_EVENT_SLEEP_BUTTON ,
652+ acpi_button_event );
653+ break ;
654+ default :
655+ acpi_remove_notify_handler (device -> handle , ACPI_DEVICE_NOTIFY ,
656+ button -> type == ACPI_BUTTON_TYPE_LID ?
657+ acpi_lid_notify :
658+ acpi_button_notify );
659+ break ;
660+ }
661+ acpi_os_wait_events_complete ();
662+
596663 acpi_button_remove_fs (device );
597664 input_unregister_device (button -> input );
598665 kfree (button );
0 commit comments