From 5209dc65c1ff40a46187f5de27190a58f8d59be9 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Sun, 27 Sep 2015 23:43:09 +0200 Subject: [PATCH] Input: xpad: replace mutex by spinlock since we cannot use mutexes in xpad_play_effect. see: http://www.spinics.net/lists/linux-input/msg40242.html --- xpad.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/xpad.c b/xpad.c index c5387b2..8fbe7b0 100644 --- a/xpad.c +++ b/xpad.c @@ -333,7 +333,7 @@ struct usb_xpad { int irq_out_active; /* we must not use an active URB */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; - struct mutex odata_mutex; + spinlock_t odata_lock; #if defined(CONFIG_JOYSTICK_XPAD_LEDS) struct xpad_led *led; @@ -751,7 +751,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) goto fail1; } - mutex_init(&xpad->odata_mutex); + spin_lock_init(&xpad->odata_lock); xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) { @@ -799,13 +799,15 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect __u16 weak; int retval; + unsigned long flags; + if (effect->type != FF_RUMBLE) return 0; strong = effect->u.rumble.strong_magnitude; weak = effect->u.rumble.weak_magnitude; - mutex_lock(&xpad->odata_mutex); + spin_lock_irqsave(&xpad->odata_lock, flags); switch (xpad->xtype) { case XTYPE_XBOX: @@ -863,7 +865,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect break; default: - mutex_unlock(&xpad->odata_mutex); + spin_unlock_irqrestore(&xpad->odata_lock, flags); dev_dbg(&xpad->dev->dev, "%s - rumble command sent to unsupported xpad type: %d\n", __func__, xpad->xtype); @@ -879,7 +881,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect __func__); } - mutex_unlock(&xpad->odata_mutex); + spin_unlock_irqrestore(&xpad->odata_lock, flags); return retval; } @@ -929,9 +931,11 @@ struct xpad_led { */ static void xpad_send_led_command(struct usb_xpad *xpad, int command) { + unsigned long flags; + command %= 16; - mutex_lock(&xpad->odata_mutex); + spin_lock_irqsave(&xpad->odata_lock, flags); switch (xpad->xtype) { case XTYPE_XBOX360: @@ -964,7 +968,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command) dev_dbg(&xpad->dev->dev, "%s - dropped, irq_out is active\n", __func__); - mutex_unlock(&xpad->odata_mutex); + spin_unlock_irqrestore(&xpad->odata_lock, flags); } /* @@ -1041,6 +1045,8 @@ static int xpad_open(struct input_dev *dev) struct usb_xpad *xpad = input_get_drvdata(dev); int retval; + unsigned long flags; + /* URB was submitted in probe */ if (xpad->xtype == XTYPE_XBOX360W) return 0; @@ -1050,13 +1056,13 @@ static int xpad_open(struct input_dev *dev) return -EIO; if (xpad->xtype == XTYPE_XBOXONE) { - mutex_lock(&xpad->odata_mutex); + spin_lock_irqsave(&xpad->odata_lock, flags); /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; xpad->odata[1] = 0x20; xpad->irq_out->transfer_buffer_length = 2; retval = usb_submit_urb(xpad->irq_out, GFP_KERNEL); - mutex_unlock(&xpad->odata_mutex); + spin_unlock_irqrestore(&xpad->odata_lock, flags); return retval; } @@ -1200,6 +1206,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id int ep_irq_in_idx; int i, error; + unsigned long flags; + for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) @@ -1301,7 +1309,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id * adapter has been plugged in, as it won't automatically * send us info about the controllers. */ - mutex_lock(&xpad->odata_mutex); + spin_lock_irqsave(&xpad->odata_lock, flags); xpad->odata[0] = 0x08; xpad->odata[1] = 0x00; xpad->odata[2] = 0x0F; @@ -1323,7 +1331,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id dev_dbg(&xpad->dev->dev, "%s - dropped, irq_out is active\n", __func__); - mutex_unlock(&xpad->odata_mutex); + spin_unlock_irqrestore(&xpad->odata_lock, flags); } else { xpad->pad_present = 1; error = xpad_init_input(xpad);