musb: Allow musb_platform_enable to return an error code
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> Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
fd1bd21bf0
commit
1583723638
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue