Support configuring the default role the controller assumes as
host mode when the usb role is USB_ROLE_NONE

This patch was split out from a larger patch originally by
Yu Chen <cheny...@huawei.com>

Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Rob Herring <robh...@kernel.org>
Cc: Mark Rutland <mark.rutl...@arm.com>
CC: ShuFan Lee <shufan_...@richtek.com>
Cc: Heikki Krogerus <heikki.kroge...@linux.intel.com>
Cc: Suzuki K Poulose <suzuki.poul...@arm.com>
Cc: Chunfeng Yun <chunfeng....@mediatek.com>
Cc: Yu Chen <cheny...@huawei.com>
Cc: Felipe Balbi <ba...@kernel.org>
Cc: Hans de Goede <hdego...@redhat.com>
Cc: Andy Shevchenko <andy.shevche...@gmail.com>
Cc: Jun Li <lijun.ker...@gmail.com>
Cc: Valentin Schneider <valentin.schnei...@arm.com>
Cc: Jack Pham <ja...@codeaurora.org>
Cc: linux-...@vger.kernel.org
Cc: devicet...@vger.kernel.org
Signed-off-by: John Stultz <john.stu...@linaro.org>
---
v3: Split this patch out from addition of usb-role-switch
    handling
---
 drivers/usb/dwc3/core.h |  3 +++
 drivers/usb/dwc3/drd.c  | 20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6f19e9891767..3c879c9ab1aa 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -953,6 +953,8 @@ struct dwc3_scratchpad_array {
  *             - USBPHY_INTERFACE_MODE_UTMI
  *             - USBPHY_INTERFACE_MODE_UTMIW
  * @role_sw: usb_role_switch handle
+ * @role_switch_default_mode: default operation mode of controller while
+ *                     usb role is USB_ROLE_NONE.
  * @usb2_phy: pointer to USB2 PHY
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
@@ -1087,6 +1089,7 @@ struct dwc3 {
        struct notifier_block   edev_nb;
        enum usb_phy_interface  hsphy_mode;
        struct usb_role_switch  *role_sw;
+       enum usb_dr_mode        role_switch_default_mode;
 
        u32                     fladj;
        u32                     irq_gadget;
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 61d4fd8aead4..0e3466fe5ac4 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -489,7 +489,10 @@ static int dwc3_usb_role_switch_set(struct device *dev, 
enum usb_role role)
                mode = DWC3_GCTL_PRTCAP_DEVICE;
                break;
        default:
-               mode = DWC3_GCTL_PRTCAP_DEVICE;
+               if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
+                       mode = DWC3_GCTL_PRTCAP_HOST;
+               else
+                       mode = DWC3_GCTL_PRTCAP_DEVICE;
                break;
        }
 
@@ -515,7 +518,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct 
device *dev)
                role = dwc->current_otg_role;
                break;
        default:
-               role = USB_ROLE_DEVICE;
+               if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
+                       role = USB_ROLE_HOST;
+               else
+                       role = USB_ROLE_DEVICE;
                break;
        }
        spin_unlock_irqrestore(&dwc->lock, flags);
@@ -534,8 +540,14 @@ int dwc3_drd_init(struct dwc3 *dwc)
                struct usb_role_switch_desc dwc3_role_switch = {NULL};
                u32 mode;
 
-               mode = DWC3_GCTL_PRTCAP_DEVICE;
-
+               if (device_property_read_bool(dwc->dev,
+                                             "role-switch-default-host")) {
+                       dwc->role_switch_default_mode = USB_DR_MODE_HOST;
+                       mode = DWC3_GCTL_PRTCAP_HOST;
+               } else {
+                       dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
+                       mode = DWC3_GCTL_PRTCAP_DEVICE;
+               }
                dwc3_role_switch.fwnode = dev_fwnode(dwc->dev);
                dwc3_role_switch.set = dwc3_usb_role_switch_set;
                dwc3_role_switch.get = dwc3_usb_role_switch_get;
-- 
2.17.1

Reply via email to