[U-Boot] [PATCH 11/22] musb: Allow musb_platform_enable to return an error code

Hans de Goede
2015-06-17T19:33:54Z

Allow musb_platform_enable to return an error code and propagate it up to
usb_lowlevel_init().

This allows moving the checks for an external vbus being present to be
moved from platform_init to platform_enable, so that the user can unplug a
charger, plug in a host adapter with a usb-device, do a "usb reset" and
have things working.

This also allows adding a check for the id-pin to platform_enable, so that
it can short circuit the 1s delay in usb_lowlevel_init() when no host cable
is plugged in and thus waiting for a device to show up is useless.

Note that all the changes to code shared with the kernel are wrapped in
the kernel.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/musb-new/am35x.c | 7 +++++++
drivers/usb/musb-new/musb_core.c | 20 ++++++++++++++++++++
drivers/usb/musb-new/musb_core.h | 18 ++++++++++++++++++
drivers/usb/musb-new/musb_dsps.c | 6 ++++++
drivers/usb/musb-new/musb_uboot.c | 6 +++++-
drivers/usb/musb-new/omap2430.c | 5 +++++
drivers/usb/musb-new/sunxi.c | 5 +++--
7 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c
index 857d7eb..d158454 100644
--- a/drivers/usb/musb-new/am35x.c
+++ b/drivers/usb/musb-new/am35x.c
@@ -100,7 +100,11 @@ struct am35x_glue {
/*
* am35x_musb_enable - enable interrupts
*/
+#ifndef __UBOOT__
static void am35x_musb_enable(struct musb *musb)
+#else
+static int am35x_musb_enable(struct musb *musb)
+#endif
{
void __iomem *reg_base = musb->ctrl_base;
u32 epmask;
@@ -116,6 +120,9 @@ static void am35x_musb_enable(struct musb *musb)
if (is_otg_enabled(musb))
musb_writel(reg_base, CORE_INTR_SRC_SET_REG,
AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT);
+#ifdef __UBOOT__
+ return 0;
+#endif
}

/*
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
index 242cc30..f530af4 100644
--- a/drivers/usb/musb-new/musb_core.c
+++ b/drivers/usb/musb-new/musb_core.c
@@ -926,10 +926,17 @@ b_host:
/*
* Program the HDRC to start (enable interrupts, dma, etc.).
*/
+#ifndef __UBOOT__
void musb_start(struct musb *musb)
+#else
+int musb_start(struct musb *musb)
+#endif
{
void __iomem *regs = musb->mregs;
u8 devctl = musb_readb(regs, MUSB_DEVCTL);
+#ifdef __UBOOT__
+ int ret;
+#endif

dev_dbg(musb->controller, "<== devctl %02x\n", devctl);

@@ -972,8 +979,21 @@ void musb_start(struct musb *musb)
if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
musb->is_active = 1;
}
+
+#ifndef __UBOOT__
musb_platform_enable(musb);
+#else
+ ret = musb_platform_enable(musb);
+ if (ret) {
+ musb->is_active = 0;
+ return ret;
+ }
+#endif
musb_writeb(regs, MUSB_DEVCTL, devctl);
+
+#ifdef __UBOOT__
+ return 0;
+#endif
}

diff --git a/drivers/usb/musb-new/musb_core.h b/drivers/usb/musb-new/musb_core.h
index 2695742..8727f64 100644
--- a/drivers/usb/musb-new/musb_core.h
+++ b/drivers/usb/musb-new/musb_core.h
@@ -231,7 +231,11 @@ struct musb_platform_ops {
int (*init)(struct musb *musb);
int (*exit)(struct musb *musb);

+#ifndef __UBOOT__
void (*enable)(struct musb *musb);
+#else
+ int (*enable)(struct musb *musb);
+#endif
void (*disable)(struct musb *musb);

int (*set_mode)(struct musb *musb, u8 mode);
@@ -546,7 +550,11 @@ static inline void musb_configure_ep0(struct musb *musb)

extern const char musb_driver_name[];

+#ifndef __UBOOT__
extern void musb_start(struct musb *musb);
+#else
+extern int musb_start(struct musb *musb);
+#endif
extern void musb_stop(struct musb *musb);

extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
@@ -564,11 +572,21 @@ static inline void musb_platform_set_vbus(struct musb *musb, int is_on)
musb->ops->set_vbus(musb, is_on);
}

+#ifndef __UBOOT__
static inline void musb_platform_enable(struct musb *musb)
{
if (musb->ops->enable)
musb->ops->enable(musb);
}
+#else
+static inline int musb_platform_enable(struct musb *musb)
+{
+ if (!musb->ops->enable)
+ return 0;
+
+ return musb->ops->enable(musb);
+}
+#endif

static inline void musb_platform_disable(struct musb *musb)
{
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
index 17ed224..8959397 100644
--- a/drivers/usb/musb-new/musb_dsps.c
+++ b/drivers/usb/musb-new/musb_dsps.c
@@ -156,7 +156,11 @@ struct dsps_glue {
/**
* dsps_musb_enable - enable interrupts
*/
+#ifndef __UBOOT__
static void dsps_musb_enable(struct musb *musb)
+#else
+static int dsps_musb_enable(struct musb *musb)
+#endif
{
#ifndef __UBOOT__
struct device *dev = musb->controller;
@@ -181,6 +185,8 @@ static void dsps_musb_enable(struct musb *musb)
if (is_otg_enabled(musb))
dsps_writel(reg_base, wrp->coreintr_set,
(1 << wrp->drvvbus) << wrp->usb_shift);
+#else
+ return 0;
#endif
}

diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 1bf676c..70e87c9 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -217,13 +217,17 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
void *mbase;
/* USB spec says it may take up to 1 second for a device to connect */
unsigned long timeout = get_timer(0) + 1000;
+ int ret;

if (!host) {
printf("MUSB host is not registered\n");
return -ENODEV;
}

- musb_start(host);
+ ret = musb_start(host);
+ if (ret)
+ return ret;
+
mbase = host->mregs;
do {
if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index 31a280e..77273a4 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -400,7 +400,11 @@ err1:
return status;
}

+#ifndef __UBOOT__
static void omap2430_musb_enable(struct musb *musb)
+#else
+static int omap2430_musb_enable(struct musb *musb)
+#endif
{
#ifndef __UBOOT__
u8 devctl;
@@ -445,6 +449,7 @@ static void omap2430_musb_enable(struct musb *musb)
__PRETTY_FUNCTION__);
}
#endif
+ return 0;
#endif
}

diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 052e065..c123d61 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -199,12 +199,12 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
/* musb_core does not call enable / disable in a balanced manner <sigh> */
static bool enabled = false;

-static void sunxi_musb_enable(struct musb *musb)
+static int sunxi_musb_enable(struct musb *musb)
{
pr_debug("%s():\n", __func__);

if (enabled)
- return;
+ return 0;

/* select PIO mode */
musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
@@ -215,6 +215,7 @@ static void sunxi_musb_enable(struct musb *musb)
USBC_ForceVbusValidToHigh(musb->mregs);

enabled = true;
+ return 0;
}

static void sunxi_musb_disable(struct musb *musb)
--
2.4.3