@@ -710,6 +710,7 @@ struct usb_xpad {
710710 int quirks ;
711711 const char * name ; /* name of the device */
712712 struct work_struct work ; /* init/remove device from callback */
713+ struct delayed_work poweroff_work ; /* work struct for poweroff on mode long press */
713714 time64_t mode_btn_down_ts ;
714715};
715716
@@ -871,20 +872,29 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
871872
872873 /* XBOX360W controllers can't be turned off without driver assistance */
873874 if (xpad -> xtype == XTYPE_XBOX360W ) {
874- if (xpad -> mode_btn_down_ts > 0 && xpad -> pad_present &&
875- (( ktime_get_seconds () - xpad -> mode_btn_down_ts ) >=
876- XPAD360W_POWEROFF_TIMEOUT )) {
877- xpad360w_poweroff_controller ( xpad );
878- xpad -> mode_btn_down_ts = 0 ;
879- return ;
875+ if (data [ 3 ] & BIT ( 2 )) {
876+ if ( xpad -> mode_btn_down_ts == 0 )
877+ xpad -> mode_btn_down_ts = ktime_get_seconds ();
878+ schedule_delayed_work ( & xpad -> poweroff_work , msecs_to_jiffies ( 0 ) );
879+ } else {
880+ xpad -> mode_btn_down_ts = 0 ;
880881 }
882+ }
883+ }
881884
882- /* mode button down/up */
883- if (data [3 ] & BIT (2 ))
884- xpad -> mode_btn_down_ts = ktime_get_seconds ();
885- else
886- xpad -> mode_btn_down_ts = 0 ;
885+ static void xpad360w_poweroff_work (struct work_struct * work ) {
886+ struct usb_xpad * xpad = container_of (to_delayed_work (work ), struct usb_xpad , poweroff_work );
887+
888+ if (xpad -> mode_btn_down_ts == 0 )
889+ return ;
890+
891+ if ((ktime_get_seconds () - xpad -> mode_btn_down_ts ) >= XPAD360W_POWEROFF_TIMEOUT ) {
892+ xpad360w_poweroff_controller (xpad );
893+ xpad -> mode_btn_down_ts = 0 ;
894+ return ;
887895 }
896+
897+ schedule_delayed_work (& xpad -> poweroff_work , msecs_to_jiffies (200 ));
888898}
889899
890900static void xpad_presence_work (struct work_struct * work )
@@ -1864,6 +1874,8 @@ static int xpad360w_start_input(struct usb_xpad *xpad)
18641874 return error ;
18651875 }
18661876
1877+ INIT_DELAYED_WORK (& xpad -> poweroff_work , xpad360w_poweroff_work );
1878+
18671879 return 0 ;
18681880}
18691881
@@ -1873,6 +1885,7 @@ static void xpad360w_stop_input(struct usb_xpad *xpad)
18731885
18741886 /* Make sure we are done with presence work if it was scheduled */
18751887 flush_work (& xpad -> work );
1888+ flush_delayed_work (& xpad -> poweroff_work );
18761889}
18771890
18781891static int xpad_open (struct input_dev * dev )
0 commit comments