Message ID | 20250113-dwc3-refactor-v3-0-d1722075df7b@oss.qualcomm.com |
---|---|
Headers | show |
Series | usb: dwc3: qcom: Flatten dwc3 structure | expand |
On Mon, Jan 13, 2025 at 09:11:41PM -0800, Bjorn Andersson wrote: > The DWC3 IP block is handled by three distinct device drivers: XHCI, > DWC3 core and a platform specific (optional) DWC3 glue driver. > > This has resulted in, at least in the case of the Qualcomm glue, the > presence of a number of layering violations, where the glue code either > can't handle, or has to work around, the fact that core might not probe > deterministically. > > An example of this is that the suspend path should operate slightly > different depending on the device operating in host or peripheral mode, > and the only way to determine the operating state is to peek into the > core's drvdata. > > The Qualcomm glue driver is expected to make updates in the qscratch > register region (the "glue" region) during role switch events, but with > the glue and core split using the driver model, there is no reasonable > way to introduce listeners for mode changes. > > Split the dwc3 core platform_driver callbacks and their implementation > and export the implementation, to make it possible to deterministically > instantiate the dwc3 core as part of the dwc3 glue drivers and to > allow flattening of the DeviceTree representation. > > Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com> > --- > drivers/usb/dwc3/core.c | 149 ++++++++++++++++++++++++++++++------------------ > drivers/usb/dwc3/glue.h | 22 +++++++ > 2 files changed, 117 insertions(+), 54 deletions(-) > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index c22b8678e02e..930d812a9fbb 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -36,6 +36,7 @@ > > #include "core.h" > #include "gadget.h" > +#include "glue.h" > #include "io.h" > > #include "debug.h" > @@ -2129,27 +2130,14 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) > return 0; > } > > -static int dwc3_probe(struct platform_device *pdev) > +int dwc3_init(struct dwc3 *dwc, struct resource *res) Maybe need data struct, which included res. It may need pass down more information in future. > { > - struct device *dev = &pdev->dev; > - struct resource *res, dwc_res; > + struct device *dev = dwc->dev; > + struct resource dwc_res; > unsigned int hw_mode; > void __iomem *regs; > - struct dwc3 *dwc; > int ret; > ... > +++ b/drivers/usb/dwc3/glue.h > @@ -0,0 +1,22 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * glue.h - DesignWare USB3 DRD glue header > + */ > + > +#ifndef __DRIVERS_USB_DWC3_GLUE_H > +#define __DRIVERS_USB_DWC3_GLUE_H > + > +#include <linux/types.h> > +#include "core.h" > + > +int dwc3_init(struct dwc3 *dwc, struct resource *res); > +void dwc3_uninit(struct dwc3 *dwc); > + > +int dwc3_runtime_suspend(struct dwc3 *dwc); > +int dwc3_runtime_resume(struct dwc3 *dwc); > +int dwc3_runtime_idle(struct dwc3 *dwc); > +int dwc3_suspend(struct dwc3 *dwc); > +int dwc3_resume(struct dwc3 *dwc); > +void dwc3_complete(struct dwc3 *dwc); dwc3_usb_*()? There may be name polution in future. There are many IPs created by dwc. Frank > + > +#endif > > -- > 2.45.2 >
On Tue, Jan 14, 2025 at 02:43:59PM -0500, Frank Li wrote: > On Mon, Jan 13, 2025 at 09:11:41PM -0800, Bjorn Andersson wrote: > > The DWC3 IP block is handled by three distinct device drivers: XHCI, > > DWC3 core and a platform specific (optional) DWC3 glue driver. > > > > This has resulted in, at least in the case of the Qualcomm glue, the > > presence of a number of layering violations, where the glue code either > > can't handle, or has to work around, the fact that core might not probe > > deterministically. > > > > An example of this is that the suspend path should operate slightly > > different depending on the device operating in host or peripheral mode, > > and the only way to determine the operating state is to peek into the > > core's drvdata. > > > > The Qualcomm glue driver is expected to make updates in the qscratch > > register region (the "glue" region) during role switch events, but with > > the glue and core split using the driver model, there is no reasonable > > way to introduce listeners for mode changes. > > > > Split the dwc3 core platform_driver callbacks and their implementation > > and export the implementation, to make it possible to deterministically > > instantiate the dwc3 core as part of the dwc3 glue drivers and to > > allow flattening of the DeviceTree representation. > > > > Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com> > > --- > > drivers/usb/dwc3/core.c | 149 ++++++++++++++++++++++++++++++------------------ > > drivers/usb/dwc3/glue.h | 22 +++++++ > > 2 files changed, 117 insertions(+), 54 deletions(-) > > > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > > index c22b8678e02e..930d812a9fbb 100644 > > --- a/drivers/usb/dwc3/core.c > > +++ b/drivers/usb/dwc3/core.c > > @@ -36,6 +36,7 @@ > > > > #include "core.h" > > #include "gadget.h" > > +#include "glue.h" > > #include "io.h" > > > > #include "debug.h" > > @@ -2129,27 +2130,14 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) > > return 0; > > } > > > > -static int dwc3_probe(struct platform_device *pdev) > > +int dwc3_init(struct dwc3 *dwc, struct resource *res) > > Maybe need data struct, which included res. It may need pass down more > information in future. > Per this series we're resolving the race conditions stemming from dwc3-qcom and core having different lifetimes, but more importantly it will allow us to propose a mechanism for invoking role-switch events in the glue code from the core - i.e. we are planning to add at least one more argument here; so this proposal makes sense. > > { > > - struct device *dev = &pdev->dev; > > - struct resource *res, dwc_res; > > + struct device *dev = dwc->dev; > > + struct resource dwc_res; > > unsigned int hw_mode; > > void __iomem *regs; > > - struct dwc3 *dwc; > > int ret; > > > ... > > > +++ b/drivers/usb/dwc3/glue.h > > @@ -0,0 +1,22 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * glue.h - DesignWare USB3 DRD glue header > > + */ > > + > > +#ifndef __DRIVERS_USB_DWC3_GLUE_H > > +#define __DRIVERS_USB_DWC3_GLUE_H > > + > > +#include <linux/types.h> > > +#include "core.h" > > + > > +int dwc3_init(struct dwc3 *dwc, struct resource *res); > > +void dwc3_uninit(struct dwc3 *dwc); > > + > > +int dwc3_runtime_suspend(struct dwc3 *dwc); > > +int dwc3_runtime_resume(struct dwc3 *dwc); > > +int dwc3_runtime_idle(struct dwc3 *dwc); > > +int dwc3_suspend(struct dwc3 *dwc); > > +int dwc3_resume(struct dwc3 *dwc); > > +void dwc3_complete(struct dwc3 *dwc); > > dwc3_usb_*()? There may be name polution in future. There are many IPs > created by dwc. > I thought dwc3 was uniquely associated with USB, but I don't have any objections to your proposal. Thanks, Bjorn > Frank > > > + > > +#endif > > > > -- > > 2.45.2 > >
On Tue, Jan 14, 2025 at 11:44:52AM -0600, Rob Herring wrote: > On Mon, Jan 13, 2025 at 09:11:33PM -0800, Bjorn Andersson wrote: > > The USB IP-block found in most Qualcomm platforms is modelled in the > > Linux kernel as 3 different independent device drivers, but as shown by > > the already existing layering violations in the Qualcomm glue driver > > they can not be operated independently. > > > > With the current implementation, the glue driver registers the core and > > has no way to know when this is done. As a result, e.g. the suspend > > callbacks needs to guard against NULL pointer dereferences when trying > > to peek into the struct dwc3 found in the drvdata of the child. > > > > Missing from the upstream Qualcomm USB support is proper handling of > > role switching, in which the glue needs to be notified upon DRD mode > > changes. Several attempts has been made through the years to register > > callbacks etc, but they always fall short when it comes to handling of > > the core's probe deferral on resources etc. > > > > Furhtermore, the DeviceTree binding is a direct representation of the > > Linux driver model, and doesn't necessarily describe "the USB IP-block". > > > > This series therefor attempts to flatten the driver split, and operate > > the glue and core out of the same platform_device instance. And in order > > to do this, the DeviceTree representation of the IP block is flattened. > > > > To avoid littering the dwc3-qcom driver with the migration code - which > > we should be able to drop again in a LTS or two - this is now placed in > > drivers/of/overlays. > > > > A patch to convert a single platform - sc8280xp - is included in the > > series. The broader conversion will be submitted in a follow up series. > > Is it not possible to use the same overlays also fixup the .dts files at > build time? > I presume so. What would the benefit of that be, over fixing up the source asap? Regards, Bjorn
On Tue, Jan 14, 2025, Bjorn Andersson wrote: > On Tue, Jan 14, 2025 at 02:43:59PM -0500, Frank Li wrote: > > ... > > > > > +++ b/drivers/usb/dwc3/glue.h > > > @@ -0,0 +1,22 @@ > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > +/* > > > + * glue.h - DesignWare USB3 DRD glue header > > > + */ > > > + > > > +#ifndef __DRIVERS_USB_DWC3_GLUE_H > > > +#define __DRIVERS_USB_DWC3_GLUE_H > > > + > > > +#include <linux/types.h> > > > +#include "core.h" > > > + > > > +int dwc3_init(struct dwc3 *dwc, struct resource *res); > > > +void dwc3_uninit(struct dwc3 *dwc); > > > + > > > +int dwc3_runtime_suspend(struct dwc3 *dwc); > > > +int dwc3_runtime_resume(struct dwc3 *dwc); > > > +int dwc3_runtime_idle(struct dwc3 *dwc); > > > +int dwc3_suspend(struct dwc3 *dwc); > > > +int dwc3_resume(struct dwc3 *dwc); > > > +void dwc3_complete(struct dwc3 *dwc); > > > > dwc3_usb_*()? There may be name polution in future. There are many IPs > > created by dwc. > > > > I thought dwc3 was uniquely associated with USB, but I don't have any > objections to your proposal. > > Thanks, > Bjorn > Regarding this naming, let's keep them as what Bjorn has as they are more consistent to what we're doing in the driver. We can revise in the future should we need to. A couple of things I would like to rename is the "dwc3_uninit" to perhaps use dwc3_exit or dwc3_cleanup instead; the other is the dwc3_complete(), perhaps dwc3_pm_complete() for clarity. Also, should we add CONFIG_PM_SLEEP guards for these exported pm ops? Thanks, Thinh
On Tue, Jan 14, 2025, Thinh Nguyen wrote: > On Tue, Jan 14, 2025, Bjorn Andersson wrote: > > Also, should we add CONFIG_PM_SLEEP guards for these exported pm ops? Ignore this. I thought I saw the code outside of the guards. BR, Thinh
On Tue, Jan 14, 2025 at 5:04 PM Bjorn Andersson <andersson@kernel.org> wrote: > > On Tue, Jan 14, 2025 at 11:44:52AM -0600, Rob Herring wrote: > > On Mon, Jan 13, 2025 at 09:11:33PM -0800, Bjorn Andersson wrote: > > > The USB IP-block found in most Qualcomm platforms is modelled in the > > > Linux kernel as 3 different independent device drivers, but as shown by > > > the already existing layering violations in the Qualcomm glue driver > > > they can not be operated independently. > > > > > > With the current implementation, the glue driver registers the core and > > > has no way to know when this is done. As a result, e.g. the suspend > > > callbacks needs to guard against NULL pointer dereferences when trying > > > to peek into the struct dwc3 found in the drvdata of the child. > > > > > > Missing from the upstream Qualcomm USB support is proper handling of > > > role switching, in which the glue needs to be notified upon DRD mode > > > changes. Several attempts has been made through the years to register > > > callbacks etc, but they always fall short when it comes to handling of > > > the core's probe deferral on resources etc. > > > > > > Furhtermore, the DeviceTree binding is a direct representation of the > > > Linux driver model, and doesn't necessarily describe "the USB IP-block". > > > > > > This series therefor attempts to flatten the driver split, and operate > > > the glue and core out of the same platform_device instance. And in order > > > to do this, the DeviceTree representation of the IP block is flattened. > > > > > > To avoid littering the dwc3-qcom driver with the migration code - which > > > we should be able to drop again in a LTS or two - this is now placed in > > > drivers/of/overlays. > > > > > > A patch to convert a single platform - sc8280xp - is included in the > > > series. The broader conversion will be submitted in a follow up series. > > > > Is it not possible to use the same overlays also fixup the .dts files at > > build time? > > > > I presume so. What would the benefit of that be, over fixing up the > source asap? The overlays would live with all the other dts files (I think kbuild can add built-in dtbs from arch/*/boot/dts/). We can test at build time they actually apply, and ensure the new dtb matches what the fixup overlay creates. Rob