[PATCH v2 52/85] USB: mos7840: remove smp barriers from icount handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Remove SMP memory barriers from icount handling and rely on the barriers
implied by wait_event, sleep and locks, while using the port lock to
guarantee atomicity.

This is a step in moving over to the generic icount implementations.

Signed-off-by: Johan Hovold <jhovold@xxxxxxxxx>
---
 drivers/usb/serial/mos7840.c | 47 +++++++++++++++++---------------------------
 1 file changed, 18 insertions(+), 29 deletions(-)

diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index d07ca11..8bd9721 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -407,22 +407,14 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
 		icount = &mos7840_port->icount;
 
 		/* update input line counters */
-		if (new_msr & MOS_MSR_DELTA_CTS) {
+		if (new_msr & MOS_MSR_DELTA_CTS)
 			icount->cts++;
-			smp_wmb();
-		}
-		if (new_msr & MOS_MSR_DELTA_DSR) {
+		if (new_msr & MOS_MSR_DELTA_DSR)
 			icount->dsr++;
-			smp_wmb();
-		}
-		if (new_msr & MOS_MSR_DELTA_CD) {
+		if (new_msr & MOS_MSR_DELTA_CD)
 			icount->dcd++;
-			smp_wmb();
-		}
-		if (new_msr & MOS_MSR_DELTA_RI) {
+		if (new_msr & MOS_MSR_DELTA_RI)
 			icount->rng++;
-			smp_wmb();
-		}
 
 		mos7840_port->delta_msr_cond = 1;
 		wake_up(&mos7840_port->delta_msr_wait);
@@ -444,22 +436,14 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
 
 	/* update input line counters */
 	icount = &port->icount;
-	if (new_lsr & SERIAL_LSR_BI) {
+	if (new_lsr & SERIAL_LSR_BI)
 		icount->brk++;
-		smp_wmb();
-	}
-	if (new_lsr & SERIAL_LSR_OE) {
+	if (new_lsr & SERIAL_LSR_OE)
 		icount->overrun++;
-		smp_wmb();
-	}
-	if (new_lsr & SERIAL_LSR_PE) {
+	if (new_lsr & SERIAL_LSR_PE)
 		icount->parity++;
-		smp_wmb();
-	}
-	if (new_lsr & SERIAL_LSR_FE) {
+	if (new_lsr & SERIAL_LSR_FE)
 		icount->frame++;
-		smp_wmb();
-	}
 }
 
 /************************************************************************/
@@ -779,7 +763,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)
 		tty_insert_flip_string(tport, data, urb->actual_length);
 		tty_flip_buffer_push(tport);
 		mos7840_port->icount.rx += urb->actual_length;
-		smp_wmb();
 		dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx);
 	}
 
@@ -1510,7 +1493,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
 	}
 	bytes_sent = transfer_size;
 	mos7840_port->icount.tx += transfer_size;
-	smp_wmb();
 	dev_dbg(&port->dev, "mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx);
 exit:
 	return bytes_sent;
@@ -2136,11 +2118,14 @@ static int mos7840_get_icount(struct tty_struct *tty,
 	struct usb_serial_port *port = tty->driver_data;
 	struct moschip_port *mos7840_port;
 	struct async_icount cnow;
+	unsigned long flags;
 
 	mos7840_port = mos7840_get_port_private(port);
+
+	spin_lock_irqsave(&port->lock, flags);
 	cnow = mos7840_port->icount;
+	spin_unlock_irqrestore(&port->lock, flags);
 
-	smp_rmb();
 	icount->cts = cnow.cts;
 	icount->dsr = cnow.dsr;
 	icount->rng = cnow.rng;
@@ -2169,7 +2154,7 @@ static int mos7840_ioctl(struct tty_struct *tty,
 	struct usb_serial_port *port = tty->driver_data;
 	void __user *argp = (void __user *)arg;
 	struct moschip_port *mos7840_port;
-
+	unsigned long flags;
 	struct async_icount cnow;
 	struct async_icount cprev;
 
@@ -2200,7 +2185,9 @@ static int mos7840_ioctl(struct tty_struct *tty,
 
 	case TIOCMIWAIT:
 		dev_dbg(&port->dev, "%s  TIOCMIWAIT\n", __func__);
+		spin_lock_irqsave(&port->lock, flags);
 		cprev = mos7840_port->icount;
+		spin_unlock_irqrestore(&port->lock, flags);
 		while (1) {
 			/* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
 			mos7840_port->delta_msr_cond = 0;
@@ -2216,8 +2203,10 @@ static int mos7840_ioctl(struct tty_struct *tty,
 			if (port->serial->disconnected)
 				return -EIO;
 
+			spin_lock_irqsave(&port->lock, flags);
 			cnow = mos7840_port->icount;
-			smp_rmb();
+			spin_unlock_irqrestore(&port->lock, flags);
+
 			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
 			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
 			    ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux