usb: dwc2: Move gadget probe function into platform code
authorDinh Nguyen <dinguyen@opensource.altera.com>
Tue, 11 Nov 2014 17:13:34 +0000 (11:13 -0600)
committerFelipe Balbi <balbi@ti.com>
Fri, 14 Nov 2014 20:59:32 +0000 (14:59 -0600)
This patch will aggregate the probing of gadget/hcd driver into platform.c.
The gadget probe funtion is converted into gadget_init that is now only
responsible for gadget only initialization. All the gadget resources are now
handled by platform.c

Since the host workqueue will not get initialized if the driver is configured
for peripheral mode only. Thus we need to check for wq_otg before calling
queue_work().

Also, we move spin_lock_init to common location for both host and gadget that
is either in platform.c or pci.c.

We also move suspend/resume code to common platform code.

Lastly, move the "samsung,s3c6400-hsotg" binding into dwc2_of_match_table.

Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Acked-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/core_intr.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/hcd.c
drivers/usb/dwc2/hcd.h
drivers/usb/dwc2/pci.c
drivers/usb/dwc2/platform.c

index 7bcdc10e4b01bdc8228ef3e13ba3d06579eeaaaa..4905d8880869b49b4652c0007ed921df441a1cf5 100644 (file)
@@ -960,4 +960,37 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg);
  */
 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__ */
index c93918b70d032e88654f8db40873e98b03112da7..b176c2fc34e5c51cb3a2badbec194ccb31a6b6b1 100644 (file)
@@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
         * Release lock before scheduling workq as it holds spinlock during
         * scheduling.
         */
-       spin_unlock(&hsotg->lock);
-       queue_work(hsotg->wq_otg, &hsotg->wf_otg);
-       spin_lock(&hsotg->lock);
+       if (hsotg->wq_otg) {
+               spin_unlock(&hsotg->lock);
+               queue_work(hsotg->wq_otg, &hsotg->wf_otg);
+               spin_lock(&hsotg->lock);
+       }
 
        /* Clear interrupt */
        writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
index 5a24e95ae1b0ae434d2d6a49730c294e32eee48e..9caea513eb0c53d87b81960baaff6baf05a224d5 100644 (file)
@@ -3423,26 +3423,21 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * 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;
 
@@ -3450,14 +3445,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
         * 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;
                        }
@@ -3474,36 +3469,12 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
                        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);
@@ -3520,7 +3491,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
        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;
        }
 
@@ -3539,7 +3510,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
        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);
@@ -3592,11 +3563,11 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
        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;
 
@@ -3615,25 +3586,24 @@ err_clk:
 
        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;
 
@@ -3661,10 +3631,10 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
 
        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;
 
@@ -3686,31 +3656,4 @@ static int s3c_hsotg_resume(struct platform_device *pdev)
 
        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);
index 74800786a169fd9b5e4340925475e63c3147b9f3..e377f58f5f4dc2342eaf0513cf1a3874303e0045 100644 (file)
@@ -2905,7 +2905,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
 
        hcd->has_tt = 1;
 
-       spin_lock_init(&hsotg->lock);
        ((struct wrapper_priv_data *) &hcd->hcd_priv)->hsotg = hsotg;
        hsotg->priv = hcd;
 
index a12bb1538666bdb78b5d1ae184df73e92d952e63..e69a843d89287015c6352bdf47689e38196b9aed 100644 (file)
@@ -668,9 +668,6 @@ extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
  */
 extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
 
-extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
-extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg);
-
 /**
  * dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host,
  * and 0 otherwise
@@ -679,13 +676,6 @@ extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg);
  */
 extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
 
-/**
- * dwc2_hcd_get_frame_number() - Returns current frame number
- *
- * @hsotg: The DWC2 HCD
- */
-extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
-
 /**
  * dwc2_hcd_dump_state() - Dumps hsotg state
  *
index c291fca5d21fc048a089ec002104ccf11619cded..6d33ecf2e295549583ad8a12043126167b09ff97 100644 (file)
@@ -141,6 +141,7 @@ static int dwc2_driver_probe(struct pci_dev *dev,
 
        pci_set_master(dev);
 
+       spin_lock_init(&hsotg->lock);
        retval = dwc2_hcd_init(hsotg, dev->irq, &dwc2_module_params);
        if (retval) {
                pci_disable_device(dev);
index 121dbdafc06b7f0f189d0d438387eb256482daf3..eeba8a44f799d900b66d6bb0752551db174fa774 100644 (file)
@@ -121,6 +121,7 @@ static int dwc2_driver_remove(struct platform_device *dev)
        struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
 
        dwc2_hcd_remove(hsotg);
+       s3c_hsotg_remove(hsotg);
 
        return 0;
 }
@@ -129,6 +130,7 @@ static const struct of_device_id dwc2_of_match_table[] = {
        { .compatible = "brcm,bcm2835-usb", .data = &params_bcm2835 },
        { .compatible = "rockchip,rk3066-usb", .data = &params_rk3066 },
        { .compatible = "snps,dwc2", .data = NULL },
+       { .compatible = "samsung,s3c6400-hsotg", .data = NULL},
        {},
 };
 MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
@@ -204,6 +206,10 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
        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;
@@ -213,6 +219,26 @@ static int dwc2_driver_probe(struct platform_device *dev)
        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,
@@ -220,6 +246,8 @@ static struct platform_driver dwc2_platform_driver = {
        },
        .probe = dwc2_driver_probe,
        .remove = dwc2_driver_remove,
+       .suspend = dwc2_suspend,
+       .resume = dwc2_resume,
 };
 
 module_platform_driver(dwc2_platform_driver);