Received: by 2002:ac0:aed5:0:0:0:0:0 with SMTP id t21csp1048479imb; Sat, 2 Mar 2019 01:07:09 -0800 (PST) X-Google-Smtp-Source: APXvYqwv54Y5k90CFkJAB10h7We2sN0IIg/50jk15tO81KWQzv4C72nlF43IOWroCQVf/3+6jkgw X-Received: by 2002:a17:902:a50a:: with SMTP id s10mr9668486plq.223.1551517629533; Sat, 02 Mar 2019 01:07:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551517629; cv=none; d=google.com; s=arc-20160816; b=peNSt3zapraoSYYK9vVekpcoNViuLGtJhnpVU1oV44GtP5MtabUo/Qo0BZT9ZJgH/6 /0E6JFrsTGIdCWbiFHwici+p0LUPo/RlFkUzja7pg0GSCCzoSta+0HrszQg56ZktAQXC 7Squomu29yCe+k9UfRNlwls72uAzH9uv96JE0+de4VSXNQV49zaIyjeXmvhL6xSCwvGC jkUp9ABgQSNPWxn7yKXzkM9Nh3v+povwpWXsfYIm0teczn5VI6fovmk2z/s4AH7UTGYJ uLS1fmfwZUUrPrEwpr1oCthYzcz281+dA7Q11UuWobxZ1Xu16obng2AvYC4/GVG9WvkI 77xg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=+B+TDgg5l2u8pN2dFqsvcTq28r650SeC8gU4upOIHmU=; b=jdSfVWncbV34Gy/cvKYeKkdUA6mFwChEGNtkD5IhW29L8Qs0bPfioSOr5Inq2ssWN4 AUGc8NIJeCcoEVqbPp0r4eV7Dlvog2TafgQAahFEO035UotiQC5XQ7Z4nNTewk7tmLah BBdU/ulcw/bOvl0mlBcQ6QsioKZG/16j5aQy6L2SMxKWZ3uZeIrw1nZ0mXY2/qQ01Eyb SsMgGT8QUVIPbThooRqkMWflwqmDVvMgLHR4wuY+NPdXg5wB09jkj2+kiNUtyBiwVBKF c5gDi2DG3hO8rB3NWxqbjMmojUuEZ9nkIZVzMipj2+6sdh+RiCMDbr97FRoZwKjFb3ZV ykbA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h2si295718pgp.60.2019.03.02.01.06.54; Sat, 02 Mar 2019 01:07:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728161AbfCBJGI (ORCPT + 99 others); Sat, 2 Mar 2019 04:06:08 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:4761 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727946AbfCBJFp (ORCPT ); Sat, 2 Mar 2019 04:05:45 -0500 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id E2D32EB6104448847B9C; Sat, 2 Mar 2019 17:05:40 +0800 (CST) Received: from vm100-107-113-134.huawei.com (100.107.113.134) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.408.0; Sat, 2 Mar 2019 17:05:30 +0800 From: Yu Chen To: , , CC: , , , , , , , , , , , , , , Yu Chen , Jun Li , Valentin Schneider , Felipe Balbi , Greg Kroah-Hartman , Heikki Krogerus Subject: [PATCH v3 09/12] usb: dwc3: Registering a role switch in the DRD code. Date: Sat, 2 Mar 2019 17:05:02 +0800 Message-ID: <20190302090505.65542-10-chenyu56@huawei.com> X-Mailer: git-send-email 2.15.0-rc2 In-Reply-To: <20190302090505.65542-1-chenyu56@huawei.com> References: <20190302090505.65542-1-chenyu56@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [100.107.113.134] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Type-C drivers use USB role switch API to inform the system about the negotiated data role, so registering a role switch in the DRD code in order to support platforms with USB Type-C connectors. Cc: Jun Li Cc: Valentin Schneider Cc: John Stultz Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: Heikki Krogerus Suggested-by: Heikki Krogerus Signed-off-by: Yu Chen --- v2: * Assign fwnode in dwc3_role_switch. v3: * Add default mode property for usb role switch. * Add select USB_ROLE_SWITCH for USB_DWC3_DUAL_ROLE in Kconfig. * Do usb_role_switch_register only if property "usb-role-switch" present. --- --- drivers/usb/dwc3/Kconfig | 1 + drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/drd.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 1a0404fda596..3a0cb9f1f38a 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -42,6 +42,7 @@ config USB_DWC3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3)) depends on (EXTCON=y || EXTCON=USB_DWC3) + select USB_ROLE_SWITCH help This is the default mode of working of DWC3 controller where both host and gadget features are enabled. diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 402b3c29eb26..b2b0da007bff 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -1083,6 +1084,8 @@ struct dwc3 { struct extcon_dev *edev; 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 869725d15c74..5bfea03233d7 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -474,6 +474,43 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) return edev; } +static int dwc3_usb_role_switch_set(struct device *dev, enum usb_role role) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + u32 mode; + + switch (role) { + case USB_ROLE_HOST: + mode = DWC3_GCTL_PRTCAP_HOST; + break; + case USB_ROLE_DEVICE: + mode = DWC3_GCTL_PRTCAP_DEVICE; + break; + default: + if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) + mode = DWC3_GCTL_PRTCAP_HOST; + else + mode = DWC3_GCTL_PRTCAP_DEVICE; + break; + } + + dwc3_set_mode(dwc, mode); + return 0; +} + +static enum usb_role dwc3_usb_role_switch_get(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + unsigned long flags; + enum usb_role role; + + spin_lock_irqsave(&dwc->lock, flags); + role = dwc->current_otg_role; + spin_unlock_irqrestore(&dwc->lock, flags); + + return role; +} + int dwc3_drd_init(struct dwc3 *dwc) { int ret, irq; @@ -482,7 +519,23 @@ int dwc3_drd_init(struct dwc3 *dwc) if (IS_ERR(dwc->edev)) return PTR_ERR(dwc->edev); - if (dwc->edev) { + if (device_property_read_bool(dwc->dev, "usb-role-switch")) { + struct usb_role_switch_desc dwc3_role_switch = {0}; + + if (device_property_read_bool(dwc->dev, + "role-switch-default-host")) + dwc->role_switch_default_mode = USB_DR_MODE_HOST; + else + dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL; + + 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; + dwc->role_sw = usb_role_switch_register(dwc->dev, + &dwc3_role_switch); + if (IS_ERR(dwc->role_sw)) + return PTR_ERR(dwc->role_sw); + } else if (dwc->edev) { dwc->edev_nb.notifier_call = dwc3_drd_notifier; ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST, &dwc->edev_nb); @@ -529,6 +582,9 @@ void dwc3_drd_exit(struct dwc3 *dwc) { unsigned long flags; + if (dwc->role_sw) + usb_role_switch_unregister(dwc->role_sw); + if (dwc->edev) extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST, &dwc->edev_nb); -- 2.15.0-rc2