From: Dinh Nguyen <dingu...@altera.com>

Similar to the DWC3 dual-role driver config, the default mode for the
dwc2/s3c-hsotg driver is a dual-role driver.

When the driver is built as a module the dwc2.ko and dwc2_platform.ko are
the two ko's that should be insmod for all operation modes of the driver.

Signed-off-by: Dinh Nguyen <dingu...@altera.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Paul Zimmerman <pa...@synopsys.com>
Cc: Felipe Balbi <ba...@ti.com>
Cc: Ben Dooks <ben-li...@fluff.org>
Cc: Matt Porter <mpor...@linaro.org>
Cc: Kukjin Kim <kgene....@samsung.com>
Cc: Stephen Warren <swar...@wwwdotorg.org>
Cc: Matthijs Kooijman <matth...@stdin.nl>
Cc: Jingoo Han <jg1....@samsung.com>
Cc: Sachin Kamat <sachin.ka...@linaro.org>
Cc: Robert Baldyga <r.bald...@samsung.com>
---
 drivers/usb/dwc2/Kconfig     |   43 +++++++++++++++++++++++++++---------------
 drivers/usb/dwc2/Makefile    |   13 +++++--------
 drivers/usb/dwc2/core.c      |    1 +
 drivers/usb/dwc2/core.h      |    2 +-
 drivers/usb/dwc2/hcd.c       |    7 +------
 drivers/usb/dwc2/platform.c  |   30 ++++++++++++++++++++++++-----
 drivers/usb/dwc2/s3c-hsotg.c |   18 ++++++++----------
 7 files changed, 69 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig
index ce14859..8c0df5d 100644
--- a/drivers/usb/dwc2/Kconfig
+++ b/drivers/usb/dwc2/Kconfig
@@ -20,21 +20,6 @@ config USB_DWC2
 
 if USB_DWC2
 
-config USB_DWC2_HOST
-       bool "Host only mode"
-       depends on USB=y || USB=USB_DWC2
-       default y
-       help
-         Select this when you want to use DWC2 in host mode only,
-         thereby the gadget feature will be regressed.
-
-config USB_S3C_HSOTG
-       depends on (ARM || USB_GADGET=y) && !USB_DWC2_HOST
-       tristate "Designware/S3C HS/OtG USB Device controller"
-       help
-         The Designware USB2.0 high-speed gadget controller
-         integrated into many SoCs.
-
 config USB_DWC2_DEBUG
        bool "Enable Debugging Messages"
        help
@@ -66,3 +51,31 @@ config USB_DWC2_DEBUG_PERIODIC
          incomplete. Note that this also disables some debug messages
          for which the transfer type cannot be deduced.
 endif
+
+choice
+       bool "DWC2 Mode Selection"
+       default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET)
+       default USB_DWC2_HOST if (USB && !USB_GADGET)
+       default USB_S3C_HSOTG if (!USB && USB_GADGET)
+
+config USB_DWC2_HOST
+       bool "Host only mode"
+       depends on USB=y || USB=USB_DWC2
+       help
+         Select this when you want to use DWC2 in host mode only,
+         thereby the gadget feature will be regressed.
+
+config USB_S3C_HSOTG
+       depends on ARM || USB_GADGET=y
+       tristate "Designware/S3C HS/OtG USB Device controller"
+       help
+         The Designware USB2.0 high-speed gadget controller
+         integrated into many SoCs.
+
+config USB_DWC2_DUAL_ROLE
+       bool "Dual Role mode"
+       depends on ((USB=y || USB=USB_DWC2) && (USB_GADGET=y))
+       help
+         This is the default mode of working of DWC2 controller where
+         both host and gadget features are enabled.
+endchoice
diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile
index 2cbbabf..eca1bd9 100644
--- a/drivers/usb/dwc2/Makefile
+++ b/drivers/usb/dwc2/Makefile
@@ -2,18 +2,15 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG)      += -DDEBUG
 ccflags-$(CONFIG_USB_DWC2_VERBOSE)     += -DVERBOSE_DEBUG
 
 obj-$(CONFIG_USB_DWC2)                 += dwc2.o
-dwc2-y                                  += core.o core_intr.o
-dwc2-y                                  += hcd.o hcd_intr.o
-dwc2-y                                  += hcd_queue.o hcd_ddma.o
-endif
-obj-$(CONFIG_USB_S3C_HSOTG)             += s3c-hsotg.o
+dwc2-y                                 += core.o core_intr.o
+dwc2-y                                 += hcd.o hcd_intr.o
+dwc2-y                                 += hcd_queue.o hcd_ddma.o
+dwc2-y                                 += s3c-hsotg.o
 
 ifneq ($(CONFIG_PCI),)
        obj-$(CONFIG_USB_DWC2)          += dwc2_pci.o
 endif
-ifneq ($(CONFIG_USB_DWC2_HOST),)
-       obj-$(CONFIG_USB_DWC2)                  += dwc2_platform.o
-endif
+obj-$(CONFIG_USB_DWC2)                 += dwc2_platform.o
 
 dwc2_pci-y                             += pci.o
 dwc2_platform-y                                += platform.o
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 1d12988..12e9465 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -467,6 +467,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool 
select_phy, int irq)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(dwc2_core_init);
 
 /**
  * dwc2_enable_host_interrupts() - Enables the Host mode interrupts
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index dd5c496..9bbbe53 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -737,7 +737,7 @@ extern void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 
*dest, u16 bytes);
 extern void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num);
 extern void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg);
 
-extern int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq);
+int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq);
 extern void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd);
 extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f59484d..2e949ef 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct 
*work)
                hsotg->op_state = OTG_STATE_B_PERIPHERAL;
                dwc2_core_init(hsotg, false, -1);
                dwc2_enable_global_interrupts(hsotg);
+               s3c_hsotg_core_init(hsotg);
        } else {
                /* A-Device connector (Host Mode) */
                dev_dbg(hsotg->dev, "connId A\n");
@@ -2798,11 +2799,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
                goto error1;
        hsotg->last_frame_num = HFNUM_MAX_FRNUM;
 #endif
-
-       hsotg->core_params = kzalloc(sizeof(*hsotg->core_params), GFP_KERNEL);
-       if (!hsotg->core_params)
-               goto error1;
-
        dwc2_set_all_params(hsotg->core_params, -1);
 
        /* Validate parameter values */
@@ -2834,7 +2830,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;
 
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index c6fb4f2..85f706d 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -42,11 +42,12 @@
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/usb/otg.h>
 
 #include "core.h"
 #include "hcd.h"
 
-static const char dwc2_driver_name[] = "dwc2";
+static const char dwc2_driver_name[] = "dwc2/s3c-hsotg";
 
 static const struct dwc2_core_params params_bcm2835 = {
        .otg_cap                        = 0,    /* HNP/SRP capable */
@@ -93,8 +94,13 @@ static int dwc2_driver_remove(struct platform_device *dev)
 
        if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
                dwc2_hcd_remove(hsotg);
-       else /* s3c-hsotg gadget */
+       else if (IS_ENABLED(CONFIG_USB_S3C_HSOTG))
                s3c_hsotg_remove(hsotg);
+       else {/* dual-role */
+               s3c_hsotg_remove(hsotg);
+               dwc2_hcd_remove(hsotg);
+       }
+       clk_disable_unprepare(hsotg->clk);
 
        return 0;
 }
@@ -134,8 +140,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
                params = match->data;
        } else {
                /* Default all params to autodetect */
-               if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
-                       dwc2_set_all_params(&defparams, -1);
+               dwc2_set_all_params(&defparams, -1);
                params = &defparams;
        }
 
@@ -143,6 +148,10 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (!hsotg)
                return -ENOMEM;
 
+       hsotg->core_params = kzalloc(sizeof(*hsotg->core_params), GFP_KERNEL);
+       if (!hsotg->core_params)
+               return -ENOMEM;
+
        hsotg->dev = &dev->dev;
 
        /*
@@ -180,11 +189,22 @@ static int dwc2_driver_probe(struct platform_device *dev)
                retval = dwc2_hcd_init(hsotg, irq, params);
                if (retval)
                        return retval;
-       } else {/* Enable s3c_hsotg gadget driver */
+       } else if (IS_ENABLED(CONFIG_USB_S3C_HSOTG)) {
                retval = dwc2_gadget_init(hsotg, irq);
                if (retval)
                        return retval;
+               retval = dwc2_core_init(hsotg, true, irq);
+               if (retval)
+                       return retval;
+       } else {/* Enable dwc2/3c_hsotg dual-role driver */
+               retval = dwc2_gadget_init(hsotg, irq);
+               if (retval)
+                       return retval;
+               retval = dwc2_hcd_init(hsotg, irq, params);
+               if (retval)
+                       return retval;
        }
+       spin_lock_init(&hsotg->lock);
 
        platform_set_drvdata(dev, hsotg);
 
diff --git a/drivers/usb/dwc2/s3c-hsotg.c b/drivers/usb/dwc2/s3c-hsotg.c
index 6c0aba8..6f5d7e4 100644
--- a/drivers/usb/dwc2/s3c-hsotg.c
+++ b/drivers/usb/dwc2/s3c-hsotg.c
@@ -2097,6 +2097,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *dwc2)
  *
  * Issue a soft reset to the core, and await the core finishing it.
  */
+#if defined(CONFIG_USB_DWC2_DUAL_ROLE) || defined(CONFIG_USB_S3C_HSOTG)
 void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2)
 {
        s3c_hsotg_corereset(dwc2);
@@ -2223,6 +2224,11 @@ void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2)
        /* remove the soft-disconnect and let's go */
        __bic32(dwc2->regs + DCTL, DCTL_SFTDISCON);
 }
+#else
+void s3c_hsotg_core_init(struct dwc2_hsotg *dwc2)
+{
+}
+#endif
 
 /**
  * s3c_hsotg_ep_enable - enable the given endpoint
@@ -3210,15 +3216,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *dwc2, int irq)
        } else
                dwc2->s3c_hsotg->phy = phy;
 
-       spin_lock_init(&dwc2->lock);
-
-       ret = devm_request_irq(dwc2->dev, irq, dwc2_handle_common_intr, 0,
-                       dev_name(dev), dwc2);
-       if (ret < 0) {
-               dev_err(dev, "cannot claim IRQ\n");
-               return ret;
-       }
-
        dwc2->gadget.max_speed = USB_SPEED_HIGH;
        dwc2->gadget.ops = &s3c_hsotg_gadget_ops;
        dwc2->gadget.name = dev_name(dev);
@@ -3328,6 +3325,7 @@ err_supplies:
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(dwc2_gadget_init);
 
 /**
  * s3c_hsotg_remove - remove function for hsotg driver
@@ -3347,8 +3345,8 @@ void s3c_hsotg_remove(struct dwc2_hsotg *dwc2)
        s3c_hsotg_phy_disable(dwc2);
        if (dwc2->s3c_hsotg->phy)
                phy_exit(dwc2->s3c_hsotg->phy);
-       clk_disable_unprepare(dwc2->clk);
 }
+EXPORT_SYMBOL_GPL(s3c_hsotg_remove);
 
 #define s3c_hsotg_suspend NULL
 #define s3c_hsotg_resume NULL
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to