[PATCH 3.18 23/83] Input: xpad - re-send LED command on present event

From: Greg Kroah-Hartman
Date: Thu Nov 29 2018 - 09:14:17 EST


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@xxxxxxxxx>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
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


--
2.17.1