aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2010-08-05 17:53:57 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-23 23:50:15 -0400
commitebb8a4e48722c8f5e04a6490b197d2fbc894a0f6 (patch)
tree6fd92615398fae2af9ada5206f52dafde7d4e16a /drivers/usb
parent76078dc4fc389185fe467d33428f259ea9e69807 (diff)
USB: isp1760: use a write barrier to ensure proper ndelay timing
The ISP1760 has some timing requirements where it has to delay a short period after a write to a register has started. However, this delay is from the time the write hits the USB chip (the ISP1760), not from the time where the processor started processing the write. So on a quick enough processor, it is sometimes possible for the write to not hit the device before we start delaying, and we then violate the part's timing requirements, so things stop working. To avoid all this, insert a write barrier after the register write and before the timing delay/register read so we can guarantee we only start counting time after the write has hit the device. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/isp1760-hcd.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index d1a3dfc9a408..bdba8c5d844a 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -829,6 +829,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
829 * almost immediately. With ISP1761, this register requires a delay of 829 * almost immediately. With ISP1761, this register requires a delay of
830 * 195ns between a write and subsequent read (see section 15.1.1.3). 830 * 195ns between a write and subsequent read (see section 15.1.1.3).
831 */ 831 */
832 mmiowb();
832 ndelay(195); 833 ndelay(195);
833 skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); 834 skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
834 835
@@ -870,6 +871,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
870 * almost immediately. With ISP1761, this register requires a delay of 871 * almost immediately. With ISP1761, this register requires a delay of
871 * 195ns between a write and subsequent read (see section 15.1.1.3). 872 * 195ns between a write and subsequent read (see section 15.1.1.3).
872 */ 873 */
874 mmiowb();
873 ndelay(195); 875 ndelay(195);
874 skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); 876 skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
875 877