summaryrefslogtreecommitdiff
path: root/drivers/staging/gdm72xx/gdm_usb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 21:59:44 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 21:59:44 (GMT)
commit8966961b31c251b854169e9886394c2a20f2cea7 (patch)
tree248a625b23335acbd5ca4b55eb136fe0dc8ba0aa /drivers/staging/gdm72xx/gdm_usb.c
parent6a5971d8fea1f4a8c33dfe0cec6a1c490f0c9cde (diff)
parent7bcb57cde66c19df378f3468ea342166a8a4504d (diff)
downloadlinux-fsl-qoriq-8966961b31c251b854169e9886394c2a20f2cea7.tar.xz
Merge tag 'staging-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver tree merge from Greg Kroah-Hartman: "Here's the big staging tree merge for 3.8-rc1 There's a lot of patches in here, the majority being the comedi rework/cleanup that has been ongoing and is causing a huge reduction in overall code size, which is amazing to watch. We also removed some older drivers (telephony and rts_pstor), and added a new one (fwserial which also came in through the tty tree due to tty api changes, take that one if you get merge conflicts.) The iio and ipack drivers are moving out of the staging area into their own part of the kernel as they have been cleaned up sufficiently and are working well. Overall, again a reduction of code: 768 files changed, 31887 insertions(+), 82166 deletions(-) All of this has been in the linux-next tree for a while. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'staging-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1298 commits) iio: imu: adis16480: remove duplicated include from adis16480.c iio: gyro: adis16136: remove duplicated include from adis16136.c iio:imu: adis16480: show_firmware() buffer too small iio:gyro: adis16136: divide by zero in write_frequency() iio: adc: Add Texas Instruments ADC081C021/027 support iio:ad7793: Add support for the ad7796 and ad7797 iio:ad7793: Add support for the ad7798 and ad7799 staging:iio: Move ad7793 driver out of staging staging:iio:ad7793: Implement stricter id checking staging:iio:ad7793: Move register definitions from header to source staging:iio:ad7793: Rework regulator handling staging:iio:ad7793: Rework platform data staging:iio:ad7793: Use kstrtol instead of strict_strtol staging:iio:ad7793: Use usleep_range instead of msleep staging:iio:ad7793: Fix temperature scale staging:iio:ad7793: Fix VDD monitor scale staging: gdm72xx: unlock on error in init_usb() staging: panel: pass correct lengths to keypad_send_key() staging: comedi: addi_apci_2032: fix interrupt support staging: comedi: addi_apci_2032: move i_APCI2032_ConfigDigitalOutput() ...
Diffstat (limited to 'drivers/staging/gdm72xx/gdm_usb.c')
-rw-r--r--drivers/staging/gdm72xx/gdm_usb.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c
index 0c9e895..bce6104 100644
--- a/drivers/staging/gdm72xx/gdm_usb.c
+++ b/drivers/staging/gdm72xx/gdm_usb.c
@@ -186,6 +186,7 @@ static int init_usb(struct usbwm_dev *udev)
struct rx_cxt *rx = &udev->rx;
struct usb_tx *t;
struct usb_rx *r;
+ unsigned long flags;
INIT_LIST_HEAD(&tx->free_list);
INIT_LIST_HEAD(&tx->sdu_list);
@@ -200,14 +201,17 @@ static int init_usb(struct usbwm_dev *udev)
spin_lock_init(&tx->lock);
spin_lock_init(&rx->lock);
+ spin_lock_irqsave(&tx->lock, flags);
for (i = 0; i < MAX_NR_SDU_BUF; i++) {
t = alloc_tx_struct(tx);
if (t == NULL) {
+ spin_unlock_irqrestore(&tx->lock, flags);
ret = -ENOMEM;
goto fail;
}
list_add(&t->list, &tx->free_list);
}
+ spin_unlock_irqrestore(&tx->lock, flags);
r = alloc_rx_struct(rx);
if (r == NULL) {
@@ -215,7 +219,9 @@ static int init_usb(struct usbwm_dev *udev)
goto fail;
}
+ spin_lock_irqsave(&rx->lock, flags);
list_add(&r->list, &rx->free_list);
+ spin_unlock_irqrestore(&rx->lock, flags);
return ret;
fail:
@@ -229,6 +235,9 @@ static void release_usb(struct usbwm_dev *udev)
struct rx_cxt *rx = &udev->rx;
struct usb_tx *t, *t_next;
struct usb_rx *r, *r_next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx->lock, flags);
list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
list_del(&t->list);
@@ -245,6 +254,10 @@ static void release_usb(struct usbwm_dev *udev)
free_tx_struct(t);
}
+ spin_unlock_irqrestore(&tx->lock, flags);
+
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
list_del(&r->list);
free_rx_struct(r);
@@ -254,6 +267,8 @@ static void release_usb(struct usbwm_dev *udev)
list_del(&r->list);
free_rx_struct(r);
}
+
+ spin_unlock_irqrestore(&rx->lock, flags);
}
static void __gdm_usb_send_complete(struct urb *urb)
@@ -303,9 +318,12 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
u8 *pkt = data;
u16 cmd_evt;
unsigned long flags;
+#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
+ unsigned long flags2;
+#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
if (!udev->usbdev) {
- printk(KERN_ERR "%s: No such device\n", __func__);
+ dev_err(&usbdev->dev, "%s: No such device\n", __func__);
return -ENODEV;
}
@@ -371,13 +389,16 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags2);
list_for_each_entry(r, &rx->used_list, list)
usb_unlink_urb(r->urb);
+ spin_unlock_irqrestore(&rx->lock, flags2);
+
udev->bw_switch = 1;
- spin_lock(&k_lock);
+ spin_lock_irqsave(&k_lock, flags2);
list_add_tail(&udev->list, &k_list);
- spin_unlock(&k_lock);
+ spin_unlock_irqrestore(&k_lock, flags2);
wake_up(&k_wait);
}
@@ -416,7 +437,7 @@ static void gdm_usb_rcv_complete(struct urb *urb)
struct tx_cxt *tx = &udev->tx;
struct usb_tx *t;
u16 cmd_evt;
- unsigned long flags;
+ unsigned long flags, flags2;
#ifdef CONFIG_WIMAX_GDM72XX_USB_PM
struct usb_device *dev = urb->dev;
@@ -462,9 +483,9 @@ static void gdm_usb_rcv_complete(struct urb *urb)
if (!urb->status && r->callback)
r->callback(r->cb_data, r->buf, urb->actual_length);
- spin_lock(&rx->lock);
+ spin_lock_irqsave(&rx->lock, flags2);
put_rx_struct(rx, r);
- spin_unlock(&rx->lock);
+ spin_unlock_irqrestore(&rx->lock, flags2);
spin_unlock_irqrestore(&tx->lock, flags);
@@ -484,7 +505,7 @@ static int gdm_usb_receive(void *priv_dev,
unsigned long flags;
if (!udev->usbdev) {
- printk(KERN_ERR "%s: No such device\n", __func__);
+ dev_err(&usbdev->dev, "%s: No such device\n", __func__);
return -ENODEV;
}
@@ -559,9 +580,9 @@ static int gdm_usb_probe(struct usb_interface *intf,
idProduct = L2H(usbdev->descriptor.idProduct);
bcdDevice = L2H(usbdev->descriptor.bcdDevice);
- printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
- idVendor, idProduct);
- printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION);
+ dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
+ idVendor, idProduct);
+ dev_info(&intf->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION);
if (idProduct == EMERGENCY_PID) {
@@ -619,8 +640,9 @@ out:
if (ret) {
kfree(phy_dev);
kfree(udev);
+ } else {
+ usb_set_intfdata(intf, phy_dev);
}
- usb_set_intfdata(intf, phy_dev);
return ret;
}
@@ -660,14 +682,22 @@ static int gdm_suspend(struct usb_interface *intf, pm_message_t pm_msg)
struct usbwm_dev *udev;
struct rx_cxt *rx;
struct usb_rx *r;
+ unsigned long flags;
phy_dev = usb_get_intfdata(intf);
+ if (!phy_dev)
+ return 0;
+
udev = phy_dev->priv_dev;
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_unlink_urb(r->urb);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
return 0;
}
@@ -677,14 +707,22 @@ static int gdm_resume(struct usb_interface *intf)
struct usbwm_dev *udev;
struct rx_cxt *rx;
struct usb_rx *r;
+ unsigned long flags;
phy_dev = usb_get_intfdata(intf);
+ if (!phy_dev)
+ return 0;
+
udev = phy_dev->priv_dev;
rx = &udev->rx;
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_submit_urb(r->urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
return 0;
}
@@ -719,9 +757,13 @@ static int k_mode_thread(void *arg)
while (jiffies < expire)
schedule_timeout(K_WAIT_TIME);
+ spin_lock_irqsave(&rx->lock, flags);
+
list_for_each_entry(r, &rx->used_list, list)
usb_submit_urb(r->urb, GFP_ATOMIC);
+ spin_unlock_irqrestore(&rx->lock, flags);
+
spin_lock_irqsave(&tx->lock, flags);
list_for_each_entry_safe(t, temp, &tx->pending_list,