]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
usb: host: max3421-hcd: Use atomic bitops in lieu of bit fields
authorDavid Mosberger-Tang <davidm@egauge.net>
Thu, 19 Jun 2014 18:56:53 +0000 (12:56 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2014 23:06:35 +0000 (16:06 -0700)
Bit fields are not MP-safe.

Signed-off-by: David Mosberger <davidm@egauge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/max3421-hcd.c

index 858efcfda50bdff9cc1603221348ecc234cac17e..f8ecd7d7212d28e5ea65afbc5f387fc67e21f952 100644 (file)
@@ -102,6 +102,15 @@ enum scheduling_pass {
        SCHED_PASS_DONE
 };
 
+/* Bit numbers for max3421_hcd->todo: */
+enum {
+       ENABLE_IRQ = 0,
+       RESET_HCD,
+       RESET_PORT,
+       CHECK_UNLINK,
+       IOPIN_UPDATE
+};
+
 struct max3421_dma_buf {
        u8 data[2];
 };
@@ -146,11 +155,7 @@ struct max3421_hcd {
        u8 hien;
        u8 mode;
        u8 iopins[2];
-       unsigned int do_enable_irq:1;
-       unsigned int do_reset_hcd:1;
-       unsigned int do_reset_port:1;
-       unsigned int do_check_unlink:1;
-       unsigned int do_iopin_update:1;
+       unsigned long todo;
 #ifdef DEBUG
        unsigned long err_stat[16];
 #endif
@@ -1165,10 +1170,8 @@ max3421_irq_handler(int irq, void *dev_id)
        if (max3421_hcd->spi_thread &&
            max3421_hcd->spi_thread->state != TASK_RUNNING)
                wake_up_process(max3421_hcd->spi_thread);
-       if (!max3421_hcd->do_enable_irq) {
-               max3421_hcd->do_enable_irq = 1;
+       if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo))
                disable_irq_nosync(spi->irq);
-       }
        return IRQ_HANDLED;
 }
 
@@ -1423,10 +1426,8 @@ max3421_spi_thread(void *dev_id)
                        spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien);
 
                        set_current_state(TASK_INTERRUPTIBLE);
-                       if (max3421_hcd->do_enable_irq) {
-                               max3421_hcd->do_enable_irq = 0;
+                       if (test_and_clear_bit(ENABLE_IRQ, &max3421_hcd->todo))
                                enable_irq(spi->irq);
-                       }
                        schedule();
                        __set_current_state(TASK_RUNNING);
                }
@@ -1440,23 +1441,18 @@ max3421_spi_thread(void *dev_id)
                else if (!max3421_hcd->curr_urb)
                        i_worked |= max3421_select_and_start_urb(hcd);
 
-               if (max3421_hcd->do_reset_hcd) {
+               if (test_and_clear_bit(RESET_HCD, &max3421_hcd->todo))
                        /* reset the HCD: */
-                       max3421_hcd->do_reset_hcd = 0;
                        i_worked |= max3421_reset_hcd(hcd);
-               }
-               if (max3421_hcd->do_reset_port) {
+               if (test_and_clear_bit(RESET_PORT, &max3421_hcd->todo)) {
                        /* perform a USB bus reset: */
-                       max3421_hcd->do_reset_port = 0;
                        spi_wr8(hcd, MAX3421_REG_HCTL,
                                BIT(MAX3421_HCTL_BUSRST_BIT));
                        i_worked = 1;
                }
-               if (max3421_hcd->do_check_unlink) {
-                       max3421_hcd->do_check_unlink = 0;
+               if (test_and_clear_bit(CHECK_UNLINK, &max3421_hcd->todo))
                        i_worked |= max3421_check_unlink(hcd);
-               }
-               if (max3421_hcd->do_iopin_update) {
+               if (test_and_clear_bit(IOPIN_UPDATE, &max3421_hcd->todo)) {
                        /*
                         * IOPINS1/IOPINS2 do not auto-increment, so we can't
                         * use spi_wr_buf().
@@ -1469,7 +1465,6 @@ max3421_spi_thread(void *dev_id)
                                spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val);
                                max3421_hcd->iopins[i] = val;
                        }
-                       max3421_hcd->do_iopin_update = 0;
                        i_worked = 1;
                }
        }
@@ -1485,7 +1480,7 @@ max3421_reset_port(struct usb_hcd *hcd)
 
        max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE |
                                      USB_PORT_STAT_LOW_SPEED);
-       max3421_hcd->do_reset_port = 1;
+       set_bit(RESET_PORT, &max3421_hcd->todo);
        wake_up_process(max3421_hcd->spi_thread);
        return 0;
 }
@@ -1498,7 +1493,7 @@ max3421_reset(struct usb_hcd *hcd)
        hcd->self.sg_tablesize = 0;
        hcd->speed = HCD_USB2;
        hcd->self.root_hub->speed = USB_SPEED_FULL;
-       max3421_hcd->do_reset_hcd = 1;
+       set_bit(RESET_HCD, &max3421_hcd->todo);
        wake_up_process(max3421_hcd->spi_thread);
        return 0;
 }
@@ -1590,7 +1585,7 @@ max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
         */
        retval = usb_hcd_check_unlink_urb(hcd, urb, status);
        if (retval == 0) {
-               max3421_hcd->do_check_unlink = 1;
+               set_bit(CHECK_UNLINK, &max3421_hcd->todo);
                wake_up_process(max3421_hcd->spi_thread);
        }
        spin_unlock_irqrestore(&max3421_hcd->lock, flags);
@@ -1690,7 +1685,7 @@ max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value)
                max3421_hcd->iopins[idx] |=  mask;
        else
                max3421_hcd->iopins[idx] &= ~mask;
-       max3421_hcd->do_iopin_update = 1;
+       set_bit(IOPIN_UPDATE, &max3421_hcd->todo);
        wake_up_process(max3421_hcd->spi_thread);
 }