*
* This file is part of the Inventra Controller Driver for Linux.
*
- * The Inventra Controller Driver for Linux is free software; you
- * can redistribute it and/or modify it under the terms of the GNU
- * General Public License version 2 as published by the Free Software
- * Foundation.
- *
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/arch/cpu.h>
writel(reg_value, SUNXI_SRAMC_BASE + 0x04);
}
+/******************************************************************************
+ * Needed for the DFU polling magic
+ ******************************************************************************/
+
+static u8 last_int_usb;
+
+bool dfu_usb_get_reset(void)
+{
+ return !!(last_int_usb & MUSB_INTR_RESET);
+}
+
/******************************************************************************
* MUSB Glue code
******************************************************************************/
/* read and flush interrupts */
musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+ last_int_usb = musb->int_usb;
if (musb->int_usb)
musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
pr_debug("%s():\n", __func__);
+ musb_ep_select(musb->mregs, 0);
+ musb_writeb(musb->mregs, MUSB_FADDR, 0);
+
if (enabled)
return 0;
};
#ifdef CONFIG_USB_MUSB_HOST
-int musb_usb_probe(struct udevice *dev)
+static int musb_usb_remove(struct udevice *dev);
+
+static int musb_usb_probe(struct udevice *dev)
{
struct musb_host_data *host = dev_get_priv(dev);
struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
priv->desc_before_addr = true;
- if (!host->host) {
- host->host = musb_init_controller(&musb_plat, NULL,
- (void *)SUNXI_USB0_BASE);
- if (!host->host)
- return -EIO;
- }
+ host->host = musb_init_controller(&musb_plat, NULL,
+ (void *)SUNXI_USB0_BASE);
+ if (!host->host)
+ return -EIO;
ret = musb_lowlevel_init(host);
if (ret == 0)
printf("MUSB OTG\n");
+ else
+ musb_usb_remove(dev);
return ret;
}
-int musb_usb_remove(struct udevice *dev)
+static int musb_usb_remove(struct udevice *dev)
{
struct musb_host_data *host = dev_get_priv(dev);
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
musb_stop(host->host);
+ sunxi_usb_phy_exit(0);
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
+#endif
+ clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
+
+ free(host->host);
+ host->host = NULL;
+
return 0;
}