]> git.karo-electronics.de Git - linux-beck.git/commitdiff
usb: musb: Add pre and post root port reset end callbacks
authorHans de Goede <hdegoede@redhat.com>
Sun, 29 Mar 2015 10:50:47 +0000 (12:50 +0200)
committerFelipe Balbi <balbi@ti.com>
Tue, 26 May 2015 15:38:24 +0000 (10:38 -0500)
The sunxi otg phy has a bug where it wrongly detects a high speed squelch
when reset on the root port gets de-asserted with a lo-speed device.

The workaround for this is to disable squelch detect before de-asserting
reset, and re-enabling it after the reset de-assert is done.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_virthub.c

index c7a0d933eff904f0d64a15f16947abc58f6ac6d7..71172266c65e5f8dad1445a1e202032669669c77 100644 (file)
@@ -167,6 +167,8 @@ struct musb_io;
  * @vbus_status: returns vbus status if possible
  * @set_vbus:  forces vbus status
  * @adjust_channel_params: pre check for standard dma channel_program func
+ * @pre_root_reset_end: called before the root usb port reset flag gets cleared
+ * @post_root_reset_end: called after the root usb port reset flag gets cleared
  */
 struct musb_platform_ops {
 
@@ -210,6 +212,8 @@ struct musb_platform_ops {
        int     (*adjust_channel_params)(struct dma_channel *channel,
                                u16 packet_sz, u8 *mode,
                                dma_addr_t *dma_addr, u32 *len);
+       void    (*pre_root_reset_end)(struct musb *musb);
+       void    (*post_root_reset_end)(struct musb *musb);
 };
 
 /*
@@ -595,4 +599,16 @@ static inline int musb_platform_exit(struct musb *musb)
        return musb->ops->exit(musb);
 }
 
+static inline void musb_platform_pre_root_reset_end(struct musb *musb)
+{
+       if (musb->ops->pre_root_reset_end)
+               musb->ops->pre_root_reset_end(musb);
+}
+
+static inline void musb_platform_post_root_reset_end(struct musb *musb)
+{
+       if (musb->ops->post_root_reset_end)
+               musb->ops->post_root_reset_end(musb);
+}
+
 #endif /* __MUSB_CORE_H__ */
index 86c4b533e90b3f9d33c4ff06c8e58d59928754f3..30842bc195f57fced81ff6190f4758570ee77d3e 100644 (file)
@@ -195,8 +195,10 @@ void musb_port_reset(struct musb *musb, bool do_reset)
                                      msecs_to_jiffies(50));
        } else {
                dev_dbg(musb->controller, "root port reset stopped\n");
+               musb_platform_pre_root_reset_end(musb);
                musb_writeb(mbase, MUSB_POWER,
                                power & ~MUSB_POWER_RESET);
+               musb_platform_post_root_reset_end(musb);
 
                power = musb_readb(mbase, MUSB_POWER);
                if (power & MUSB_POWER_HSMODE) {