3.18-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit cae705baa40b2c20de8f9bb79ef4bcc6b2418c7c ]
The controller only receives commands when its present. So for the correct LED to be lit the LED command has to be sent on the present event.
Signed-off-by: Pavel Rojtberg rojtberg@gmail.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/joystick/xpad.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 5606e66ca5a5..a66720136290 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -346,6 +346,7 @@ struct usb_xpad {
int mapping; /* map d-pad to buttons or to axes */ int xtype; /* type of xbox device */ + unsigned long led_no; /* led to lit on xbox360 controllers */ };
/* @@ -490,6 +491,8 @@ static void xpad360_process_packet(struct usb_xpad *xpad, input_sync(dev); }
+static void xpad_identify_controller(struct usb_xpad *xpad); + /* * xpad360w_process_packet * @@ -512,6 +515,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha if (data[1] & 0x80) { xpad->pad_present = 1; usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); + /* + * Light up the segment corresponding to + * controller number. + */ + xpad_identify_controller(xpad); } else xpad->pad_present = 0; } @@ -936,6 +944,12 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command) mutex_unlock(&xpad->odata_mutex); }
+static void xpad_identify_controller(struct usb_xpad *xpad) +{ + /* Light up the segment corresponding to controller number */ + xpad_send_led_command(xpad, (xpad->led_no % 4) + 2); +} + static void xpad_led_set(struct led_classdev *led_cdev, enum led_brightness value) { @@ -947,8 +961,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe(struct usb_xpad *xpad) { - static atomic_t led_seq = ATOMIC_INIT(-1); - unsigned long led_no; + static atomic_t led_seq = ATOMIC_INIT(-1); struct xpad_led *led; struct led_classdev *led_cdev; int error; @@ -960,9 +973,9 @@ static int xpad_led_probe(struct usb_xpad *xpad) if (!led) return -ENOMEM;
- led_no = atomic_inc_return(&led_seq); + xpad->led_no = atomic_inc_return(&led_seq);
- snprintf(led->name, sizeof(led->name), "xpad%lu", led_no); + snprintf(led->name, sizeof(led->name), "xpad%lu", xpad->led_no); led->xpad = xpad;
led_cdev = &led->led_cdev; @@ -976,10 +989,8 @@ static int xpad_led_probe(struct usb_xpad *xpad) return error; }
- /* - * Light up the segment corresponding to controller number - */ - xpad_send_led_command(xpad, (led_no % 4) + 2); + /* Light up the segment corresponding to controller number */ + xpad_identify_controller(xpad);
return 0; } @@ -996,6 +1007,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) #else static int xpad_led_probe(struct usb_xpad *xpad) { return 0; } static void xpad_led_disconnect(struct usb_xpad *xpad) { } +static void xpad_identify_controller(struct usb_xpad *xpad) { } #endif