* Sergei Shtylyov <[email protected]> [150319 06:30]:
> On 3/19/2015 1:48 AM, Tony Lindgren wrote:
>
> >Looks like dm81xx can only do 32-bit fifo reads like am35x. Let's set
> >up musb-dsps with a custom read_fifo function based on the compatible
> >flag.
...
> >--- a/drivers/usb/musb/musb_dsps.c
> >+++ b/drivers/usb/musb/musb_dsps.c
> >+/* Similar to am35x, dm81xx support only 32-bit read operation */
> >+static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
> >+{
> >+ void __iomem *fifo = hw_ep->fifo;
> >+ u32 val;
> >+ int i;
> >+
> >+ /* Read for 32bit-aligned destination address */
> >+ if (likely((0x03 & (unsigned long)dst) == 0) && len >= 4) {
> >+ readsl(fifo, dst, len >> 2);
> >+ dst += len & ~0x03;
> >+ len &= 0x03;
> >+ }
> >+ /*
> >+ * Now read the remaining 1 to 3 byte or complete length if
> >+ * unaligned address.
> >+ */
>
> This comment seems misplaced, it belongs before the next *if*.
>
> >+ if (len > 4) {
> >+ for (i = 0; i < (len >> 2); i++) {
> >+ *(u32 *)dst = musb_readl(fifo, 0);
> >+ dst += 4;
> >+ }
>
> Not sure how this is different to using readsl().
>
> >+ len &= 0x03;
> >+ }
> >+ if (len > 0) {
> >+ val = musb_readl(fifo, 0);
> >+ memcpy(dst, &val, len);
> >+ }
> >+}
Indeed, thanks for looking at it. That function in the TI kernel probably
had something else for the 32-bit aligned case that got swapped to use
readsl().
Looks like the following works just fine for me with a USB Ethernet
and variable size ping test:
static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
{
void __iomem *fifo = hw_ep->fifo;
if (len >= 4) {
readsl(fifo, dst, len >> 2);
dst += len & ~0x03;
len &= 0x03;
}
/* Read any remaining 1 to 3 bytes */
if (len > 0) {
u32 val = musb_readl(fifo, 0);
memcpy(dst, &val, len);
}
}
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html