unsigned int num_stream_ctxs,
                struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
 {
-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
        size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
        if (size > MEDIUM_STREAM_ARRAY_SIZE)
                unsigned int num_stream_ctxs, dma_addr_t *dma,
                gfp_t mem_flags)
 {
-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
        size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
        if (size > MEDIUM_STREAM_ARRAY_SIZE)
 static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
 {
        int i;
-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
        int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 {
        int num_sp;
        int i;
-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 
        if (!xhci->scratchpad)
                return;
 
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
-       struct device   *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device   *dev = xhci_to_hcd(xhci)->self.sysdev;
        int size;
        int i, j, num_ports;
 
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
        dma_addr_t      dma;
-       struct device   *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device   *dev = xhci_to_hcd(xhci)->self.sysdev;
        unsigned int    val, val2;
        u64             val_64;
        struct xhci_segment     *seg;
 
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/usb/phy.h>
 {
        const struct of_device_id *match;
        const struct hc_driver  *driver;
+       struct device           *sysdev;
        struct xhci_hcd         *xhci;
        struct resource         *res;
        struct usb_hcd          *hcd;
        if (irq < 0)
                return -ENODEV;
 
+       /*
+        * sysdev must point to a device that is known to the system firmware
+        * or PCI hardware. We handle these three cases here:
+        * 1. xhci_plat comes from firmware
+        * 2. xhci_plat is child of a device from firmware (dwc3-plat)
+        * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
+        */
+       sysdev = &pdev->dev;
+       if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node)
+               sysdev = sysdev->parent;
+#ifdef CONFIG_PCI
+       else if (sysdev->parent && sysdev->parent->parent &&
+                sysdev->parent->parent->bus == &pci_bus_type)
+               sysdev = sysdev->parent->parent;
+#endif
+
        /* Try to set 64-bit DMA first */
-       if (!pdev->dev.dma_mask)
+       if (WARN_ON(!sysdev->dma_mask))
                /* Platform did not initialize dma_mask */
-               ret = dma_coerce_mask_and_coherent(&pdev->dev,
+               ret = dma_coerce_mask_and_coherent(sysdev,
                                                   DMA_BIT_MASK(64));
        else
-               ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+               ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
 
        /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
        if (ret) {
-               ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+               ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
                if (ret)
                        return ret;
        }
 
-       hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+       hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
+                              dev_name(&pdev->dev), NULL);
        if (!hcd)
                return -ENOMEM;
 
 
        xhci->clk = clk;
        xhci->main_hcd = hcd;
-       xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
+       xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
                        dev_name(&pdev->dev), hcd);
        if (!xhci->shared_hcd) {
                ret = -ENOMEM;
                goto disable_clk;
        }
 
-       if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
+       if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
                xhci->quirks |= XHCI_LPM_SUPPORT;
 
        if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
                xhci->quirks |= XHCI_BROKEN_PORT_PED;
 
-       hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+       hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
        if (IS_ERR(hcd->usb_phy)) {
                ret = PTR_ERR(hcd->usb_phy);
                if (ret == -EPROBE_DEFER)
 
 static int xhci_setup_msi(struct xhci_hcd *xhci)
 {
        int ret;
+       /*
+        * TODO:Check with MSI Soc for sysdev
+        */
        struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
 
        ret = pci_enable_msi(pdev);
  */
 static void xhci_free_irq(struct xhci_hcd *xhci)
 {
-       struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+       struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
        int ret;
 
        /* return if using legacy interrupt */
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
        if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
-               usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
+               usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
 
        spin_lock_irq(&xhci->lock);
        xhci_halt(xhci);
 
        /* Yet another workaround for spurious wakeups at shutdown with HSW */
        if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-               pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
+               pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
 
 #ifdef CONFIG_PM
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 {
        struct xhci_hcd         *xhci;
-       struct device           *dev = hcd->self.controller;
+       /*
+        * TODO: Check with DWC3 clients for sysdev according to
+        * quirks
+        */
+       struct device           *dev = hcd->self.sysdev;
        int                     retval;
 
        /* Accept arbitrarily long scatter-gather lists */