Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michael Hennerich and committed by
Greg Kroah-Hartman
ebb8a4e4 76078dc4

+2
+2
drivers/usb/host/isp1760-hcd.c
··· 829 829 * almost immediately. With ISP1761, this register requires a delay of 830 830 * 195ns between a write and subsequent read (see section 15.1.1.3). 831 831 */ 832 + mmiowb(); 832 833 ndelay(195); 833 834 skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); 834 835 ··· 871 870 * almost immediately. With ISP1761, this register requires a delay of 872 871 * 195ns between a write and subsequent read (see section 15.1.1.3). 873 872 */ 873 + mmiowb(); 874 874 ndelay(195); 875 875 skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); 876 876