usb: xhci: fsl: Add code to use CONFIG_DM_USB

Adds code to use driver model for USB XHCI FSL driver

Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c
index c12a189..bdcd4f1 100644
--- a/drivers/usb/host/xhci-fsl.c
+++ b/drivers/usb/host/xhci-fsl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2015,2016 Freescale Semiconductor, Inc.
  *
  * FSL USB HOST xHCI Controller
  *
@@ -17,12 +17,21 @@
 #include "xhci.h"
 #include <fsl_errata.h>
 #include <fsl_usb.h>
+#include <dm.h>
 
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_DM_USB
 static struct fsl_xhci fsl_xhci;
 unsigned long ctr_addr[] = FSL_USB_XHCI_ADDR;
+#else
+struct xhci_fsl_priv {
+	struct xhci_ctrl xhci;
+	fdt_addr_t hcd_base;
+	struct fsl_xhci ctx;
+};
+#endif
 
 __weak int __board_usb_init(int index, enum usb_init_type init)
 {
@@ -77,6 +86,77 @@
 	return 0;
 }
 
+#ifdef CONFIG_DM_USB
+static int xhci_fsl_probe(struct udevice *dev)
+{
+	struct xhci_fsl_priv *priv = dev_get_priv(dev);
+	struct xhci_hccr *hccr;
+	struct xhci_hcor *hcor;
+
+	int ret = 0;
+
+	/*
+	 * Get the base address for XHCI controller from the device node
+	 */
+	priv->hcd_base = dev_get_addr(dev);
+	if (priv->hcd_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the XHCI register base address\n");
+		return -ENXIO;
+	}
+	priv->ctx.hcd = (struct xhci_hccr *)priv->hcd_base;
+	priv->ctx.dwc3_reg = (struct dwc3 *)((char *)(priv->hcd_base) +
+			  DWC3_REG_OFFSET);
+
+	fsl_apply_xhci_errata();
+
+	ret = fsl_xhci_core_init(&priv->ctx);
+	if (ret < 0) {
+		puts("Failed to initialize xhci\n");
+		return ret;
+	}
+
+	hccr = (struct xhci_hccr *)(priv->ctx.hcd);
+	hcor = (struct xhci_hcor *)((uintptr_t) hccr
+				+ HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
+
+	debug("xhci-fsl: init hccr %lx and hcor %lx hc_length %lx\n",
+	      (uintptr_t)hccr, (uintptr_t)hcor,
+	      (uintptr_t)HC_LENGTH(xhci_readl(&hccr->cr_capbase)));
+
+	return xhci_register(dev, hccr, hcor);
+}
+
+static int xhci_fsl_remove(struct udevice *dev)
+{
+	struct xhci_fsl_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	fsl_xhci_core_exit(&priv->ctx);
+
+	ret = xhci_deregister(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct udevice_id xhci_usb_ids[] = {
+	{ .compatible = "fsl,layerscape-dwc3", },
+	{ }
+};
+
+U_BOOT_DRIVER(xhci_fsl) = {
+	.name	= "xhci_fsl",
+	.id	= UCLASS_USB,
+	.of_match = xhci_usb_ids,
+	.probe = xhci_fsl_probe,
+	.remove = xhci_fsl_remove,
+	.ops	= &xhci_usb_ops,
+	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
+	.priv_auto_alloc_size = sizeof(struct xhci_fsl_priv),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+#else
 int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
 {
 	struct fsl_xhci *ctx = &fsl_xhci;
@@ -116,3 +196,4 @@
 
 	fsl_xhci_core_exit(ctx);
 }
+#endif