Message ID | 20160908122810.GA14132@b29397-desktop (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote: > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote: > > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote: > > > Arnd Bergmann <arnd@arndb.de> writes: > > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote: > > > If we have a parent device, use that as sysdev, otherwise use self as > > > sysdev. > > > > But there is often a parent device in DT, as the xhci device is > > attached to some internal bus that gets turned into a platform_device > > as well, so checking whether there is a parent will get the wrong > > device node. > > From my point, all platform and firmware information at dwc3 are > correct, so we don't need to change dwc3/core.c, only changing for > xhci-plat.c is ok. Ok, thanks. That leaves the PCI glue, right? > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index d2e3f65..563600b 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd) > /* Did the HC die before the root hub was registered? */ > if (HCD_DEAD(hcd)) > usb_hc_died (hcd); /* This time clean up */ > - usb_dev->dev.of_node = parent_dev->of_node; > + usb_dev->dev.of_node = parent_dev->sysdev->of_node; > } > mutex_unlock(&usb_bus_idr_lock); > > At above changes, the root hub's of_node equals to xhci-hcd sysdev's > of_node, which is from firmware or from its parent (it is dwc3 core > device). Just to make sure I understand you right: in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the dwc3 device, not the qcom,dwc3 device. > > > > That sounds a bit clumsy for the sake of consistency with PCI. > > > > The advantage is that xhci can always use the grandparent device > > > > as sysdev whenever it isn't probed through PCI or firmware > > > > itself, but the purpose of the dwc3-glue is otherwise questionable. > > > > > > > > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3 > > > > device when that is created from the PCI driver and checking for that > > > > with the device property interface instead? If it's "snps,dwc3" > > > > we use the device itself while for "snps,dwc3-pci", we use the parent? > > > > > For pci glue device, it is always the parent for dwc3 core device. > In your patch, you may not need to split pci or non-pci, just using > if (dev->parent). Here we have the pci-dwc3 -> dwc3 -> xhci hierarchy, and we want sysdev to point to pci-dwc3, not dwc3! The point is that the pci_dev is where we have the dma settings and (optionally) additional DT or ACPI data for that device. Arnd
On 09/08/2016 03:28 PM, Peter Chen wrote: > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote: >> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote: >>> Arnd Bergmann <arnd@arndb.de> writes: >>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote: >>>>>> If we do that, we have to put child devices of the dwc3 devices into >>>>>> the platform glue, and it also breaks those dwc3 devices that don't >>>>>> have a parent driver. >>>>> >>>>> Well, this is easy to fix: >>>>> >>>>> if (dwc->dev->parent) { >>>>> dwc->sysdev = dwc->dev->parent; >>>>> } else { >>>>> dev_info(dwc->dev, "Please provide a glue layer!\n"); >>>>> dwc->sysdev = dwc->dev; >>>>> } >>>> >>>> I don't understand. Do you mean we should have an extra level of >>>> stacking and splitting "static struct platform_driver dwc3_driver" >>>> in two so instead of >>>> >>>> "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev) >>>> >>>> we do this? >>>> >>>> "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev) >>> >>> no >>> >>> If we have a parent device, use that as sysdev, otherwise use self as >>> sysdev. >> >> But there is often a parent device in DT, as the xhci device is >> attached to some internal bus that gets turned into a platform_device >> as well, so checking whether there is a parent will get the wrong >> device node. > > From my point, all platform and firmware information at dwc3 are > correct, so we don't need to change dwc3/core.c, only changing for > xhci-plat.c is ok. > > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c > index ed56bf9..fd57c0d 100644 > --- a/drivers/usb/host/xhci-plat.c > +++ b/drivers/usb/host/xhci-plat.c > @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev) > struct clk *clk; > int ret; > int irq; > + struct device *dev = &pdev->dev, *sysdev; > > if (usb_disabled()) > return -ENODEV; > @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev) > if (irq < 0) > return -ENODEV; > > + if (dev->parent) { > + sysdev = dev->parent; > + } else { > + sysdev = dev; > + } > + Shouldn't we be more careful with that? armada-375.dtsi soc { compatible = "marvell,armada375-mbus", "simple-bus"; internal-regs { compatible = "simple-bus"; usb3@58000 { compatible = "marvell,armada-375-xhci"; reg = <0x58000 0x20000>,<0x5b880 0x80>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gateclk 16>; phys = <&usbcluster PHY_TYPE_USB3>; phy-names = "usb"; status = "disabled"; }; What will be the parent dev in above case?
On Thu, Sep 08, 2016 at 02:52:29PM +0200, Arnd Bergmann wrote: > On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote: > > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote: > > > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote: > > > > Arnd Bergmann <arnd@arndb.de> writes: > > > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote: > > > > If we have a parent device, use that as sysdev, otherwise use self as > > > > sysdev. > > > > > > But there is often a parent device in DT, as the xhci device is > > > attached to some internal bus that gets turned into a platform_device > > > as well, so checking whether there is a parent will get the wrong > > > device node. > > > > From my point, all platform and firmware information at dwc3 are > > correct, so we don't need to change dwc3/core.c, only changing for > > xhci-plat.c is ok. > > Ok, thanks. That leaves the PCI glue, right? If pci's firmware information can only get from dwc3-pci, I was wrong. I am almost sure your patch covers all 3 cases. dwc3->sysdev covers dwc3 core and gadget side, hcd->self.sysdev cover host side. The only possible improvement may be how to detect pci device. > > > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > > index d2e3f65..563600b 100644 > > --- a/drivers/usb/core/hcd.c > > +++ b/drivers/usb/core/hcd.c > > @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd) > > /* Did the HC die before the root hub was registered? */ > > if (HCD_DEAD(hcd)) > > usb_hc_died (hcd); /* This time clean up */ > > - usb_dev->dev.of_node = parent_dev->of_node; > > + usb_dev->dev.of_node = parent_dev->sysdev->of_node; > > } > > mutex_unlock(&usb_bus_idr_lock); > > > > At above changes, the root hub's of_node equals to xhci-hcd sysdev's > > of_node, which is from firmware or from its parent (it is dwc3 core > > device). > > Just to make sure I understand you right: > > in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the > dwc3 device, not the qcom,dwc3 device. > Yes, since there is a DT node for dwc3, and firmware information is there, that's why the original patch (Grygorii Strashko's) can work.
On Thu, Sep 08, 2016 at 03:59:19PM +0300, Grygorii Strashko wrote: > On 09/08/2016 03:28 PM, Peter Chen wrote: > > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote: > >> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote: > >>> Arnd Bergmann <arnd@arndb.de> writes: > >>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote: > >>>>>> If we do that, we have to put child devices of the dwc3 devices into > >>>>>> the platform glue, and it also breaks those dwc3 devices that don't > >>>>>> have a parent driver. > >>>>> > >>>>> Well, this is easy to fix: > >>>>> > >>>>> if (dwc->dev->parent) { > >>>>> dwc->sysdev = dwc->dev->parent; > >>>>> } else { > >>>>> dev_info(dwc->dev, "Please provide a glue layer!\n"); > >>>>> dwc->sysdev = dwc->dev; > >>>>> } > >>>> > >>>> I don't understand. Do you mean we should have an extra level of > >>>> stacking and splitting "static struct platform_driver dwc3_driver" > >>>> in two so instead of > >>>> > >>>> "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev) > >>>> > >>>> we do this? > >>>> > >>>> "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev) > >>> > >>> no > >>> > >>> If we have a parent device, use that as sysdev, otherwise use self as > >>> sysdev. > >> > >> But there is often a parent device in DT, as the xhci device is > >> attached to some internal bus that gets turned into a platform_device > >> as well, so checking whether there is a parent will get the wrong > >> device node. > > > > From my point, all platform and firmware information at dwc3 are > > correct, so we don't need to change dwc3/core.c, only changing for > > xhci-plat.c is ok. > > > > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c > > index ed56bf9..fd57c0d 100644 > > --- a/drivers/usb/host/xhci-plat.c > > +++ b/drivers/usb/host/xhci-plat.c > > @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev) > > struct clk *clk; > > int ret; > > int irq; > > + struct device *dev = &pdev->dev, *sysdev; > > > > if (usb_disabled()) > > return -ENODEV; > > @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev) > > if (irq < 0) > > return -ENODEV; > > > > + if (dev->parent) { > > + sysdev = dev->parent; > > + } else { > > + sysdev = dev; > > + } > > + > > Shouldn't we be more careful with that? > Above code does not consider pci device case, Arnd's patch covers all cases. > armada-375.dtsi > > soc { > compatible = "marvell,armada375-mbus", "simple-bus"; > > internal-regs { > compatible = "simple-bus"; > > usb3@58000 { > compatible = "marvell,armada-375-xhci"; > reg = <0x58000 0x20000>,<0x5b880 0x80>; > interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; > clocks = <&gateclk 16>; > phys = <&usbcluster PHY_TYPE_USB3>; > phy-names = "usb"; > status = "disabled"; > }; > > > What will be the parent dev in above case? > In this case, no parent dev for above case, it will use itself as sysdev since it has of_node at dts.
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ed56bf9..fd57c0d 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev) struct clk *clk; int ret; int irq; + struct device *dev = &pdev->dev, *sysdev; if (usb_disabled()) return -ENODEV; @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; + if (dev->parent) { + sysdev = dev->parent; + } else { + sysdev = dev; + } + /* Try to set 64-bit DMA first */ if (WARN_ON(!pdev->dev.dma_mask)) /* Platform did not initialize dma_mask */ @@ -170,7 +177,8 @@ static int xhci_plat_probe(struct platform_device *pdev) return ret; } - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); + hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, + dev_name(&pdev->dev), NULL); if (!hcd) return -ENOMEM; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d2e3f65..563600b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd) /* Did the HC die before the root hub was registered? */ if (HCD_DEAD(hcd)) usb_hc_died (hcd); /* This time clean up */ - usb_dev->dev.of_node = parent_dev->of_node; + usb_dev->dev.of_node = parent_dev->sysdev->of_node; } mutex_unlock(&usb_bus_idr_lock);