On 06/13/2017 02:10 PM, Vignesh R wrote: > From: Mugunthan V N <mugunthan...@ti.com> > > Add a TI DWC3 peripheral driver with driver model support and the > driver will be bound by the DWC3 wrapper driver based on the > dr_mode device tree entry. > > Signed-off-by: Mugunthan V N <mugunthan...@ti.com> > Signed-off-by: Vignesh R <vigne...@ti.com> > --- > drivers/usb/dwc3/core.c | 57 +++++++++++++++ > drivers/usb/dwc3/core.h | 6 ++ > drivers/usb/dwc3/dwc3-omap.c | 167 > +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 230 insertions(+) > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index 98102bd6b00a..a895f8fbddd3 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -603,6 +603,8 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) > > #define DWC3_ALIGN_MASK (16 - 1) > > +#ifndef CONFIG_DM_USB > + > /** > * dwc3_uboot_init - dwc3 core uboot initialization code > * @dwc3_dev: struct dwc3_device containing initialization data > @@ -789,3 +791,58 @@ MODULE_ALIAS("platform:dwc3"); > MODULE_AUTHOR("Felipe Balbi <ba...@ti.com>"); > MODULE_LICENSE("GPL v2"); > MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver"); > + > +#else > + > +int dwc3_init(struct dwc3 *dwc) > +{ > + int ret; > + > + dwc3_cache_hwparams(dwc); > + > + ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); > + if (ret) { > + dev_err(dwc->dev, "failed to allocate event buffers\n"); > + return -ENOMEM; > + } > + > + ret = dwc3_core_init(dwc); > + if (ret) { > + dev_err(dev, "failed to initialize core\n"); > + goto err0; > + } > + > + ret = dwc3_event_buffers_setup(dwc); > + if (ret) { > + dev_err(dwc->dev, "failed to setup event buffers\n"); > + goto err1; > + } > + > + ret = dwc3_core_init_mode(dwc); > + if (ret) > + goto err2; > + > + return 0; > + > +err2:
Use more descriptive label names please ... > + dwc3_event_buffers_cleanup(dwc); > + > +err1: > + dwc3_core_exit(dwc); > + > +err0: > + dwc3_free_event_buffers(dwc); > + > + return ret; > +} > + > +void dwc3_remove(struct dwc3 *dwc) > +{ > + dwc3_core_exit_mode(dwc); > + dwc3_event_buffers_cleanup(dwc); > + dwc3_free_event_buffers(dwc); > + dwc3_core_exit(dwc); > + kfree(dwc->mem); > +} > + > +#endif > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h > index 72d2fcdd3f42..972628751697 100644 > --- a/drivers/usb/dwc3/core.h > +++ b/drivers/usb/dwc3/core.h > @@ -713,7 +713,11 @@ struct dwc3 { > /* device lock */ > spinlock_t lock; > > +#ifndef CONFIG_DM_USB > struct device *dev; > +#else > + struct udevice *dev; > +#endif > > struct platform_device *xhci; > struct resource xhci_resources[DWC3_XHCI_RESOURCES_NUM]; > @@ -988,6 +992,8 @@ struct dwc3_gadget_ep_cmd_params { > > /* prototypes */ > int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); > +int dwc3_init(struct dwc3 *dwc); > +void dwc3_remove(struct dwc3 *dwc); > > #ifdef CONFIG_USB_DWC3_HOST > int dwc3_host_init(struct dwc3 *dwc); > diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c > index f18884f13392..b4dde726c6f3 100644 > --- a/drivers/usb/dwc3/dwc3-omap.c > +++ b/drivers/usb/dwc3/dwc3-omap.c > @@ -27,6 +27,23 @@ > #include <dwc3-uboot.h> > > #include "linux-compat.h" > +#include <linux/usb/ch9.h> > +#include <linux/usb/gadget.h> > +#include <ti-usb-phy-uboot.h> > +#include <usb.h> > + > +#include "core.h" > + > +#include <libfdt.h> > +#include <dm/device.h> > +#include <dm/uclass.h> > +#include <dm/lists.h> > +#include <dwc3-uboot.h> > + > +#include <asm/omap_common.h> > +#include "gadget.h" > + > +DECLARE_GLOBAL_DATA_PTR; > > /* > * All these registers belong to OMAP's Wrapper around the > @@ -135,6 +152,12 @@ struct dwc3_omap { > u32 index; > }; > > +struct omap_dwc3_priv { > + struct dwc3_omap omap; > + struct dwc3 dwc3; > + struct ti_usb_phy_device phy_device; > +}; > + > static LIST_HEAD(dwc3_omap_list); > > static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) > @@ -362,6 +385,8 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap > *omap, int utmi_mode) > dwc3_omap_write_utmi_status(omap, reg); > } > > +#ifndef CONFIG_DM_USB > + > /** > * dwc3_omap_uboot_init - dwc3 omap uboot initialization code > * @dev: struct dwc3_omap_device containing initialization data > @@ -462,3 +487,145 @@ MODULE_ALIAS("platform:omap-dwc3"); > MODULE_AUTHOR("Felipe Balbi <ba...@ti.com>"); > MODULE_LICENSE("GPL v2"); > MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer"); > + > +#else > + > +int usb_gadget_handle_interrupts(int index) Can this be made somehow more generic , so that the core code would contain the basic interrupt handling and probe routines and the various SoC-specific drivers would add their specific bits to it ? > +{ > + struct omap_dwc3_priv *priv; > + struct dwc3_omap *omap; > + struct dwc3 *dwc; > + struct udevice *dev; > + u32 status; > + int ret; > + > + ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); > + if (!dev || ret) { > + error("No USB device found\n"); > + return -ENODEV; > + } > + > + priv = dev_get_priv(dev); > + omap = &priv->omap; > + dwc = &priv->dwc3; > + > + status = dwc3_omap_interrupt(-1, omap); > + if (status) > + dwc3_gadget_uboot_handle_interrupt(dwc); > + > + return 0; > +} > + > +static int dwc3_omap_peripheral_probe(struct udevice *dev) > +{ > + struct omap_dwc3_priv *priv = dev_get_priv(dev); > + struct dwc3_omap *omap = &priv->omap; > + struct dwc3 *dwc = &priv->dwc3; > + u32 reg; > + int ret; > + > + enable_usb_clocks(0); > + > + /* Initialize usb phy */ > + ret = ti_usb_phy_uboot_init(&priv->phy_device); > + if (ret) > + return ret; > + > + dwc3_omap_map_offset(omap); > + dwc3_omap_set_utmi_mode(omap, DWC3_OMAP_UTMI_MODE_SW); > + > + /* check the DMA Status */ > + reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); > + omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); > + > + dwc3_omap_enable_irqs(omap); > + > + dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); > + > + /* default to highest possible threshold */ > + dwc->lpm_nyet_threshold = 0xff; > + /* > + * default to assert utmi_sleep_n and use maximum allowed HIRD > + * threshold value of 0b1100 > + */ > + dwc->hird_threshold = 12; > + /* default to -3.5dB de-emphasis */ > + dwc->tx_de_emphasis = 1; > + > + dwc->needs_fifo_resize = false; > + dwc->index = 0; > + > + return dwc3_init(dwc); > +} > + > +static int dwc3_omap_peripheral_remove(struct udevice *dev) > +{ > + struct omap_dwc3_priv *priv = dev_get_priv(dev); > + struct dwc3_omap *omap = &priv->omap; > + struct dwc3 *dwc = &priv->dwc3; > + > + dwc3_omap_disable_irqs(omap); > + dwc3_remove(dwc); > + > + return 0; > +} > + > +static int dwc3_omap_ofdata_to_platdata(struct udevice *dev) > +{ > + struct omap_dwc3_priv *priv = dev_get_priv(dev); > + const void *fdt = gd->fdt_blob; > + int node = dev_of_offset(dev); > + int ctrlmodnode; > + int physnode; > + > + priv->omap.base = map_physmem(fdtdec_get_addr(fdt, > + dev_of_offset(dev->parent), "reg"), 0, > + MAP_NOCACHE); > + > + priv->dwc3.regs = devfdt_map_physmem(dev, > + sizeof(priv->dwc3.regs_size)); > + priv->dwc3.regs += DWC3_GLOBALS_REGS_START; > + > + physnode = fdtdec_lookup_phandle(fdt, node, "phys"); > + ctrlmodnode = fdtdec_lookup_phandle(fdt, physnode, "ctrl-module"); > + priv->phy_device.usb2_phy_power = > + map_physmem(fdtdec_get_addr(fdt, ctrlmodnode, "reg"), > + 0, MAP_NOCACHE); > + priv->phy_device.index = 0; > + > + priv->dwc3.maximum_speed = usb_get_maximum_speed(node); > + if (priv->dwc3.maximum_speed < 0) { > + error("Invalid usb maximum speed\n"); > + return priv->dwc3.maximum_speed; > + } > + > + return 0; > +} > + > +static int dwc3_omap_peripheral_ofdata_to_platdata(struct udevice *dev) > +{ > + struct omap_dwc3_priv *priv = dev_get_priv(dev); > + int ret; > + > + ret = dwc3_omap_ofdata_to_platdata(dev); > + if (ret) { > + error("platform dt parse error\n"); > + return ret; > + } > + > + priv->dwc3.dr_mode = USB_DR_MODE_PERIPHERAL; > + > + return 0; > +} > + > +U_BOOT_DRIVER(dwc3_omap_peripheral) = { > + .name = "dwc3-omap-peripheral", > + .id = UCLASS_USB_DEV_GENERIC, > + .ofdata_to_platdata = dwc3_omap_peripheral_ofdata_to_platdata, > + .probe = dwc3_omap_peripheral_probe, > + .remove = dwc3_omap_peripheral_remove, > + .platdata_auto_alloc_size = sizeof(struct usb_platdata), > + .priv_auto_alloc_size = sizeof(struct omap_dwc3_priv), > + .flags = DM_FLAG_ALLOC_PRIV_DMA, > +}; > +#endif /* CONFIG_DM_USB */ > -- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot