*/
 extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg);
 
+/* Gadget defines */
+#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
+extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg);
+extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2);
+extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2);
+extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
+#else
+static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2)
+{ return 0; }
+static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2)
+{ return 0; }
+static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2)
+{ return 0; }
+static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
+{ return 0; }
+#endif
+
+#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
+extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
+extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg);
+extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
+#else
+static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {}
+static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
+{ return 0; }
+static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
+static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
+                               const struct dwc2_core_params *params)
+{ return 0; }
+#endif
+
 #endif /* __DWC2_CORE_H__ */
 
 }
 
 /**
- * s3c_hsotg_probe - probe function for hsotg driver
- * @pdev: The platform information for the driver
+ * dwc2_gadget_init - init function for gadget
+ * @dwc2: The data structure for the DWC2 driver.
+ * @irq: The IRQ number for the controller.
  */
-static int s3c_hsotg_probe(struct platform_device *pdev)
+int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 {
-       struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev);
+       struct device *dev = hsotg->dev;
+       struct s3c_hsotg_plat *plat = dev->platform_data;
        struct phy *phy;
        struct usb_phy *uphy;
-       struct device *dev = &pdev->dev;
        struct s3c_hsotg_ep *eps;
-       struct dwc2_hsotg *hsotg;
-       struct resource *res;
        int epnum;
        int ret;
        int i;
 
-       hsotg = devm_kzalloc(&pdev->dev, sizeof(struct dwc2_hsotg), GFP_KERNEL);
-       if (!hsotg)
-               return -ENOMEM;
-
        /* Set default UTMI width */
        hsotg->phyif = GUSBCFG_PHYIF16;
 
         * Attempt to find a generic PHY, then look for an old style
         * USB PHY, finally fall back to pdata
         */
-       phy = devm_phy_get(&pdev->dev, "usb2-phy");
+       phy = devm_phy_get(dev, "usb2-phy");
        if (IS_ERR(phy)) {
                uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
                if (IS_ERR(uphy)) {
                        /* Fallback for pdata */
-                       plat = dev_get_platdata(&pdev->dev);
+                       plat = dev_get_platdata(dev);
                        if (!plat) {
-                               dev_err(&pdev->dev,
+                               dev_err(dev,
                                "no platform data or transceiver defined\n");
                                return -EPROBE_DEFER;
                        }
                        hsotg->phyif = GUSBCFG_PHYIF8;
        }
 
-       hsotg->dev = dev;
-
-       hsotg->clk = devm_clk_get(&pdev->dev, "otg");
+       hsotg->clk = devm_clk_get(dev, "otg");
        if (IS_ERR(hsotg->clk)) {
                dev_err(dev, "cannot get otg clock\n");
                return PTR_ERR(hsotg->clk);
        }
 
-       platform_set_drvdata(pdev, hsotg);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       hsotg->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(hsotg->regs)) {
-               ret = PTR_ERR(hsotg->regs);
-               goto err_clk;
-       }
-
-       ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               dev_err(dev, "cannot find IRQ\n");
-               goto err_clk;
-       }
-
-       spin_lock_init(&hsotg->lock);
-
-       hsotg->irq = ret;
-
-       dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq);
-
        hsotg->gadget.max_speed = USB_SPEED_HIGH;
        hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
        hsotg->gadget.name = dev_name(dev);
        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
                                 hsotg->supplies);
        if (ret) {
-               dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
+               dev_err(dev, "failed to request supplies: %d\n", ret);
                goto err_clk;
        }
 
        s3c_hsotg_hw_cfg(hsotg);
        s3c_hsotg_init(hsotg);
 
-       ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0,
+       ret = devm_request_irq(dev, irq, s3c_hsotg_irq, 0,
                                dev_name(dev), hsotg);
        if (ret < 0) {
                s3c_hsotg_phy_disable(hsotg);
        ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
                                    hsotg->supplies);
        if (ret) {
-               dev_err(&pdev->dev, "failed to disable supplies: %d\n", ret);
+               dev_err(dev, "failed to disable supplies: %d\n", ret);
                goto err_ep_mem;
        }
 
-       ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
+       ret = usb_add_gadget_udc(dev, &hsotg->gadget);
        if (ret)
                goto err_ep_mem;
 
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(dwc2_gadget_init);
 
 /**
  * s3c_hsotg_remove - remove function for hsotg driver
  * @pdev: The platform information for the driver
  */
-static int s3c_hsotg_remove(struct platform_device *pdev)
+int s3c_hsotg_remove(struct dwc2_hsotg *hsotg)
 {
-       struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev);
-
        usb_del_gadget_udc(&hsotg->gadget);
        s3c_hsotg_delete_debug(hsotg);
        clk_disable_unprepare(hsotg->clk);
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(s3c_hsotg_remove);
 
-static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
+int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
 {
-       struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev);
        unsigned long flags;
        int ret = 0;
 
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(s3c_hsotg_suspend);
 
-static int s3c_hsotg_resume(struct platform_device *pdev)
+int s3c_hsotg_resume(struct dwc2_hsotg *hsotg)
 {
-       struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev);
        unsigned long flags;
        int ret = 0;
 
 
        return ret;
 }
-
-#ifdef CONFIG_OF
-static const struct of_device_id s3c_hsotg_of_ids[] = {
-       { .compatible = "samsung,s3c6400-hsotg", },
-       { .compatible = "snps,dwc2", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids);
-#endif
-
-static struct platform_driver s3c_hsotg_driver = {
-       .driver         = {
-               .name   = "s3c-hsotg",
-               .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(s3c_hsotg_of_ids),
-       },
-       .probe          = s3c_hsotg_probe,
-       .remove         = s3c_hsotg_remove,
-       .suspend        = s3c_hsotg_suspend,
-       .resume         = s3c_hsotg_resume,
-};
-
-module_platform_driver(s3c_hsotg_driver);
-
-MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c-hsotg");
+EXPORT_SYMBOL_GPL(s3c_hsotg_resume);
 
        struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
 
        dwc2_hcd_remove(hsotg);
+       s3c_hsotg_remove(hsotg);
 
        return 0;
 }
        { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 },
        { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 },
        { .compatible = "snps,dwc2", .data = NULL },
+       { .compatible = "samsung,s3c6400-hsotg", .data = NULL},
        {},
 };
 MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
 
        hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node);
 
+       spin_lock_init(&hsotg->lock);
+       retval = dwc2_gadget_init(hsotg, irq);
+       if (retval)
+               return retval;
        retval = dwc2_hcd_init(hsotg, irq, params);
        if (retval)
                return retval;
        return retval;
 }
 
+static int dwc2_suspend(struct platform_device *dev, pm_message_t state)
+{
+       struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev);
+       int ret = 0;
+
+       if (dwc2_is_device_mode(dwc2))
+               ret = s3c_hsotg_suspend(dwc2);
+       return ret;
+}
+
+static int dwc2_resume(struct platform_device *dev)
+{
+       struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev);
+       int ret = 0;
+
+       if (dwc2_is_device_mode(dwc2))
+               ret = s3c_hsotg_resume(dwc2);
+       return ret;
+}
+
 static struct platform_driver dwc2_platform_driver = {
        .driver = {
                .name = dwc2_driver_name,
        },
        .probe = dwc2_driver_probe,
        .remove = dwc2_driver_remove,
+       .suspend = dwc2_suspend,
+       .resume = dwc2_resume,
 };
 
 module_platform_driver(dwc2_platform_driver);