mbox series

[v2,0/4] usb: dwc3: Modify role-switching QC drd usb controllers

Message ID 20250610091357.2983085-1-krishna.kurapati@oss.qualcomm.com
Headers show
Series usb: dwc3: Modify role-switching QC drd usb controllers | expand

Message

Krishna Kurapati June 10, 2025, 9:13 a.m. UTC
Currently on QC targets, the conndone/disconnect events in device mode are
generated by controller when software writes to QSCRATCH registers in qcom
glue layer rather than the vbus line being routed to dwc3 core IP for it
to recognize and generate these events. We need to set UTMI_OTG_VBUS_VALID
bit of QSCRATCH_HS_PHY_CTRL register to generate a connection done event
and clear it to generate a disconnect event during cable removal or mode
switch is done

When the disconnect is not generated upon cable removal, the "connected"
flag of dwc3 is left marked as "true" and it blocks suspend routines and
for that to happen upon cable removal, the cable disconnect notification
from usb_role_switch to DWC3 core driver needs to reach DWC3 Qualcomm glue
driver for it generate the event.

Currently, the way DWC3 core and Qualcomm glue driver is designed, there
is no mechanism through which the DWC3 core can notify the Qualcomm glue
layer of any role changes which it receives from usb_role_switch. To
register these glue callbacks at probe time, for enabling core to notify
glue layer, the legacy Qualcomm driver has no way to find out when the
child driver probe was successful since it does not check for the same
during of_platform_populate.

For flattened implementation of the glue driver, register callbacks for
core to invoke and notify glue layer of role switch notifications.

Set-Role and Run_stop notifier callbacks have been added to inform glue
of changes in role and any modifications UDC might be performing on the
controller. These callbacks allow us to modify qscratch accordingly and
generate disconnect/connect events to facilitate suspend entry and proper
enumeration.

The series only allows autosuspend to be used but still relies on user
enabling it from userspace (echo auto > a600000.usb/power/control).

Tests done:
1. Enumeration in device mode:
After creating symlinks to ffs.adb and writing to UDC node, ADB is up and
working in a stable way.

2. When none is written to UDC, device enters suspend.

3. When cable is removed, cable disconnect notification comes and when
qscratch registers are cleared properly, it is generating disconnect event

4. Device enters suspend upon removing cable (host and device mode).

5. In host mode, when autosuspend is enabled from userspace for controller,
xhci, roothubs and connected peripheral, the controller
enters runtime suspend.

6. Upon removing cable in host mode, setmode brings back usb to device
mode (which is default setting), it enters suspend as cable is still
disconnected.

7. When in host mode, if we enter runtime suspend with wakeup enabled,
clicking on buttons of headset are resuming the controller.

While at it, remove glue's extcon handling. Let the DTs being flattened use
role-switch/typec frameworks instead of extcon. DTs using "linux,extcon-usb-
gpio" can use "usb-conn-gpio" if they are having USB-B connectors. If they
are using Type-c like in case of msm8996-xiaomi-common.dtsi which gets
extcon informtation from TI based typec control chip, while flattening the
DT, role switch mechanism needs to be used instead of extcon.

This series has been tested on SM8450 QRD.
There will be a separate patch sent for flattening usb dt node.

changes in v2:
Rebased on top of usb-next.
Removed glue's extcon handling and made use of in-core handling.

Link to v1:
https://lore.kernel.org/all/20231017131851.8299-1-quic_kriskura@quicinc.com/

Krishna Kurapati (4):
  usb: dwc3: core: Introduce glue callbacks for flattened
    implementations
  usb: dwc3: qcom: Implement glue callbacks to facilitate runtime
    suspend
  usb: dwc3: qcom: Facilitate autosuspend during host mode
  usb: dwc3: qcom: Remove extcon functionality from glue

 drivers/usb/dwc3/core.c      |   1 +
 drivers/usb/dwc3/core.h      |  26 +++++
 drivers/usb/dwc3/drd.c       |   1 +
 drivers/usb/dwc3/dwc3-qcom.c | 219 +++++++++++++++++++----------------
 drivers/usb/dwc3/gadget.c    |   1 +
 5 files changed, 150 insertions(+), 98 deletions(-)

Comments

Krishna Kurapati June 10, 2025, 10:01 a.m. UTC | #1
On 6/10/2025 2:43 PM, Krishna Kurapati wrote:

[...]

> 
> changes in v2:
> Rebased on top of usb-next.

One correction. The series is based on top of (acked commit):

https://lore.kernel.org/all/20250604060019.2174029-1-krishna.kurapati@oss.qualcomm.com/

Sorry for the above mistake.

Regards,
Krishna.

> Removed glue's extcon handling and made use of in-core handling.
> 
> Link to v1:
> https://lore.kernel.org/all/20231017131851.8299-1-quic_kriskura@quicinc.com/
> 
> Krishna Kurapati (4):
>    usb: dwc3: core: Introduce glue callbacks for flattened
>      implementations
>    usb: dwc3: qcom: Implement glue callbacks to facilitate runtime
>      suspend
>    usb: dwc3: qcom: Facilitate autosuspend during host mode
>    usb: dwc3: qcom: Remove extcon functionality from glue
> 
>   drivers/usb/dwc3/core.c      |   1 +
>   drivers/usb/dwc3/core.h      |  26 +++++
>   drivers/usb/dwc3/drd.c       |   1 +
>   drivers/usb/dwc3/dwc3-qcom.c | 219 +++++++++++++++++++----------------
>   drivers/usb/dwc3/gadget.c    |   1 +
>   5 files changed, 150 insertions(+), 98 deletions(-)
>
Dmitry Baryshkov June 10, 2025, 5:24 p.m. UTC | #2
On Tue, Jun 10, 2025 at 10:10:33PM +0530, Krishna Kurapati wrote:
> 
> 
> On 6/10/2025 4:30 PM, Dmitry Baryshkov wrote:
> > On Tue, Jun 10, 2025 at 02:43:56PM +0530, Krishna Kurapati wrote:
> > > When in host mode, it is intended that the controller goes to suspend
> > > state to save power and wait for interrupts from connected peripheral
> > > to wake it up. This is particularly used in cases where a HID or Audio
> > > device is connected. In such scenarios, the usb controller can enter
> > > auto suspend and resume action after getting interrupts from the
> > > connected device.
> > > 
> > > Allow autosuspend for and xhci device and allow userspace to decide
> > > whether to enable this functionality.
> > > 
> > > a) Register to usb-core notifications in set_role vendor callback to
> > > identify when root hubs are being created. Configure them to
> > > use_autosuspend.
> > > 
> > > b) Identify usb core notifications where the HCD is being added and
> > > enable autosuspend for that particular xhci device.
> > > 
> > > Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> > > ---
> > >   drivers/usb/dwc3/dwc3-qcom.c | 62 ++++++++++++++++++++++++++++++++----
> > >   1 file changed, 56 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
> > > index d40b52e2ba01..17bbd5a06c08 100644
> > > --- a/drivers/usb/dwc3/dwc3-qcom.c
> > > +++ b/drivers/usb/dwc3/dwc3-qcom.c
> > > @@ -95,6 +95,8 @@ struct dwc3_qcom {
> > >   	 * internally by mutex lock.
> > >   	 */
> > >   	enum usb_role		current_role;
> > > +
> > > +	struct notifier_block	xhci_nb;
> > >   };
> > >   #define to_dwc3_qcom(d) container_of((d), struct dwc3_qcom, dwc)
> > > @@ -647,6 +649,39 @@ static int dwc3_qcom_setup_irq(struct dwc3_qcom *qcom, struct platform_device *p
> > >   	return 0;
> > >   }
> > > +static int dwc3_xhci_event_notifier(struct notifier_block *nb,
> > > +				    unsigned long event, void *ptr)
> > > +{
> > > +	struct dwc3_qcom  *qcom	= container_of(nb, struct dwc3_qcom, xhci_nb);
> > > +	struct dwc3	  *dwc	= &qcom->dwc;
> > > +	struct usb_bus	  *ubus	= ptr;
> > > +	struct usb_hcd	  *hcd;
> > > +
> > > +	if (!dwc->xhci)
> > > +		goto done;
> > > +
> > > +	hcd = platform_get_drvdata(dwc->xhci);
> > > +	if (!hcd)
> > > +		goto done;
> > > +
> > > +	if (event != USB_BUS_ADD)
> > > +		goto done;
> > > +
> > > +	if (strcmp(dev_name(ubus->sysdev), dev_name(dwc->sysdev)) != 0)
> > > +		goto done;
> > > +
> > > +	if (event == USB_BUS_ADD) {
> > > +		/*
> > > +		 * Identify instant of creation of primary hcd and
> > > +		 * mark xhci as autosuspend capable at this point.
> > > +		 */
> > > +		pm_runtime_use_autosuspend(&dwc->xhci->dev);
> > 
> > This feels like an overkill, using notifiers to set autosuspend flag.
> > Please extend platform data and/or other static code in order to set the
> > flag on the created xHCI devices.
> > 
> 
> Do you mean modifying pdev of xhci from dwc3/host.c ? Or adding the
> use_autosuspend call in xhci-plat.c ?

The latter one.

> 
> I thought adding this notifier would be a better way to identify when the
> xhci probe is in progress instead of touching pdev of xhci device from dwc3
> layer.
> 
> Regards,
> Krishna,