Amlogic Meson GXL/GXM USB support (dwc2 and dwc3)
Hello, currently I am trying to get the USB controllers on the Amlogic Meson GXL SoCs working: there is one dwc2 and dwc3 controller each. The SoC itself provides 3x USB2 PHYs and 1x USB3 PHY. I wrote drivers for both of them based on the vendor kernel, see [0] The PHY registers of the USB2 PHYs seem to be identical, regardless of whether they are connected to dwc2 or dwc3. The USB3 PHY also takes care of the OTG interrupts (to switch between host and device) and seems to inform the USB2 PHY about mode-changes. USB3 seems to be disabled in the dwc3 configuration, meaning it provides only high-speed support. The dwc3 core fails to initialize currently due to some DMA issues which will be fixed in Linux v4.10 - the corresponding patchset can be found here: [1] With these patches applied we get the dwc3 controller to initialize: xhci-hcd xhci-hcd.0.auto: xHCI Host Controller xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 xhci-hcd xhci-hcd.0.auto: hcc params 0x0228f664 hci version 0x100 quirks 0x00010010 xhci-hcd xhci-hcd.0.auto: irq 20, io mem 0xc900 hub 1-0:1.0: USB hub found hub 1-0:1.0: 3 ports detected xhci-hcd xhci-hcd.0.auto: xHCI Host Controller xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 usb usb2: We don't know the algorithms for LPM for this host, disabling LPM. hub 2-0:1.0: USB hub found hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19) (the last message seems fine, there are probably no USB3 ports enabled in the dwc3 hardware configuration) strange fact #1: there are 3 USB2 PHYs enabled in the dwc3 core (regdump from the vendor kernel - a full version is attached): GUSB2PHYCFG(0) = 0x40102500 GUSB2PHYCFG(1) = 0x40102540 GUSB2PHYCFG(2) = 0x40102540 (this explains the "hub 1-0:1.0: 3 ports detected" message on my GXM board - other SoCs seem to have a different number of ports available based on the vendor sources, GXL seem to have 2 ports, while "TXL" seems to have 4 ports). I tried enabling all available PHYs in the SoC and giving GUSB2PHYCFG(1 and 2) the same tickle that is currently done in dwc3_phy_setup() for GUSB2PHYCFG(0). The LED on my thumb drive flashes when I plug it into the dwc3 port, but I don't get any interrupts and the kernel does not recognize any new USB device. For the dwc2 controller I am probably missing a clock somewhere, because it's reporting: dwc2 c910.usb: Configuration mismatch. dr_mode forced to device dwc2 c910.usb: dwc2_core_reset() HANG! Soft Reset GRSTCTL=8001 dwc2 c910.usb: Specified GNPTXFDEP=1024 > 768 dwc2 c910.usb: EPs: 7, dedicated fifos, 712 entries in SPRAM I must admit that I have been focusing on the dwc3 controller so far, so I don't have any more information here. if any of these problems sound familiar to you or if you have any advice on what I could experiment with: please don't hesitate and let me know! I'll also keep continue looking into this, because it's not unlikely that I'm running into a platform specific issue. Regards, Martin [0] https://github.com/xdarklight/linux/commits/meson-gx-integration-4.10-20161123 [1] http://marc.info/?l=linux-usb&m=147938307209685&w=2 sys_kernel_debug_dwc3_regdump_vendor_kernel Description: Binary data
Re: Amlogic Meson GXL/GXM USB support (dwc2 and dwc3)
On Thu, Nov 24, 2016 at 6:42 PM, Martin Blumenstingl wrote: > Hello, > > currently I am trying to get the USB controllers on the Amlogic Meson > GXL SoCs working: there is one dwc2 and dwc3 controller each. > > The SoC itself provides 3x USB2 PHYs and 1x USB3 PHY. > I wrote drivers for both of them based on the vendor kernel, see [0] > The PHY registers of the USB2 PHYs seem to be identical, regardless of > whether they are connected to dwc2 or dwc3. > The USB3 PHY also takes care of the OTG interrupts (to switch between > host and device) and seems to inform the USB2 PHY about mode-changes. > USB3 seems to be disabled in the dwc3 configuration, meaning it > provides only high-speed support. > > The dwc3 core fails to initialize currently due to some DMA issues > which will be fixed in Linux v4.10 - the corresponding patchset can be > found here: [1] > With these patches applied we get the dwc3 controller to initialize: > xhci-hcd xhci-hcd.0.auto: xHCI Host Controller > xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 > xhci-hcd xhci-hcd.0.auto: hcc params 0x0228f664 hci version 0x100 > quirks 0x00010010 > xhci-hcd xhci-hcd.0.auto: irq 20, io mem 0xc900 > hub 1-0:1.0: USB hub found > hub 1-0:1.0: 3 ports detected > xhci-hcd xhci-hcd.0.auto: xHCI Host Controller > xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 > usb usb2: We don't know the algorithms for LPM for this host, disabling LPM. > hub 2-0:1.0: USB hub found > hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19) > (the last message seems fine, there are probably no USB3 ports enabled > in the dwc3 hardware configuration) > > strange fact #1: there are 3 USB2 PHYs enabled in the dwc3 core > (regdump from the vendor kernel - a full version is attached): > GUSB2PHYCFG(0) = 0x40102500 > GUSB2PHYCFG(1) = 0x40102540 > GUSB2PHYCFG(2) = 0x40102540 > (this explains the "hub 1-0:1.0: 3 ports detected" message on my GXM > board - other SoCs seem to have a different number of ports available > based on the vendor sources, GXL seem to have 2 ports, while "TXL" > seems to have 4 ports). > > I tried enabling all available PHYs in the SoC and giving > GUSB2PHYCFG(1 and 2) the same tickle that is currently done in > dwc3_phy_setup() for GUSB2PHYCFG(0). > The LED on my thumb drive flashes when I plug it into the dwc3 port, > but I don't get any interrupts and the kernel does not recognize any > new USB device. it turns out that this was a PHY problem. due to whatever reason it seems that we have to enable all 3 USB2 PHYs in the SoC to make *any* of these work! After lots of headache and refactoring I have my USB2 PHY driver now in a working state (in case someone is interested in this early code: [0]). > For the dwc2 controller I am probably missing a clock somewhere, > because it's reporting: > dwc2 c910.usb: Configuration mismatch. dr_mode forced to device > dwc2 c910.usb: dwc2_core_reset() HANG! Soft Reset GRSTCTL=8001 > dwc2 c910.usb: Specified GNPTXFDEP=1024 > 768 > dwc2 c910.usb: EPs: 7, dedicated fifos, 712 entries in SPRAM > I must admit that I have been focusing on the dwc3 controller so far, > so I don't have any more information here. I do not have any (new) findings here as I was busy with the dwc3 PHY driver again. [0] https://github.com/xdarklight/linux/commits/meson-gx-integration-4.10-20161125 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Amlogic Meson GXL/GXM USB support (dwc2 and dwc3)
On Thu, Nov 24, 2016 at 6:42 PM, Martin Blumenstingl wrote: > Hello, > > currently I am trying to get the USB controllers on the Amlogic Meson > GXL SoCs working: there is one dwc2 and dwc3 controller each. > > The SoC itself provides 3x USB2 PHYs and 1x USB3 PHY. > I wrote drivers for both of them based on the vendor kernel, see [0] > The PHY registers of the USB2 PHYs seem to be identical, regardless of > whether they are connected to dwc2 or dwc3. > The USB3 PHY also takes care of the OTG interrupts (to switch between > host and device) and seems to inform the USB2 PHY about mode-changes. > USB3 seems to be disabled in the dwc3 configuration, meaning it > provides only high-speed support. > > The dwc3 core fails to initialize currently due to some DMA issues > which will be fixed in Linux v4.10 - the corresponding patchset can be > found here: [1] > With these patches applied we get the dwc3 controller to initialize: > xhci-hcd xhci-hcd.0.auto: xHCI Host Controller > xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 > xhci-hcd xhci-hcd.0.auto: hcc params 0x0228f664 hci version 0x100 > quirks 0x00010010 > xhci-hcd xhci-hcd.0.auto: irq 20, io mem 0xc900 > hub 1-0:1.0: USB hub found > hub 1-0:1.0: 3 ports detected > xhci-hcd xhci-hcd.0.auto: xHCI Host Controller > xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 > usb usb2: We don't know the algorithms for LPM for this host, disabling LPM. > hub 2-0:1.0: USB hub found > hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19) > (the last message seems fine, there are probably no USB3 ports enabled > in the dwc3 hardware configuration) > > strange fact #1: there are 3 USB2 PHYs enabled in the dwc3 core > (regdump from the vendor kernel - a full version is attached): > GUSB2PHYCFG(0) = 0x40102500 > GUSB2PHYCFG(1) = 0x40102540 > GUSB2PHYCFG(2) = 0x40102540 > (this explains the "hub 1-0:1.0: 3 ports detected" message on my GXM > board - other SoCs seem to have a different number of ports available > based on the vendor sources, GXL seem to have 2 ports, while "TXL" > seems to have 4 ports). > > I tried enabling all available PHYs in the SoC and giving > GUSB2PHYCFG(1 and 2) the same tickle that is currently done in > dwc3_phy_setup() for GUSB2PHYCFG(0). > The LED on my thumb drive flashes when I plug it into the dwc3 port, > but I don't get any interrupts and the kernel does not recognize any > new USB device. > > For the dwc2 controller I am probably missing a clock somewhere, > because it's reporting: > dwc2 c910.usb: Configuration mismatch. dr_mode forced to device > dwc2 c910.usb: dwc2_core_reset() HANG! Soft Reset GRSTCTL=8001 > dwc2 c910.usb: Specified GNPTXFDEP=1024 > 768 > dwc2 c910.usb: EPs: 7, dedicated fifos, 712 entries in SPRAM > I must admit that I have been focusing on the dwc3 controller so far, > so I don't have any more information here. I found out that the dwc2 block is not used on my GXM SoC. the configuration register forces it to "device" mode only, so it wouldn't be of much use anyways. with my latest PHY fixes I can now use both USB ports (both provided by the dwc3 controller's internal hub). the work-in-progress code can be found here: [0] Regards, Martin [0] https://github.com/xdarklight/linux/tree/meson-gx-integration-4.10-20161126 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
dwc3: add support for hardware with multiple ports on USB2 hub enabled
Hello, while adding USB support on the Amlogic Meson GXL / GXM SoCs I have come across something I did not know yet: dwc3 has an internal USB2 hub (from what I can read in the code there seem to be multiple USB3 ports supported as well). When searching the web I did not come across any SoC that uses a configuration with more than one port enabled. On my Amlogic Meson GXM device (consumer device, no development board) I see the following USB2 PHY register configuration (full register dump from the kernel that was shipped with the device is attached): GUSB2PHYCFG(0) = 0x40102500 GUSB2PHYCFG(1) = 0x40102540 GUSB2PHYCFG(2) = 0x40102540 Then vendor kernel sources (a 3.14 kernel) are adding the resets for GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches from linux-usb) kernel works fine even with just applying the reset to GUSB2PHYCFG(0). That brings up two questions: 1. I guess it makes sense to adjust the upstream dwc3 to add the resets for all available USB2 PHYs - is there a specific reason why the current dwc3 driver does not do that (or is it simply because why we find on Meson GXL/GXM is very exotic)? 2. would we also implement this for the USB3 "pipes" as well (without being able to test this)? 3. from what I can see in the code we have to adjust dwc3_phy_setup() and ulpi.c to add support for multiple ports, but how do we detect the number of USB2 and USB3 ports (is this somewhere encoded in the DWC3_GHWPARAMS registers)? lsusb output is also attached, based on the PHY drivers for which the patches can be found here: [0] Best Regards, Martin [0] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001721.html sys_kernel_debug_dwc3_regdump_vendor_kernel Description: Binary data lsusb-mainline-kernel Description: Binary data
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Sun, Nov 27, 2016 at 2:02 PM, Martin Blumenstingl wrote: > Hello, > > while adding USB support on the Amlogic Meson GXL / GXM SoCs I have > come across something I did not know yet: > dwc3 has an internal USB2 hub (from what I can read in the code there > seem to be multiple USB3 ports supported as well). > When searching the web I did not come across any SoC that uses a > configuration with more than one port enabled. > > On my Amlogic Meson GXM device (consumer device, no development board) > I see the following USB2 PHY register configuration (full register > dump from the kernel that was shipped with the device is attached): > GUSB2PHYCFG(0) = 0x40102500 > GUSB2PHYCFG(1) = 0x40102540 > GUSB2PHYCFG(2) = 0x40102540 > > Then vendor kernel sources (a 3.14 kernel) are adding the resets for > GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). > A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches > from linux-usb) kernel works fine even with just applying the reset to > GUSB2PHYCFG(0). > > That brings up two questions: > 1. I guess it makes sense to adjust the upstream dwc3 to add the > resets for all available USB2 PHYs - is there a specific reason why > the current dwc3 driver does not do that (or is it simply because why > we find on Meson GXL/GXM is very exotic)? > 2. would we also implement this for the USB3 "pipes" as well (without > being able to test this)? > 3. from what I can see in the code we have to adjust dwc3_phy_setup() > and ulpi.c to add support for multiple ports, but how do we detect the > number of USB2 and USB3 ports (is this somewhere encoded in the > DWC3_GHWPARAMS registers)? > > lsusb output is also attached, based on the PHY drivers for which the > patches can be found here: [0] > > > Best Regards, > Martin > > > [0] > http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001721.html re-sending due to a typo in Felipe Balbi's email address (sorry for that) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
Hello Felipe, Hello John, On Sun, Nov 27, 2016 at 2:05 PM, Martin Blumenstingl wrote: > On Sun, Nov 27, 2016 at 2:02 PM, Martin Blumenstingl > wrote: >> Hello, >> >> while adding USB support on the Amlogic Meson GXL / GXM SoCs I have >> come across something I did not know yet: >> dwc3 has an internal USB2 hub (from what I can read in the code there >> seem to be multiple USB3 ports supported as well). >> When searching the web I did not come across any SoC that uses a >> configuration with more than one port enabled. I am still trying to figure out the logic behind the dwc3 USB hubs to add USB support for the Amlogic Meson GXL and GXM SoCs. Unfortunately I do not have access to the dwc3 documentation. It would be great if you could share your thoughts how to add support for dwc3 configurations with more than one port enabled on the internal hub. I am *not* expecting any finished code or a concept that just has to be converted to "source code". You can find *my* ideas on how to solve this below. >> On my Amlogic Meson GXM device (consumer device, no development board) >> I see the following USB2 PHY register configuration (full register >> dump from the kernel that was shipped with the device is attached): >> GUSB2PHYCFG(0) = 0x40102500 >> GUSB2PHYCFG(1) = 0x40102540 >> GUSB2PHYCFG(2) = 0x40102540 >> >> Then vendor kernel sources (a 3.14 kernel) are adding the resets for >> GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). >> A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches >> from linux-usb) kernel works fine even with just applying the reset to >> GUSB2PHYCFG(0). >> >> That brings up two questions: >> 1. I guess it makes sense to adjust the upstream dwc3 to add the >> resets for all available USB2 PHYs - is there a specific reason why >> the current dwc3 driver does not do that (or is it simply because why >> we find on Meson GXL/GXM is very exotic)? >> 2. would we also implement this for the USB3 "pipes" as well (without >> being able to test this)? >> 3. from what I can see in the code we have to adjust dwc3_phy_setup() >> and ulpi.c to add support for multiple ports, but how do we detect the >> number of USB2 and USB3 ports (is this somewhere encoded in the >> DWC3_GHWPARAMS registers)? after reading more about how USB hubs are working internally it seems to me that this design makes sense. I guess the answer for #1 and #2 is simply "yes". it also seems to make sense that I have to enable all USB2 PHYs (additional info: I cannot get dwc3 to detect any device as long as any of the USB PHYs is disabled, even if the device is plugged into a non-disabled port) due to the way an USB hub works. so it only seems logical that we should add support for that to the dwc3 driver as well. my current idea is to describe the hub on the dwc3 via devicetree (thanks to Rob for the idea back in November). the result could look like this (very work in progress!): roothub@0 { compatible = "usb1d6b,2"; #address-cells = <1>; #size-cells = <0>; reg = <0>; port@1 { reg = <1>; phys = <&usb2_phy0>; phy-names = "usb2-phy"; }; port@2 { reg = <2>; phys = <&usb2_phy1>; phy-names = "usb2-phy"; }; }; (there are no usb3-phys configured because these are not supported on the SoC I'm testing with, but the code would support these of course) This would also allow us to move settings like "snps,dis_u2_susphy_quirk" to specific ports as well. If we don't find the root-hub as child-node of the dwc3 node then we can simply fall back to parsing the dwc3 node itself (to ensure backwards compatibility). we could also use this in the future to prevent the following error message when the dwc3 IP is configured without USB3 ports: hub 2-0:1.0: USB hub found hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19) PS: I found the Genesys Logic GL850 and Cypress CY7C65642 datasheets helpful. The "Block Diagrams" give a good basic overview. Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
Hi Felipe, On Mon, Jan 9, 2017 at 11:37 AM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: >> while adding USB support on the Amlogic Meson GXL / GXM SoCs I have >> come across something I did not know yet: >> dwc3 has an internal USB2 hub (from what I can read in the code there >> seem to be multiple USB3 ports supported as well). > > no, that's not true. It has a roothub when working as host. But that's > it. When working as peripheral, it's always single-port AFAIR. OK, I should have been more clear here: I am only talking about host-mode since DWC3_GHWPARAMS0 on the GXL/GXM SoCs has a value of 0x20208009 which translates to "DWC3_GHWPARAMS0_MODE_HOST". are you sure about the fact that it does not have an internal hub? What I see in both, the vendor kernel's and my own patched mainline kernel log is: [ 19.130331@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller [ 19.130385@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 [ 19.139666@3] xhci-hcd xhci-hcd.0.auto: irq 62, io mem 0xc900 [ 19.145295@3] hub 1-0:1.0: USB hub found [ 19.148098@3] hub 1-0:1.0: 3 ports detected [ 19.152396@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller [ 19.157813@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 [ 19.166598@3] hub 2-0:1.0: USB hub found [ 19.169452@3] hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19) This is from a GXM SoC which also comes with 3x USB2 PHYs (these are not Synopsys DesignWare PHYs but custom ones from Amlogic). I see similar messages but with "2 ports detect" on a GXL SoC which comes with 2x USB2 PHYs. >> When searching the web I did not come across any SoC that uses a >> configuration with more than one port enabled. >> >> On my Amlogic Meson GXM device (consumer device, no development board) >> I see the following USB2 PHY register configuration (full register >> dump from the kernel that was shipped with the device is attached): >> GUSB2PHYCFG(0) = 0x40102500 >> GUSB2PHYCFG(1) = 0x40102540 >> GUSB2PHYCFG(2) = 0x40102540 > > multiple PHYs are only used by the host block (xHCI). Don't touch these > and just let xHCI core handle the ports. could you be more specific with "xHCI core" - do you mean the core in the dwc3 IP or drivers/usb/host/xhci-*? However, we still have a "problem" here: the USB PHYs for each "enabled" port have to be turned on (if I leave only one USB PHY disabled then none of the ports is working). unfortunately the current code (both, in dwc3 and drivers/usb/host/*) assumes that there's either 0 or 1 PHY for each HCD. >> Then vendor kernel sources (a 3.14 kernel) are adding the resets for >> GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). > > That shouldn't be necessary, actually. If it is, it means the HW was > poorly integrated. In that case, we _can_ add the other resets, but I > need confirmation that they are needed by means of a public errata > document. > >> A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches >> from linux-usb) kernel works fine even with just applying the reset to >> GUSB2PHYCFG(0). > > there you go does that mean that the reset of GUSB2PHYCFG(0) (which is part of the current dwc3 code in dwc3_phy_setup) is done only because of the quirks/erratas? in other words: do you mean that one would not have to reset GUSB2PHYCFG(0) if there were no erratas? >> That brings up two questions: >> 1. I guess it makes sense to adjust the upstream dwc3 to add the >> resets for all available USB2 PHYs - is there a specific reason why >> the current dwc3 driver does not do that (or is it simply because why >> we find on Meson GXL/GXM is very exotic)? > > yeah, they're not needed :-) > >> 2. would we also implement this for the USB3 "pipes" as well (without >> being able to test this)? > > nope these two are probably covered with the question before >> 3. from what I can see in the code we have to adjust dwc3_phy_setup() >> and ulpi.c to add support for multiple ports, but how do we detect the >> number of USB2 and USB3 ports (is this somewhere encoded in the >> DWC3_GHWPARAMS registers)? > > also nope. xHCI can detect how many ports a roothub has and work with > it. From peripheral point of view, dwc3 is always single-port. let's postpone this until we have discussed the more important questions Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Mon, Jan 9, 2017 at 12:18 PM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: >>> Martin Blumenstingl writes: >>>> while adding USB support on the Amlogic Meson GXL / GXM SoCs I have >>>> come across something I did not know yet: >>>> dwc3 has an internal USB2 hub (from what I can read in the code there >>>> seem to be multiple USB3 ports supported as well). >>> >>> no, that's not true. It has a roothub when working as host. But that's >>> it. When working as peripheral, it's always single-port AFAIR. >> OK, I should have been more clear here: I am only talking about >> host-mode since DWC3_GHWPARAMS0 on the GXL/GXM SoCs has a value of >> 0x20208009 which translates to "DWC3_GHWPARAMS0_MODE_HOST". >> >> are you sure about the fact that it does not have an internal hub? >> What I see in both, the vendor kernel's and my own patched mainline >> kernel log is: >> [ 19.130331@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller >> [ 19.130385@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, >> assigned bus number 1 >> [ 19.139666@3] xhci-hcd xhci-hcd.0.auto: irq 62, io mem 0xc900 >> [ 19.145295@3] hub 1-0:1.0: USB hub found > > this is the roothub :-) agreed :) >> [ 19.148098@3] hub 1-0:1.0: 3 ports detected this is the one I wanted to point out: in this case there are 3 ports on the (USB2) roothub. the SoC has one USB2 for each of these ports, and all 3 PHYs have to be initialized to get USB working (this seems to be my main issue). >> [ 19.152396@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller >> [ 19.157813@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, >> assigned bus number 2 >> [ 19.166598@3] hub 2-0:1.0: USB hub found >> [ 19.169452@3] hub 2-0:1.0: config failed, hub doesn't have any >> ports! (err -19) >> This is from a GXM SoC which also comes with 3x USB2 PHYs (these are >> not Synopsys DesignWare PHYs but custom ones from Amlogic). >> I see similar messages but with "2 ports detect" on a GXL SoC which >> comes with 2x USB2 PHYs. > > The fact that is claims that it has "no ports" hints at quirk caused, > likely, by poor RTL edits. coreConsultant should make sure that > MAX_PORTS (in xHCI HCC_PARAMS* register set) was set to correct value, > but somehow that field is set to 0 in one of your Amlogic SoC. yes, it's a USB2-only configuration (so there are no USB3 ports on the internal roothub) >>>> When searching the web I did not come across any SoC that uses a >>>> configuration with more than one port enabled. >>>> >>>> On my Amlogic Meson GXM device (consumer device, no development board) >>>> I see the following USB2 PHY register configuration (full register >>>> dump from the kernel that was shipped with the device is attached): >>>> GUSB2PHYCFG(0) = 0x40102500 >>>> GUSB2PHYCFG(1) = 0x40102540 >>>> GUSB2PHYCFG(2) = 0x40102540 >>> >>> multiple PHYs are only used by the host block (xHCI). Don't touch these >>> and just let xHCI core handle the ports. >> could you be more specific with "xHCI core" - do you mean the core in >> the dwc3 IP or drivers/usb/host/xhci-*? >> However, we still have a "problem" here: the USB PHYs for each >> "enabled" port have to be turned on (if I leave only one USB PHY >> disabled then none of the ports is working). unfortunately the current >> code (both, in dwc3 and drivers/usb/host/*) assumes that there's >> either 0 or 1 PHY for each HCD. >> >>>> Then vendor kernel sources (a 3.14 kernel) are adding the resets for >>>> GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). >>> >>> That shouldn't be necessary, actually. If it is, it means the HW was >>> poorly integrated. In that case, we _can_ add the other resets, but I >>> need confirmation that they are needed by means of a public errata >>> document. >>> >>>> A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches >>>> from linux-usb) kernel works fine even with just applying the reset to >>>> GUSB2PHYCFG(0). >>> >>> there you go >> does that mean that the reset of GUSB2PHYCFG(0) (which is part of the >> current dwc3 code in dwc3_phy_setup) is done only because of the >> quirks/erratas? in other words: do you mean that one would not have to >> reset GUSB2PHYCFG(0) if there were no erratas? > > no, it's done for peripheral configuration of dwc3. Look at the code > more carefully: sorry for the confusion - the word "reset" should be "configuration". The function I am looking at is dwc3_phy_setup(): apart from toggling some "errata bits" it also configures the PHY modes. I am wondering if I need to do this setup (DWC3_GUSB2PHYCFG_ULPI_UTMI and DWC3_GUSB2PHYCFG_PHYIF_MASK related bits) not only for the *first* port ("DWC3_GUSB2PHYCFG(0)") but also for the "other" ports (index 1 and 2 in above case, where the roothub has 3 ports) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Mon, Jan 9, 2017 at 12:55 PM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: >> On Mon, Jan 9, 2017 at 12:18 PM, Felipe Balbi >> wrote: >>> >>> Hi, >>> >>> Martin Blumenstingl writes: >>>>> Martin Blumenstingl writes: >>>>>> while adding USB support on the Amlogic Meson GXL / GXM SoCs I have >>>>>> come across something I did not know yet: >>>>>> dwc3 has an internal USB2 hub (from what I can read in the code there >>>>>> seem to be multiple USB3 ports supported as well). >>>>> >>>>> no, that's not true. It has a roothub when working as host. But that's >>>>> it. When working as peripheral, it's always single-port AFAIR. >>>> OK, I should have been more clear here: I am only talking about >>>> host-mode since DWC3_GHWPARAMS0 on the GXL/GXM SoCs has a value of >>>> 0x20208009 which translates to "DWC3_GHWPARAMS0_MODE_HOST". >>>> >>>> are you sure about the fact that it does not have an internal hub? >>>> What I see in both, the vendor kernel's and my own patched mainline >>>> kernel log is: >>>> [ 19.130331@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller >>>> [ 19.130385@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, >>>> assigned bus number 1 >>>> [ 19.139666@3] xhci-hcd xhci-hcd.0.auto: irq 62, io mem 0xc900 >>>> [ 19.145295@3] hub 1-0:1.0: USB hub found >>> >>> this is the roothub :-) >> agreed :) >> >>>> [ 19.148098@3] hub 1-0:1.0: 3 ports detected >> this is the one I wanted to point out: in this case there are 3 ports >> on the (USB2) roothub. >> the SoC has one USB2 for each of these ports, and all 3 PHYs have to >> be initialized to get USB working (this seems to be my main issue). >> >>>> [ 19.152396@3] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller >>>> [ 19.157813@3] xhci-hcd xhci-hcd.0.auto: new USB bus registered, >>>> assigned bus number 2 >>>> [ 19.166598@3] hub 2-0:1.0: USB hub found >>>> [ 19.169452@3] hub 2-0:1.0: config failed, hub doesn't have any >>>> ports! (err -19) >>>> This is from a GXM SoC which also comes with 3x USB2 PHYs (these are >>>> not Synopsys DesignWare PHYs but custom ones from Amlogic). >>>> I see similar messages but with "2 ports detect" on a GXL SoC which >>>> comes with 2x USB2 PHYs. >>> >>> The fact that is claims that it has "no ports" hints at quirk caused, >>> likely, by poor RTL edits. coreConsultant should make sure that >>> MAX_PORTS (in xHCI HCC_PARAMS* register set) was set to correct value, >>> but somehow that field is set to 0 in one of your Amlogic SoC. >> yes, it's a USB2-only configuration (so there are no USB3 ports on the >> internal roothub) > > aha, makes sense. > >>>>>> When searching the web I did not come across any SoC that uses a >>>>>> configuration with more than one port enabled. >>>>>> >>>>>> On my Amlogic Meson GXM device (consumer device, no development board) >>>>>> I see the following USB2 PHY register configuration (full register >>>>>> dump from the kernel that was shipped with the device is attached): >>>>>> GUSB2PHYCFG(0) = 0x40102500 >>>>>> GUSB2PHYCFG(1) = 0x40102540 >>>>>> GUSB2PHYCFG(2) = 0x40102540 >>>>> >>>>> multiple PHYs are only used by the host block (xHCI). Don't touch these >>>>> and just let xHCI core handle the ports. >>>> could you be more specific with "xHCI core" - do you mean the core in >>>> the dwc3 IP or drivers/usb/host/xhci-*? >>>> However, we still have a "problem" here: the USB PHYs for each >>>> "enabled" port have to be turned on (if I leave only one USB PHY >>>> disabled then none of the ports is working). unfortunately the current >>>> code (both, in dwc3 and drivers/usb/host/*) assumes that there's >>>> either 0 or 1 PHY for each HCD. > > true. But even so, that PHY handle is only needed for devices which > weren't properly configured at coreConsultant time. I don't understand that - there are two separate modules involved here: 1. the dwc3 IP block 2. Amlogic's own USB2 PHYs (they did not choose Synopsys DesignWare PHYs) (some background info: th
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Mon, Jan 9, 2017 at 1:16 PM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: >>>>>>>> When searching the web I did not come across any SoC that uses a >>>>>>>> configuration with more than one port enabled. >>>>>>>> >>>>>>>> On my Amlogic Meson GXM device (consumer device, no development board) >>>>>>>> I see the following USB2 PHY register configuration (full register >>>>>>>> dump from the kernel that was shipped with the device is attached): >>>>>>>> GUSB2PHYCFG(0) = 0x40102500 >>>>>>>> GUSB2PHYCFG(1) = 0x40102540 >>>>>>>> GUSB2PHYCFG(2) = 0x40102540 >>>>>>> >>>>>>> multiple PHYs are only used by the host block (xHCI). Don't touch these >>>>>>> and just let xHCI core handle the ports. >>>>>> could you be more specific with "xHCI core" - do you mean the core in >>>>>> the dwc3 IP or drivers/usb/host/xhci-*? >>>>>> However, we still have a "problem" here: the USB PHYs for each >>>>>> "enabled" port have to be turned on (if I leave only one USB PHY >>>>>> disabled then none of the ports is working). unfortunately the current >>>>>> code (both, in dwc3 and drivers/usb/host/*) assumes that there's >>>>>> either 0 or 1 PHY for each HCD. >>> >>> true. But even so, that PHY handle is only needed for devices which >>> weren't properly configured at coreConsultant time. >> I don't understand that - there are two separate modules involved >> here: 1. the dwc3 IP block 2. Amlogic's own USB2 PHYs (they did not >> choose Synopsys DesignWare PHYs) >> (some background info: the USB2 PHYs are in "reset mode" by default) >> So even if the dwc3 IP block is configured correctly at coreConsultant >> time we still need to configure the PHYs. From "USB controller driver" >> (could be dwc3, or some generic hcd.c code, etc.) this means that >> phy_init() and phy_power_on() needs to be called for each of the three >> "Amlogic USB2 PHYs". the current code however only calls these for the >> first PHY (leaving the others in reset mode = disabled). > > argh, good point. In that case, we need to figure out the best way to > pass all these handles to xHCI-plat OK, I assume that we want to let xHCI-plat manage the PHYs in the future instead of doing this in dwc3 (dwc3 may have to pass these to xHCI-plat, but it should not do the logic on it's own)? >>>>>>>> Then vendor kernel sources (a 3.14 kernel) are adding the resets for >>>>>>>> GUSB2PHYCFG([1-3]) in dwc3_core_soft_reset(). >>>>>>> >>>>>>> That shouldn't be necessary, actually. If it is, it means the HW was >>>>>>> poorly integrated. In that case, we _can_ add the other resets, but I >>>>>>> need confirmation that they are needed by means of a public errata >>>>>>> document. >>>>>>> >>>>>>>> A mainline 4.9+(Meson GXL USB PHY patches + dwc3/xhci-plat DMA patches >>>>>>>> from linux-usb) kernel works fine even with just applying the reset to >>>>>>>> GUSB2PHYCFG(0). >>>>>>> >>>>>>> there you go >>>>>> does that mean that the reset of GUSB2PHYCFG(0) (which is part of the >>>>>> current dwc3 code in dwc3_phy_setup) is done only because of the >>>>>> quirks/erratas? in other words: do you mean that one would not have to >>>>>> reset GUSB2PHYCFG(0) if there were no erratas? >>>>> >>>>> no, it's done for peripheral configuration of dwc3. Look at the code >>>>> more carefully: >>>> sorry for the confusion - the word "reset" should be "configuration". >>>> The function I am looking at is dwc3_phy_setup(): apart from toggling >>>> some "errata bits" it also configures the PHY modes. I am wondering if >>>> I need to do this setup (DWC3_GUSB2PHYCFG_ULPI_UTMI and >>>> DWC3_GUSB2PHYCFG_PHYIF_MASK related bits) not only for the *first* >>>> port ("DWC3_GUSB2PHYCFG(0)") but also for the "other" ports (index 1 >>>> and 2 in above case, where the roothub has 3 ports) >>> >>> Ideally, that should've been set at coreConsultant (
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Mon, Jan 9, 2017 at 1:39 PM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: > > [snip] > >>>>> true. But even so, that PHY handle is only needed for devices which >>>>> weren't properly configured at coreConsultant time. >>>> I don't understand that - there are two separate modules involved >>>> here: 1. the dwc3 IP block 2. Amlogic's own USB2 PHYs (they did not >>>> choose Synopsys DesignWare PHYs) >>>> (some background info: the USB2 PHYs are in "reset mode" by default) >>>> So even if the dwc3 IP block is configured correctly at coreConsultant >>>> time we still need to configure the PHYs. From "USB controller driver" >>>> (could be dwc3, or some generic hcd.c code, etc.) this means that >>>> phy_init() and phy_power_on() needs to be called for each of the three >>>> "Amlogic USB2 PHYs". the current code however only calls these for the >>>> first PHY (leaving the others in reset mode = disabled). >>> >>> argh, good point. In that case, we need to figure out the best way to >>> pass all these handles to xHCI-plat >> OK, I assume that we want to let xHCI-plat manage the PHYs in the >> future instead of doing this in dwc3 (dwc3 may have to pass these to >> xHCI-plat, but it should not do the logic on it's own)? > > perhaps. Maybe that mode check for dwc3 to bail out if mode == Host > should be done earlier. I guess your idea is to let xHCI-plat handle all phy_* logic when in host-mode? > [snip] > >>>> That is an explanation I'm fine with: we trust the (default) values >>>> which are in hardware until we have documentation that we need a >>>> quirk. I do not have access to Amlogic's documentation so I can't >>>> provide that - but we can probably leave it as it is as it "worked for >>>> me". >>> >>> awesome, so we need *only* phy_init() / phy_power_on() for the other >>> PHYs, right? >> correct! >> That made me curious and I found these: >> - ehci-platform.c has ehci_platform_power_{on,off} >> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> - ohci-platform.c has ohci_platform_power_{on,off} >> - (there are some more, for example ohci-exynos.c which are doing similar >> stuff) >> >> all of them are parsing the "phys" property and build an array of "struct >> phy*": >> of_count_phandle_with_args(np, "phys", "#phy-cells"); >> (afterwards they apply phy_{init,power_on,power_off,exit} in a loop on >> all of the PHYs) >> >> Maybe it would make sense to remove duplicated code from these drivers >> and create some generic functions from it. > > makes sense to me. The difficulty is really just making sure no > regressions are caused along the way. Also, DWC3 creates xHCI > platform-device manually, so we need to figure out a clean way of > passing along PHY phandles to xHCI. Another thing to consider is > dual-role implementations of dwc3. In such cases, peripheral side also > needs to control PHY[0]. indeed, regression-testing is probably the hardest part here! I think we already have the correct device_node (sysdev->of_node) available in xHCI-plat, see the comment above the sysdev variable assignment in xhci_plat_probe. The Amlogic GXL and GXM SoCs also support dual-role mode, but I think that is a bit more exotic: like you mentioned PHY[0] is used for dual-role mode. There is an additional USB3 PHY which also does mode-detection (in otg mode). when that USB3 PHY/mode-detection block detects that it has to switch to device mode it re-configures USB2 PHY[0] accordingly. however it doesn't stop here: after that it goes ahead and turns on an additional dwc2 (yes, dwc2, not dwc3!) IP block which is limited to "device" (peripheral) mode only. So on Amlogic GXL and GXM SoCs host-mode is handled by dwc3 while device-mode is handled by dwc2 >> that would result in a few functions (function names are just to >> illustrate my idea): >> - devm_get_all_phys_from_of_node() >> - all_phys_init_and_power_on() (phy_init and phy_power_on always seem >> to be used together) >> - all_phys_power_off_and_exit() (phy_power_off and phy_exit always >> seem to be used together) >> >> let me know what you think > > I like that, specially so if it's done generically and all HCD drivers > just use the same piece of code. great! how should we proceed: should I come up with a first RFC so we can then discuss issues/improvements based on that RFC patch? -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Documentation: dt: dwc3: add reference to the usb-xhci properties
dwc3 internally creates a usb-xhci device which means that all properties documented in usb-xhci.txt are supported as well. Signed-off-by: Martin Blumenstingl --- Documentation/devicetree/bindings/usb/dwc3.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index e3e6983288e3..f658f394c2d3 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -56,6 +56,10 @@ Optional properties: - tx-fifo-resize: determines if the FIFO *has* to be reallocated. + - in addition all properties from usb-xhci.txt from the current directory are + supported as well + + This is usually a subnode to DWC3 glue to which it is connected. dwc3@4a03 { -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 1/2] usb: host: add a generic platform USB roothub driver
Many SoC platforms have separate devices for the USB PHY which are registered through the generic PHY framework. These PHYs have to be enabled to make the USB controller actually work. They also have to be disabled again on shutdown/suspend. Currently (at least) the following HCI platform drivers are using custom code to obtain all PHYs via devicetree for the roothub/controller and disable/enable them when required: - ehci-platform.c has ehci_platform_power_{on,off} - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} - ohci-platform.c has ohci_platform_power_{on,off} These drivers are not using the generic devicetree USB device bindings yet which were only introduced recently (documentation is available in devicetree/bindings/usb/usb-device.txt). With this new driver the usb2-phy and usb3-phy can be specified directly in the child-node of the corresponding port of the roothub via devicetree. This can be extended by not just parsing PHYs (some of the other drivers listed above are for example also parsing a list of clocks as well) when required. Signed-off-by: Martin Blumenstingl --- .../devicetree/bindings/usb/usb-roothub.txt| 41 ++ drivers/usb/host/Kconfig | 3 + drivers/usb/host/Makefile | 2 + drivers/usb/host/platform-roothub.c| 146 + drivers/usb/host/platform-roothub.h| 14 ++ 5 files changed, 206 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt create mode 100644 drivers/usb/host/platform-roothub.c create mode 100644 drivers/usb/host/platform-roothub.h diff --git a/Documentation/devicetree/bindings/usb/usb-roothub.txt b/Documentation/devicetree/bindings/usb/usb-roothub.txt new file mode 100644 index ..96e152d3901c --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-roothub.txt @@ -0,0 +1,41 @@ +Generic USB root-hub Properties + +similar to the USB device bindings (documented in usb-device.txt from the +current directory) this provides support for configuring the root-hub. + +Required properties: +- compatible: should be at least one of "usb1d6b,3", "usb1d6b,2" +- reg: must be 0. +- address-cells: must be 1 +- size-cells: must be 0 +- a sub-node per port supports the following properties: + - reg: the port number on the root-hub (mandatory) + - phys: optional, from the *Generic PHY* bindings (mandatory needed when +phy-names is given) + - phy-names: optional, from the *Generic PHY* bindings; supported names +are "usb2-phy" or "usb3-phy" + +Example: + &usb1 { + #address-cells = <1>; + #size-cells = <0>; + + roothub@0 { + compatible = "usb1d6b,3", "usb1d6b,2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + port@1 { + reg = <1>; + usb-phy = <&usb2_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + }; + + port@2 { + reg = <2>; + usb-phy = <&usb2_phy2>, <&usb3_phy2>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; + } diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 6361fc739306..eb7009460322 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -797,6 +797,9 @@ config USB_HCD_SSB If unsure, say N. +config USB_PLATFORM_ROOTHUB + bool + config USB_HCD_TEST_MODE bool "HCD test mode support" ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 2644537b7bcf..1f1e19c4a826 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -31,6 +31,8 @@ ifneq ($(CONFIG_USB), ) obj-$(CONFIG_PCI) += pci-quirks.o endif +obj-$(CONFIG_USB_PLATFORM_ROOTHUB) += platform-roothub.o + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)+= ehci-platform.o diff --git a/drivers/usb/host/platform-roothub.c b/drivers/usb/host/platform-roothub.c new file mode 100644 index ..84837e42b006 --- /dev/null +++ b/drivers/usb/host/platform-roothub.c @@ -0,0 +1,146 @@ +/* + * platform roothub driver - a virtual PHY device which passes all phy_* + * function calls to multiple (actual) PHY devices. This is comes handy when + * initializing all PHYs on a root-hub (to keep them all in the same state). + * + * Copyright (C) 2017 Martin Blumenstingl + * + * This program
[RFC PATCH 2/2] usb: host: xhci: plat: integrate the platform-roothub
This enables the platform-roothub for the xhci-plat driver. This allows specifying a PHY for each port via devicetree. All PHYs will then be enabled/disabled by the platform-roothub driver. One example where this is required is the Amlogic GXL and GXM SoCs: They are using a dwc3 USB controller with up to three ports enabled on the internal roothub. Using only the top-level "phy" properties does not work here since one can only specify one "usb2-phy" and one "usb3-phy", while actually at least two "usb2-phy" have to be specified. Signed-off-by: Martin Blumenstingl --- Documentation/devicetree/bindings/usb/usb-xhci.txt | 7 drivers/usb/host/Kconfig | 1 + drivers/usb/host/xhci-plat.c | 37 -- drivers/usb/host/xhci.h| 3 ++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 0b7d8576001c..f05b2306ae19 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -28,6 +28,13 @@ Optional properties: - clocks: reference to a clock - usb3-lpm-capable: determines if platform is USB3 LPM capable +sub-nodes: +- optionally there can be a node for the root-hub, see usb-roothub.txt in the + current directory +- one or more nodes with reg 1-31 for each port to which a device is connected. + See usb-device.txt in the current directory for more information. + + Example: usb@f0931000 { compatible = "generic-xhci"; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index eb7009460322..b83b5aa89b76 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -36,6 +36,7 @@ config USB_XHCI_PCI config USB_XHCI_PLATFORM tristate "Generic xHCI driver for a platform device" select USB_XHCI_RCAR if ARCH_RENESAS + select USB_PLATFORM_ROOTHUB ---help--- Adds an xHCI host driver for a generic platform device, which provides a memory space and an irq. diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index e94bfd07e6c3..a0211cebac71 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -248,6 +248,12 @@ static int xhci_plat_probe(struct platform_device *pdev) goto disable_clk; } + xhci->platform_roothub = platform_roothub_init(sysdev); + if (IS_ERR(xhci->platform_roothub)) { + ret = PTR_ERR(xhci->platform_roothub); + goto disable_clk; + } + if (device_property_read_bool(sysdev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; @@ -266,10 +272,14 @@ static int xhci_plat_probe(struct platform_device *pdev) goto put_usb3_hcd; } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + ret = platform_roothub_power_on(xhci->platform_roothub); if (ret) goto disable_usb_phy; + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret) + goto disable_platform_roothub; + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto dealloc_usb2_hcd; @@ -280,6 +290,9 @@ static int xhci_plat_probe(struct platform_device *pdev) dealloc_usb2_hcd: usb_remove_hcd(hcd); +disable_platform_roothub: + platform_roothub_power_off(xhci->platform_roothub); + disable_usb_phy: usb_phy_shutdown(hcd->usb_phy); @@ -305,6 +318,8 @@ static int xhci_plat_remove(struct platform_device *dev) usb_remove_hcd(xhci->shared_hcd); usb_phy_shutdown(hcd->usb_phy); + platform_roothub_power_off(xhci->platform_roothub); + usb_remove_hcd(hcd); usb_put_hcd(xhci->shared_hcd); @@ -320,6 +335,7 @@ static int xhci_plat_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int ret; /* * xhci_suspend() needs `do_wakeup` to know whether host is allowed @@ -329,15 +345,30 @@ static int xhci_plat_suspend(struct device *dev) * reconsider this when xhci_plat_suspend enlarges its scope, e.g., * also applies to runtime suspend. */ - return xhci_suspend(xhci, device_may_wakeup(dev)); + ret = xhci_suspend(xhci, device_may_wakeup(dev)); + if (ret) + return ret; + + platform_roothub_power_off(xhci->platform_roothub); + + return 0; } static int xhci_plat_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int ret; - return xhci_resume(xhci, 0); + ret = platform_roothub_power
[RFC PATCH 0/2] initialize (multiple) PHYs in xhci-plat
This series is the outcome of a discussion with Felipe Balbi, see [0] and [1]. The quick-summary of this is: - dwc3 already takes one USB2 and one USB3 PHY and initializes these correct - some other HCI platform drivers (like ehci-platform.c, xhci-mtk.c and ohci-platform.c) do not have a limitation on the number of PHYs - they support one PHY per actual host port - Amlogic Meson GXL and GXM SoCs come with a dwc3 IP block which has two or three USB2 ports enabled on the internal root-hub. The SoCs also provide separate USB2 PHYs, one per port. All USB2 PHYs (which are internally "connected" to the dwc3 roothub) need to be powered on, otherwise USB devices cannot be enumerated (even if just one PHY is disabled and if the device is plugged into another, enabled port) In my first attempt to get USB supported on the GXL and GXM SoCs I tried to work-around the problem that I could not pass multiple PHYs to the dwc3 controller. This was rejected by Rob Herring (which was definitely the thing to do in my opinion), see [2] This series adds a new "platform-roothub". This can be configured through devicetree by passing a child-node with "reg = <0>" to the USB controller. Additionally there has to be a child-node for each port on the root-hub. Each of the child-nodes takes a "phys" and "phy-names" property. This allows modeling the root-hub in devicetree similar to the USB device binding (documented in devicetree/bindings/usb/usb-device.txt) This avoids and backwards-compatibility problems (which was a concern regardless of the solution, see [3]) since the binding for the root-hub was previously not specified (and we're not using the "phys" property of the controller, which might have served different purposes before, depending on the drivers). Additionally this integrates the new platform-roothub into xhci-plat.c which automatically enables it for the dwc3 driver (in host-mode). [0] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001945.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001947.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001818.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001948.html Martin Blumenstingl (2): usb: host: add a generic platform USB roothub driver usb: host: xhci: plat: integrate the platform-roothub .../devicetree/bindings/usb/usb-roothub.txt| 41 ++ Documentation/devicetree/bindings/usb/usb-xhci.txt | 7 + drivers/usb/host/Kconfig | 4 + drivers/usb/host/Makefile | 2 + drivers/usb/host/platform-roothub.c| 146 + drivers/usb/host/platform-roothub.h| 14 ++ drivers/usb/host/xhci-plat.c | 37 +- drivers/usb/host/xhci.h| 3 + 8 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt create mode 100644 drivers/usb/host/platform-roothub.c create mode 100644 drivers/usb/host/platform-roothub.h -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dwc3: add support for hardware with multiple ports on USB2 hub enabled
On Mon, Jan 9, 2017 at 2:05 PM, Felipe Balbi wrote: > > Hi, > > Martin Blumenstingl writes: >> On Mon, Jan 9, 2017 at 1:39 PM, Felipe Balbi >> wrote: >>> >>> Hi, >>> >>> Martin Blumenstingl writes: >>> >>> [snip] >>> >>>>>>> true. But even so, that PHY handle is only needed for devices which >>>>>>> weren't properly configured at coreConsultant time. >>>>>> I don't understand that - there are two separate modules involved >>>>>> here: 1. the dwc3 IP block 2. Amlogic's own USB2 PHYs (they did not >>>>>> choose Synopsys DesignWare PHYs) >>>>>> (some background info: the USB2 PHYs are in "reset mode" by default) >>>>>> So even if the dwc3 IP block is configured correctly at coreConsultant >>>>>> time we still need to configure the PHYs. From "USB controller driver" >>>>>> (could be dwc3, or some generic hcd.c code, etc.) this means that >>>>>> phy_init() and phy_power_on() needs to be called for each of the three >>>>>> "Amlogic USB2 PHYs". the current code however only calls these for the >>>>>> first PHY (leaving the others in reset mode = disabled). >>>>> >>>>> argh, good point. In that case, we need to figure out the best way to >>>>> pass all these handles to xHCI-plat >>>> OK, I assume that we want to let xHCI-plat manage the PHYs in the >>>> future instead of doing this in dwc3 (dwc3 may have to pass these to >>>> xHCI-plat, but it should not do the logic on it's own)? >>> >>> perhaps. Maybe that mode check for dwc3 to bail out if mode == Host >>> should be done earlier. >> I guess your idea is to let xHCI-plat handle all phy_* logic when in >> host-mode? > > right. I guess at the end of the day host-only dwc3 instances shouldn't > need dwc3.ko at all. Only peripheral-only and dual-role implementations > should rely on dwc3.ko. interesting thought, I guess that makes sense! > okay, in that case this is less important for you. We should really make > sure we don't cause problems for a future dual-role support. > >> like you mentioned PHY[0] is used for dual-role mode. There is an >> additional USB3 PHY which also does mode-detection (in otg mode). >> when that USB3 PHY/mode-detection block detects that it has to switch >> to device mode it re-configures USB2 PHY[0] accordingly. > > okay > >> however it doesn't stop here: after that it goes ahead and turns on an >> additional dwc2 (yes, dwc2, not dwc3!) IP block which is limited to >> "device" (peripheral) mode only. > > hehe, that's interesting :-) > >> So on Amlogic GXL and GXM SoCs host-mode is handled by dwc3 while >> device-mode is handled by dwc2 > > so you have host-only dwc3 (for all practical reasons, a standard xHCI) > and a peripheral only dwc2. Good to know. I wonder why it was done this > way. Maybe Amlogic didn't pay for dual-role dwc3 license? I don't know any details how this decision was made but licensing costs may have been the reason (it may also be the same reason why they chose to enable multiple USB ports on just one dwc3 instance). Please note that this is just pure speculation and no official information (as I don't have that)! >>>> that would result in a few functions (function names are just to >>>> illustrate my idea): >>>> - devm_get_all_phys_from_of_node() >>>> - all_phys_init_and_power_on() (phy_init and phy_power_on always seem >>>> to be used together) >>>> - all_phys_power_off_and_exit() (phy_power_off and phy_exit always >>>> seem to be used together) >>>> >>>> let me know what you think >>> >>> I like that, specially so if it's done generically and all HCD drivers >>> just use the same piece of code. >> great! >> how should we proceed: should I come up with a first RFC so we can >> then discuss issues/improvements based on that RFC patch? > > yeah, that's usually the way :-) I sent a first draft to the linux-usb list with the subject "[RFC PATCH 0/2] initialize (multiple) PHYs in xhci-plat" (which does not show up in the usual web-archives yet) Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] usb: host: add a generic platform USB roothub driver
Hi Rob, On Fri, Jan 13, 2017 at 9:08 PM, Rob Herring wrote: > On Wed, Jan 11, 2017 at 04:29:46PM +0100, Martin Blumenstingl wrote: >> Many SoC platforms have separate devices for the USB PHY which are >> registered through the generic PHY framework. These PHYs have to be >> enabled to make the USB controller actually work. They also have to be >> disabled again on shutdown/suspend. >> >> Currently (at least) the following HCI platform drivers are using custom >> code to obtain all PHYs via devicetree for the roothub/controller and >> disable/enable them when required: >> - ehci-platform.c has ehci_platform_power_{on,off} >> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> - ohci-platform.c has ohci_platform_power_{on,off} >> >> These drivers are not using the generic devicetree USB device bindings >> yet which were only introduced recently (documentation is available in >> devicetree/bindings/usb/usb-device.txt). >> With this new driver the usb2-phy and usb3-phy can be specified directly >> in the child-node of the corresponding port of the roothub via >> devicetree. This can be extended by not just parsing PHYs (some of the >> other drivers listed above are for example also parsing a list of clocks >> as well) when required. >> >> Signed-off-by: Martin Blumenstingl >> --- >> .../devicetree/bindings/usb/usb-roothub.txt| 41 ++ >> drivers/usb/host/Kconfig | 3 + >> drivers/usb/host/Makefile | 2 + >> drivers/usb/host/platform-roothub.c| 146 >> + >> drivers/usb/host/platform-roothub.h| 14 ++ >> 5 files changed, 206 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt >> create mode 100644 drivers/usb/host/platform-roothub.c >> create mode 100644 drivers/usb/host/platform-roothub.h >> >> diff --git a/Documentation/devicetree/bindings/usb/usb-roothub.txt >> b/Documentation/devicetree/bindings/usb/usb-roothub.txt >> new file mode 100644 >> index ..96e152d3901c >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/usb/usb-roothub.txt >> @@ -0,0 +1,41 @@ >> +Generic USB root-hub Properties >> + >> +similar to the USB device bindings (documented in usb-device.txt from the >> +current directory) this provides support for configuring the root-hub. >> + >> +Required properties: >> +- compatible: should be at least one of "usb1d6b,3", "usb1d6b,2" >> +- reg: must be 0. >> +- address-cells: must be 1 >> +- size-cells: must be 0 > >> +- a sub-node per port supports the following properties: > > Make this another section with required and optional sections. I can do that, but let's wait for the results if we want the PHYs to be specified at the grand-child or child level >> + - reg: the port number on the root-hub (mandatory) >> + - phys: optional, from the *Generic PHY* bindings (mandatory needed when >> +phy-names is given) >> + - phy-names: optional, from the *Generic PHY* bindings; supported names >> +are "usb2-phy" or "usb3-phy" >> + >> +Example: >> + &usb1 { >> + #address-cells = <1>; >> + #size-cells = <0>; >> + >> + roothub@0 { >> + compatible = "usb1d6b,3", "usb1d6b,2"; > > Is this discoverable? IIRC, we had decided that ports on the root hub > are just children of the USB controller node (rather than > grandchildren). Why does that not work? if I understand you correctly you are thinking of something like this: &usb1 { ...cells... port@1 { reg = <1>; phys = <&phy2> } port@2 { reg = <2>; phys = <&phy2> } } in that case we need a way to differentiate between "actual device at port 1" and "configuration for root-hub port 1". in that example I also cannot specify a compatible string since I don't know which device might be plugged into that port. >> + #address-cells = <1>; >> + #size-cells = <0>; >> + reg = <0>; >> + >> + port@1 { > > Wouldn't this normally be 0 and 1. This should probably be usb-port > rather than port to avoid OF graph overlap. the USB subsystem starts counting at 1, there can never be a "device with device-number 0" - so I think we should stay with 1 and 2 for a 2-port roothub
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman wrote: >> + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson_usb2_ops); >> + if (IS_ERR(phy)) { >> + dev_err(&pdev->dev, "failed to create PHY\n"); >> + return PTR_ERR(phy); >> + } >> + >> + if (usb_reset_refcnt++ == 0) { >> + ret = device_reset(&pdev->dev); >> + if (ret) { >> + dev_err(&phy->dev, "Failed to reset USB PHY\n"); >> + return ret; >> + } >> + } > > The ref count + reset here looks like something that could/should be > handled in a runtime PM callback. Unfortunately that doesn't work (as Jerome found out) because both PHYs are sharing the same reset line. So if the second PHY would call device_reset then it would also reset the first PHY! There's a comment above the declaration of usb_reset_refcnt which tries to explain this: "The PHYs are sharing a common reset line -> we are only allowed to reset once for all PHYs." Maybe I should move this comment to the "if (usb_reset_refcnt++ == 0) {" line to make it easier to see? Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Thu, Sep 8, 2016 at 10:53 PM, Ben Dooks wrote: > On 08/09/16 21:42, Kevin Hilman wrote: >> >> Ben Dooks writes: >> >>> On 08/09/16 20:52, Martin Blumenstingl wrote: >>>> >>>> On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman >>>> wrote: >>>>>> >>>>>> + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson_usb2_ops); >>>>>> + if (IS_ERR(phy)) { >>>>>> + dev_err(&pdev->dev, "failed to create PHY\n"); >>>>>> + return PTR_ERR(phy); >>>>>> + } >>>>>> + >>>>>> + if (usb_reset_refcnt++ == 0) { >>>>>> + ret = device_reset(&pdev->dev); >>>>>> + if (ret) { >>>>>> + dev_err(&phy->dev, "Failed to reset USB PHY\n"); >>>>>> + return ret; >>>>>> + } >>>>>> + } >>>>> >>>>> >>>>> The ref count + reset here looks like something that could/should be >>>>> handled in a runtime PM callback. >>>> >>>> Unfortunately that doesn't work (as Jerome found out) because both >>>> PHYs are sharing the same reset line. >>>> So if the second PHY would call device_reset then it would also reset >>>> the first PHY! >>>> >>>> There's a comment above the declaration of usb_reset_refcnt which >>>> tries to explain this: >>>> "The PHYs are sharing a common reset line -> we are only allowed to >>>> reset once for all PHYs." >>>> Maybe I should move this comment to the "if (usb_reset_refcnt++ == 0) >>>> {" line to make it easier to see? >>>> >>> >>> pm-runtime has refcounting in it. When one of the nodes turns on, >>> the pm-runtime will call your driver to say there is a user when >>> this first use turns up. >>> >>> If all the sub-phys turn off and drop their refcount then the driver >>> is called to say there are no more users and you can go to sleep. >> >> >> After a chat w/Martin on IRC, It turns out runtime PM wont help here. >> >> The reason is because there are physically two PHY devices[1]. Those 2 >> devices will be treated independely by runtime PM, and have separate >> use-counting, which means doing what I proposed would cause a reset to >> happen when either device was probed. >> >> So, I think it's OK as it is. > > > Surely you can do pm_runtime_get/put on the phy's parent platform > device and do it that way? could you please be more specific with that (do you mean pdev->dev.parent)? so we would use pm_runtime_{get_sync,put} with the parent, while we would still define the runtime_resume in our driver. I'd be happy if that works and we can remove that refcounting hack -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: > However, the problem with all of the solutions proposed (runtime PM ones > included) is that we're forcing a board-specific design issue (2 devices > sharing a reset line) into a driver that should not have any > board-specific assumptions in it. > > For example, if this driver is used on another platform where different > PHYs have different reset lines, then one of them (the unlucky one who > is not probed first) will never get reset. So any form of per-device > ref-counting is not a portable solution. maybe we should also consider Ben's solution: he played with the USB PHY on his Meson8b board. His approach was to have only one USB PHY driver instance which exposes two PHYs. The downside of this: the driver would have to know the offset of the PHYs (0x0 for the first PHY, 0x20 for the second), but we could handle the reset using runtime PM without any hacks. I checked the USB PHY reference driver: it seems that there will be a new USB PHY with the GXL/GXM SoCs. So maybe we could live with the assumption that the PHYs are at consecutive addresses. > I'm not sure yet how the reset framework is supposed to handle shared > reset lines, but that needs some investigation. I quick glance and it > seems that reset controllers can have shared lines, so that should be > investigated. unfortunately shared resets are not allowed to use reset_control_reset, see [0] [0] http://lxr.free-electrons.com/source/drivers/reset/core.c#L102 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Fri, Sep 9, 2016 at 7:21 PM, Ben Dooks wrote: > On 09/09/16 17:14, Martin Blumenstingl wrote: >> >> On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: >>> >>> However, the problem with all of the solutions proposed (runtime PM ones >>> included) is that we're forcing a board-specific design issue (2 devices >>> sharing a reset line) into a driver that should not have any >>> board-specific assumptions in it. >>> >>> For example, if this driver is used on another platform where different >>> PHYs have different reset lines, then one of them (the unlucky one who >>> is not probed first) will never get reset. So any form of per-device >>> ref-counting is not a portable solution. >> >> maybe we should also consider Ben's solution: he played with the USB >> PHY on his Meson8b board. His approach was to have only one USB PHY >> driver instance which exposes two PHYs. >> The downside of this: the driver would have to know the offset of the >> PHYs (0x0 for the first PHY, 0x20 for the second), but we could handle >> the reset using runtime PM without any hacks. >> >> I checked the USB PHY reference driver: it seems that there will be a >> new USB PHY with the GXL/GXM SoCs. >> So maybe we could live with the assumption that the PHYs are at >> consecutive addresses. >> >>> I'm not sure yet how the reset framework is supposed to handle shared >>> reset lines, but that needs some investigation. I quick glance and it >>> seems that reset controllers can have shared lines, so that should be >>> investigated. >> >> unfortunately shared resets are not allowed to use reset_control_reset, >> see [0] >> >> >> [0] http://lxr.free-electrons.com/source/drivers/reset/core.c#L102 > > > If we didn't have the shared reset, we'd have one of node per phy > and not have to have two sub-nodes... I don't think any other bits > of the PHY framework are shared. okay, sounds reasonable - so we should try to get this scenario supported through by the reset framework -> see my other mail. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: > Martin Blumenstingl writes: > >> On Thu, Sep 8, 2016 at 10:53 PM, Ben Dooks wrote: >>> On 08/09/16 21:42, Kevin Hilman wrote: >>>> >>>> Ben Dooks writes: >>>> >>>>> On 08/09/16 20:52, Martin Blumenstingl wrote: >>>>>> >>>>>> On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman >>>>>> wrote: >>>>>>>> >>>>>>>> + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson_usb2_ops); >>>>>>>> + if (IS_ERR(phy)) { >>>>>>>> + dev_err(&pdev->dev, "failed to create PHY\n"); >>>>>>>> + return PTR_ERR(phy); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (usb_reset_refcnt++ == 0) { >>>>>>>> + ret = device_reset(&pdev->dev); >>>>>>>> + if (ret) { >>>>>>>> + dev_err(&phy->dev, "Failed to reset USB PHY\n"); >>>>>>>> + return ret; >>>>>>>> + } >>>>>>>> + } >>>>>>> >>>>>>> >>>>>>> The ref count + reset here looks like something that could/should be >>>>>>> handled in a runtime PM callback. >>>>>> >>>>>> Unfortunately that doesn't work (as Jerome found out) because both >>>>>> PHYs are sharing the same reset line. >>>>>> So if the second PHY would call device_reset then it would also reset >>>>>> the first PHY! >>>>>> >>>>>> There's a comment above the declaration of usb_reset_refcnt which >>>>>> tries to explain this: >>>>>> "The PHYs are sharing a common reset line -> we are only allowed to >>>>>> reset once for all PHYs." >>>>>> Maybe I should move this comment to the "if (usb_reset_refcnt++ == 0) >>>>>> {" line to make it easier to see? >>>>>> >>>>> >>>>> pm-runtime has refcounting in it. When one of the nodes turns on, >>>>> the pm-runtime will call your driver to say there is a user when >>>>> this first use turns up. >>>>> >>>>> If all the sub-phys turn off and drop their refcount then the driver >>>>> is called to say there are no more users and you can go to sleep. >>>> >>>> >>>> After a chat w/Martin on IRC, It turns out runtime PM wont help here. >>>> >>>> The reason is because there are physically two PHY devices[1]. Those 2 >>>> devices will be treated independely by runtime PM, and have separate >>>> use-counting, which means doing what I proposed would cause a reset to >>>> happen when either device was probed. >>>> >>>> So, I think it's OK as it is. >>> >>> >>> Surely you can do pm_runtime_get/put on the phy's parent platform >>> device and do it that way? >> could you please be more specific with that (do you mean pdev->dev.parent)? >> so we would use pm_runtime_{get_sync,put} with the parent, while we >> would still define the runtime_resume in our driver. > > You'd also need to do get/put on the children, but yes, that's what Ben > is suggesting. > > However, the problem with all of the solutions proposed (runtime PM ones > included) is that we're forcing a board-specific design issue (2 devices > sharing a reset line) into a driver that should not have any > board-specific assumptions in it. > > For example, if this driver is used on another platform where different > PHYs have different reset lines, then one of them (the unlucky one who > is not probed first) will never get reset. So any form of per-device > ref-counting is not a portable solution. indeed, so in simple words we would need something like reset_control_do_once(rstc, RESET/ASSERT/DEASSERT) which would remember internally if any action has already been executed: if not it does a _reset, _assert or _deassert and otherwise it does nothing. > I'm not sure yet how the reset framework is supposed to handle shared > reset lines, but that needs some investigation. I quick glance and it > seems that reset controllers can have shared lines, so that should be > investigated. I added Philipp and Hans to this thread - maybe they can comment on this. To sum it up, our problem is: - there are two separate USB PHYs on Meson GXBB - both are sharing the same reset line (provided by the reset-meson driver) - during initialization of the PHYs we must only call reset_control_reset(rstc) once (if we do it for the first *and* second PHY then the first PHY gets confused once the second PHY uses the reset because the first PHY's state is reset as well) Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/6] usb: dwc2: add support for Meson8b and GXBB SoCs
From: Jerome Brunet Add compatible strings for amlogic Meson8b and GXBB SoCs with the corresponding configuration parameters. Signed-off-by: Jerome Brunet Signed-off-by: Martin Blumenstingl --- Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++ drivers/usb/dwc2/platform.c| 34 ++ 2 files changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 20a68bf..2c30a54 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -10,6 +10,8 @@ Required properties: - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; + - "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs; + - "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs; - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index fc6f525..8f7b34c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -181,6 +181,38 @@ static const struct dwc2_core_params params_ltq = { .hibernation= -1, }; +static const struct dwc2_core_params params_amlogic = { + .otg_cap= DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE, + .otg_ver= -1, + .dma_enable = 1, + .dma_desc_enable= 0, + .dma_desc_fs_enable = 0, + .speed = DWC2_SPEED_PARAM_HIGH, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 512, + .host_nperio_tx_fifo_size = 500, + .host_perio_tx_fifo_size= 500, + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = 16, + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = 1, + .ahbcfg = GAHBCFG_HBSTLEN_INCR8 << + GAHBCFG_HBSTLEN_SHIFT, + .uframe_sched = 0, + .external_id_pin_ctl= -1, + .hibernation= -1, +}; + /* * Check the dr_mode against the module configuration and hardware * capabilities. @@ -464,6 +496,8 @@ static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "lantiq,xrx200-usb", .data = ¶ms_ltq }, { .compatible = "snps,dwc2", .data = NULL }, { .compatible = "samsung,s3c6400-hsotg", .data = NULL}, + { .compatible = "amlogic,meson8b-usb", .data = ¶ms_amlogic }, + { .compatible = "amlogic,meson-gxbb-usb", .data = ¶ms_amlogic }, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/6] Documentation: dt-bindings: Add documentation for the Meson USB2 PHYs
Add the documentation for the bindings for the Meson8b and GXBB USB2 PHYs. Signed-off-by: Martin Blumenstingl --- .../devicetree/bindings/phy/meson-usb2-phy.txt | 27 ++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/meson-usb2-phy.txt diff --git a/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt b/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt new file mode 100644 index 000..9da5ea2 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt @@ -0,0 +1,27 @@ +* Amlogic USB2 PHY + +Required properties: +- compatible: Depending on the platform this should be one of: + "amlogic,meson8b-usb2-phy" + "amlogic,meson-gxbb-usb2-phy" +- reg: The base address and length of the registers +- #phys-cells: should be 0 (see phy-bindings.txt in this directory) +- clocks: phandle and clock identifier for the phy clocks +- clock-names: "usb_general" and "usb" + +Optional properties: +- resets: reference to the reset controller +- phy-supply: see phy-bindings.txt in this directory + + +Example: + +usb0_phy: usb_phy@0 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0x0 0x0 0x20>; + resets = <&reset RESET_USB_OTG>; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; + phy-supply = <&usb_vbus>; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/6] usb/phy: Add Amlogic Meson8b and GXBB USB support
This series adds initial support for the DWC2 USB controllers and Meson specific USB PHYs found in Meson8b and GXBB SoCs, which means: - new DWC2 bindings and platform specific core configuration - a PHY driver supporting the USB2 PHY on Meson8b and GXBB SoCs The first DWC2 controller is usually configured in OTG mode, whereas the second DWC2 controller is usually configured in host(-only) mode. Unfortunately no (public) datasheet is available and the reference PHY driver does not contain comments or speaking register name definitions. The nice people from BayLibre have already requested the datasheets (currently we can for example only guess that there is a mux clock inside the PHY, but we don't know it's parents). With this series both DWC2 controllers are configure in host mode, because the reference driver polls some of the PHY registers in OTG mode and then re-configures the dwc2 driver instance accordingly (if anyone is interested, this is the relevant piece of code: [0]). This seems good enough for the beginning though. Changes since v1: - the patch "clk: gxbb: expose USB clocks" was not sent again as it was already applied by Kevin Hilman (thanks!) - dropped (unnecessary) USB PHY bus from .dts - remove underscores from PHY node names in .dts - rename the dwc2 nodes in the .dts to usb (as per convention) - remove unused struct reset_control from phy_meson_usb2_priv - removed refcounting "reset" workaround and only specify the reset for the first PHY in the .dts (Jerome has reported that his boards don't need the explicit reset, while my board needs it). In addition (to make this work) the driver now treats the reset as optional - use the RESET_USB_OTG definition (from ) instead of a magic number in the .dts [0] https://github.com/150balbes/Amlogic_s905-kernel/blob/master/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.c#L642 Jerome Brunet (2): usb: dwc2: add support for Meson8b and GXBB SoCs ARM64: meson-gxbb-p20x: Enable USB Nodes Martin Blumenstingl (4): Documentation: dt-bindings: Add documentation for the Meson USB2 PHYs phy: meson: add USB2 PHY support for Meson8b and GXBB ARM64: meson-gxbb: add USB Nodes ARM64: meson-gxbb-vega-s95: Enable USB Nodes .../devicetree/bindings/phy/meson-usb2-phy.txt | 27 ++ Documentation/devicetree/bindings/usb/dwc2.txt | 2 + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 29 +++ .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 30 +++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi| 43 drivers/phy/Kconfig| 11 + drivers/phy/Makefile | 1 + drivers/phy/phy-meson-usb2.c | 280 + drivers/usb/dwc2/platform.c| 34 +++ 9 files changed, 457 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/meson-usb2-phy.txt create mode 100644 drivers/phy/phy-meson-usb2.c -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/6] phy: meson: add USB2 PHY support for Meson8b and GXBB
This is a new driver for the USB PHY found in Meson8b and GXBB SoCs. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet Tested-by: Kevin Hilman --- drivers/phy/Kconfig | 11 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-meson-usb2.c | 280 +++ 3 files changed, 292 insertions(+) create mode 100644 drivers/phy/phy-meson-usb2.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 19bff3a..6ad87ec 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -453,4 +453,15 @@ config PHY_NS2_PCIE help Enable this to support the Broadcom Northstar2 PCIe PHY. If unsure, say N. + +config PHY_MESON_USB2 + tristate "Meson USB2 PHY driver" + default ARCH_MESON + depends on OF && (ARCH_MESON || COMPILE_TEST) + select GENERIC_PHY + help + Enable this to support the Meson USB2 PHYs found in Meson8b + and GXBB SoCs. + If unsure, say N. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90ae198..dd507ac 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -56,3 +56,4 @@ obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o +obj-$(CONFIG_PHY_MESON_USB2) += phy-meson-usb2.o diff --git a/drivers/phy/phy-meson-usb2.c b/drivers/phy/phy-meson-usb2.c new file mode 100644 index 000..eece521 --- /dev/null +++ b/drivers/phy/phy-meson-usb2.c @@ -0,0 +1,280 @@ +/* + * Meson USB2 PHY driver + * + * Copyright (C) 2016 Martin Blumenstingl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_CONFIG 0x00 + #define REG_CONFIG_CLK_EN BIT(0) + #define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1) + #define REG_CONFIG_CLK_DIV_MASK GENMASK(10, 4) + #define REG_CONFIG_CLK_32k_ALTSEL BIT(15) + #define REG_CONFIG_TEST_TRIGBIT(31) + +#define REG_CTRL 0x04 + #define REG_CTRL_SOFT_PRST BIT(0) + #define REG_CTRL_SOFT_HRESETBIT(1) + #define REG_CTRL_SS_SCALEDOWN_MODE_MASK GENMASK(3, 2) + #define REG_CTRL_CLK_DET_RSTBIT(4) + #define REG_CTRL_INTR_SEL BIT(5) + #define REG_CTRL_CLK_DETECTED BIT(8) + #define REG_CTRL_SOF_SENT_RCVD_TGL BIT(9) + #define REG_CTRL_SOF_TOGGLE_OUT BIT(10) + #define REG_CTRL_POWER_ON_RESET BIT(15) + #define REG_CTRL_SLEEPM BIT(16) + #define REG_CTRL_TX_BITSTUFF_ENN_H BIT(17) + #define REG_CTRL_TX_BITSTUFF_ENNBIT(18) + #define REG_CTRL_COMMON_ON BIT(19) + #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) + #define REG_CTRL_REF_CLK_SEL_SHIFT 20 + #define REG_CTRL_FSEL_MASK GENMASK(24, 22) + #define REG_CTRL_FSEL_SHIFT 22 + #define REG_CTRL_PORT_RESET BIT(25) + #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) + +#define REG_ENDP_INTR 0x08 + +/* bits [31:26], [24:21] and [15:3] seem to be read-only */ +#define REG_ADP_BC 0x0c + #define REG_ADP_BC_VBUS_VLD_EXT_SEL BIT(0) + #define REG_ADP_BC_VBUS_VLD_EXT BIT(1) + #define REG_ADP_BC_OTG_DISABLE BIT(2) + #define REG_ADP_BC_ID_PULLUPBIT(3) + #define REG_ADP_BC_DRV_VBUS BIT(4) + #define REG_ADP_BC_ADP_PRB_EN BIT(5) + #define REG_ADP_BC_ADP_DISCHARGEBIT(6) + #define REG_ADP_BC_ADP_CHARGE BIT(7) + #define REG_ADP_BC_SESS_END BIT(8) + #define REG_ADP_BC_DEVICE_SESS_VLD BIT(9) + #define REG_ADP_BC_B_VALID BIT(10) + #define REG_ADP_BC_A_VALID BIT(11) + #define REG_ADP_BC_ID_DIG BIT(12) + #define REG_ADP_BC_VBUS_VALID BIT(13) + #define REG_ADP_BC_ADP_PROB
[PATCH v2 5/6] ARM64: meson-gxbb-p20x: Enable USB Nodes
From: Jerome Brunet Enable both gxbb USB controller and add a 5V regulator for the OTG port VBUS Signed-off-by: Jerome Brunet --- arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 29 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index ce105fe..4493bce 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -93,6 +93,18 @@ compatible = "mmc-pwrseq-emmc"; reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; }; + + usb_vbus: regulator-usb0-vbus { + compatible = "regulator-fixed"; + + regulator-name = "USB0_VBUS"; + + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + + gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; /* This UART is brought out to the DB9 connector */ @@ -149,3 +161,20 @@ vmmc-supply = <&vcc_3v3>; vmmcq-sumpply = <&vddio_boot>; }; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_vbus>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/6] ARM64: meson-gxbb: add USB Nodes
Add the nodes for the dwc2 USB controller and the related USB PHYs. Currently we force usb0 to host mode because OTG is currently not working in our PHY driver. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 43 + 1 file changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 2e8a3d9..30a8661 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -151,6 +151,25 @@ #size-cells = <2>; ranges; + usb0_phy: phy@c000 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0xc000 0x0 0x20>; + resets = <&reset RESET_USB_OTG>; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; + status = "disabled"; + }; + + usb1_phy: phy@c020 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0xc020 0x0 0x20>; + clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>; + clock-names = "usb_general", "usb"; + status = "disabled"; + }; + cbus: cbus@c110 { compatible = "simple-bus"; reg = <0x0 0xc110 0x0 0x10>; @@ -496,6 +515,30 @@ }; }; + usb0: usb@c900 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; + reg = <0x0 0xc900 0x0 0x4>; + interrupts = ; + clocks = <&clkc CLKID_USB0_DDR_BRIDGE>; + clock-names = "otg"; + phys = <&usb0_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; + status = "disabled"; + }; + + usb1: usb@c910 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; + reg = <0x0 0xc910 0x0 0x4>; + interrupts = ; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; + clock-names = "otg"; + phys = <&usb1_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; + status = "disabled"; + }; + ethmac: ethernet@c941 { compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac"; reg = <0x0 0xc941 0x0 0x1 -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 6/6] ARM64: meson-gxbb-vega-s95: Enable USB Nodes
Enable both gxbb USB controller and add a 5V regulator for the OTG port VBUS Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 30 ++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index 463185d..bad32e6 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -77,6 +77,19 @@ compatible = "mmc-pwrseq-emmc"; reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; }; + + usb_vbus: regulator-usb0-vbus { + compatible = "regulator-fixed"; + + regulator-name = "USB0_VBUS"; + + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + + gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; &uart_AO { @@ -133,3 +146,20 @@ vmmc-supply = <&vcc_3v3>; vmmcq-sumpply = <&vcc_1v8>; }; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_vbus>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Fri, Sep 9, 2016 at 10:36 PM, Martin Blumenstingl wrote: > On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: >> Martin Blumenstingl writes: >> >>> On Thu, Sep 8, 2016 at 10:53 PM, Ben Dooks >>> wrote: >>>> On 08/09/16 21:42, Kevin Hilman wrote: >>>>> >>>>> Ben Dooks writes: >>>>> >>>>>> On 08/09/16 20:52, Martin Blumenstingl wrote: >>>>>>> >>>>>>> On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman >>>>>>> wrote: >>>>>>>>> >>>>>>>>> + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson_usb2_ops); >>>>>>>>> + if (IS_ERR(phy)) { >>>>>>>>> + dev_err(&pdev->dev, "failed to create PHY\n"); >>>>>>>>> + return PTR_ERR(phy); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + if (usb_reset_refcnt++ == 0) { >>>>>>>>> + ret = device_reset(&pdev->dev); >>>>>>>>> + if (ret) { >>>>>>>>> + dev_err(&phy->dev, "Failed to reset USB PHY\n"); >>>>>>>>> + return ret; >>>>>>>>> + } >>>>>>>>> + } >>>>>>>> >>>>>>>> >>>>>>>> The ref count + reset here looks like something that could/should be >>>>>>>> handled in a runtime PM callback. >>>>>>> >>>>>>> Unfortunately that doesn't work (as Jerome found out) because both >>>>>>> PHYs are sharing the same reset line. >>>>>>> So if the second PHY would call device_reset then it would also reset >>>>>>> the first PHY! >>>>>>> >>>>>>> There's a comment above the declaration of usb_reset_refcnt which >>>>>>> tries to explain this: >>>>>>> "The PHYs are sharing a common reset line -> we are only allowed to >>>>>>> reset once for all PHYs." >>>>>>> Maybe I should move this comment to the "if (usb_reset_refcnt++ == 0) >>>>>>> {" line to make it easier to see? >>>>>>> >>>>>> >>>>>> pm-runtime has refcounting in it. When one of the nodes turns on, >>>>>> the pm-runtime will call your driver to say there is a user when >>>>>> this first use turns up. >>>>>> >>>>>> If all the sub-phys turn off and drop their refcount then the driver >>>>>> is called to say there are no more users and you can go to sleep. >>>>> >>>>> >>>>> After a chat w/Martin on IRC, It turns out runtime PM wont help here. >>>>> >>>>> The reason is because there are physically two PHY devices[1]. Those 2 >>>>> devices will be treated independely by runtime PM, and have separate >>>>> use-counting, which means doing what I proposed would cause a reset to >>>>> happen when either device was probed. >>>>> >>>>> So, I think it's OK as it is. >>>> >>>> >>>> Surely you can do pm_runtime_get/put on the phy's parent platform >>>> device and do it that way? >>> could you please be more specific with that (do you mean pdev->dev.parent)? >>> so we would use pm_runtime_{get_sync,put} with the parent, while we >>> would still define the runtime_resume in our driver. >> >> You'd also need to do get/put on the children, but yes, that's what Ben >> is suggesting. >> >> However, the problem with all of the solutions proposed (runtime PM ones >> included) is that we're forcing a board-specific design issue (2 devices >> sharing a reset line) into a driver that should not have any >> board-specific assumptions in it. >> >> For example, if this driver is used on another platform where different >> PHYs have different reset lines, then one of them (the unlucky one who >> is not probed first) will never get reset. So any form of per-device >> ref-counting is not a portable solution. > indeed, so in simple words we would need something like > reset_control_do_once(rstc, RESET/ASSERT/DEASSERT) which would > remember internally if any action has already been executed: if not it > does a _reset, _assert or _deassert and otherwise it does nothing. for now I've implemented something less hacky: I made the reset optional and only specified it for phy0. During Jerome's tests the reset was not needed, while on my board it's required to bring both PHYs up. Additionally the USB PHY reference driver does not have any reset logic for newer SoCs (GXL), so making the reset optional doesn't sound that bad to me. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
Hi Philipp, On Tue, Sep 13, 2016 at 5:28 PM, Philipp Zabel wrote: > Hi Martin, > > Am Freitag, den 09.09.2016, 22:36 +0200 schrieb Martin Blumenstingl: >> On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: >> > Martin Blumenstingl writes: >> > >> >> On Thu, Sep 8, 2016 at 10:53 PM, Ben Dooks >> >> wrote: >> >>> On 08/09/16 21:42, Kevin Hilman wrote: >> >>>> >> >>>> Ben Dooks writes: >> >>>> >> >>>>> On 08/09/16 20:52, Martin Blumenstingl wrote: >> >>>>>> >> >>>>>> On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman >> >>>>>> wrote: >> >>>>>>>> >> >>>>>>>> + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson_usb2_ops); >> >>>>>>>> + if (IS_ERR(phy)) { >> >>>>>>>> + dev_err(&pdev->dev, "failed to create PHY\n"); >> >>>>>>>> + return PTR_ERR(phy); >> >>>>>>>> + } >> >>>>>>>> + >> >>>>>>>> + if (usb_reset_refcnt++ == 0) { >> >>>>>>>> + ret = device_reset(&pdev->dev); >> >>>>>>>> + if (ret) { >> >>>>>>>> + dev_err(&phy->dev, "Failed to reset USB >> >>>>>>>> PHY\n"); >> >>>>>>>> + return ret; >> >>>>>>>> + } >> >>>>>>>> + } >> >>>>>>> >> >>>>>>> >> >>>>>>> The ref count + reset here looks like something that could/should be >> >>>>>>> handled in a runtime PM callback. >> >>>>>> >> >>>>>> Unfortunately that doesn't work (as Jerome found out) because both >> >>>>>> PHYs are sharing the same reset line. >> >>>>>> So if the second PHY would call device_reset then it would also reset >> >>>>>> the first PHY! >> >>>>>> >> >>>>>> There's a comment above the declaration of usb_reset_refcnt which >> >>>>>> tries to explain this: >> >>>>>> "The PHYs are sharing a common reset line -> we are only allowed to >> >>>>>> reset once for all PHYs." >> >>>>>> Maybe I should move this comment to the "if (usb_reset_refcnt++ == 0) >> >>>>>> {" line to make it easier to see? >> >>>>>> >> >>>>> >> >>>>> pm-runtime has refcounting in it. When one of the nodes turns on, >> >>>>> the pm-runtime will call your driver to say there is a user when >> >>>>> this first use turns up. >> >>>>> >> >>>>> If all the sub-phys turn off and drop their refcount then the driver >> >>>>> is called to say there are no more users and you can go to sleep. >> >>>> >> >>>> >> >>>> After a chat w/Martin on IRC, It turns out runtime PM wont help here. >> >>>> >> >>>> The reason is because there are physically two PHY devices[1]. Those 2 >> >>>> devices will be treated independely by runtime PM, and have separate >> >>>> use-counting, which means doing what I proposed would cause a reset to >> >>>> happen when either device was probed. >> >>>> >> >>>> So, I think it's OK as it is. >> >>> >> >>> >> >>> Surely you can do pm_runtime_get/put on the phy's parent platform >> >>> device and do it that way? >> >> could you please be more specific with that (do you mean >> >> pdev->dev.parent)? >> >> so we would use pm_runtime_{get_sync,put} with the parent, while we >> >> would still define the runtime_resume in our driver. >> > >> > You'd also need to do get/put on the children, but yes, that's what Ben >> > is suggesting. >> > >> > However, the problem with all of the solutions proposed (runtime PM ones >> > included) is that we're forcing a board-specific design issue (2 devices >
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Wed, Sep 14, 2016 at 10:37 AM, Philipp Zabel wrote: > Am Dienstag, den 13.09.2016, 17:59 -0700 schrieb Kevin Hilman: >> Martin Blumenstingl writes: >> >> > On Tue, Sep 13, 2016 at 5:28 PM, Philipp Zabel >> > wrote: >> >> [...] >> >> >>> I added Philipp and Hans to this thread - maybe they can comment on this. >> >>> To sum it up, our problem is: >> >>> - there are two separate USB PHYs on Meson GXBB >> >>> - both are sharing the same reset line (provided by the reset-meson >> >>> driver) >> >>> - during initialization of the PHYs we must only call >> >>> reset_control_reset(rstc) once (if we do it for the first *and* second >> >>> PHY then the first PHY gets confused once the second PHY uses the >> >>> reset because the first PHY's state is reset as well) >> >> >> >> If you have an initially asserted reset line and you can enable the >> >> first module by deasserting the reset via reset_control_deassert (and >> >> reset_control_assert to signal when the module may be disabled again >> >> after use), shared resets are for you. >> >> >> >> If you need a reset pulse or have no direct control over the reset line, >> >> (device_reset), the reset framework currently has no solution for this. >> >> The ugly thing about reset_control_once would be that it can't re-reset >> >> modules when unloading and reloading driver modules. >> > >> > The corresponding reset driver in question is reset-meson, which only >> > implements reset (assert/deassert are not implemented). However, I >> > don't know if this is due to hardware design. >> > I think the hardware implements the latter, but maybe Neil can give >> > more information here (I currently don't have access to my board so I >> > cannot test how the hardware actually behaves). >> >> It's implemented that way because the hardware only supports a reset >> pulse. > > Would it be possible to bring down both PHYs drivers, pull the reset > line once, and then bring the drivers back up again? I guess that this is the rmmod case: I haven't tested it yet but that should work (even with the current code and .dts) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Wed, Sep 14, 2016 at 10:37 AM, Philipp Zabel wrote: > Am Dienstag, den 13.09.2016, 20:38 +0200 schrieb Martin Blumenstingl: >> Hi Philipp, >> >> On Tue, Sep 13, 2016 at 5:28 PM, Philipp Zabel >> wrote: >> > Hi Martin, >> > >> > Am Freitag, den 09.09.2016, 22:36 +0200 schrieb Martin Blumenstingl: >> >> On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: >> >> > Martin Blumenstingl writes: >> >> > >> >> >> On Thu, Sep 8, 2016 at 10:53 PM, Ben Dooks >> >> >> wrote: >> >> >>> On 08/09/16 21:42, Kevin Hilman wrote: >> >> >>>> >> >> >>>> Ben Dooks writes: >> >> >>>> >> >> >>>>> On 08/09/16 20:52, Martin Blumenstingl wrote: >> >> >>>>>> >> >> >>>>>> On Thu, Sep 8, 2016 at 9:35 PM, Kevin Hilman >> >> >>>>>> wrote: >> >> >>>>>>>> >> >> >>>>>>>> + phy = devm_phy_create(&pdev->dev, NULL, >> >> >>>>>>>> &phy_meson_usb2_ops); >> >> >>>>>>>> + if (IS_ERR(phy)) { >> >> >>>>>>>> + dev_err(&pdev->dev, "failed to create PHY\n"); >> >> >>>>>>>> + return PTR_ERR(phy); >> >> >>>>>>>> + } >> >> >>>>>>>> + >> >> >>>>>>>> + if (usb_reset_refcnt++ == 0) { >> >> >>>>>>>> + ret = device_reset(&pdev->dev); >> >> >>>>>>>> + if (ret) { >> >> >>>>>>>> + dev_err(&phy->dev, "Failed to reset USB >> >> >>>>>>>> PHY\n"); >> >> >>>>>>>> + return ret; >> >> >>>>>>>> + } >> >> >>>>>>>> + } >> >> >>>>>>> >> >> >>>>>>> >> >> >>>>>>> The ref count + reset here looks like something that could/should >> >> >>>>>>> be >> >> >>>>>>> handled in a runtime PM callback. >> >> >>>>>> >> >> >>>>>> Unfortunately that doesn't work (as Jerome found out) because both >> >> >>>>>> PHYs are sharing the same reset line. >> >> >>>>>> So if the second PHY would call device_reset then it would also >> >> >>>>>> reset >> >> >>>>>> the first PHY! >> >> >>>>>> >> >> >>>>>> There's a comment above the declaration of usb_reset_refcnt which >> >> >>>>>> tries to explain this: >> >> >>>>>> "The PHYs are sharing a common reset line -> we are only allowed to >> >> >>>>>> reset once for all PHYs." >> >> >>>>>> Maybe I should move this comment to the "if (usb_reset_refcnt++ == >> >> >>>>>> 0) >> >> >>>>>> {" line to make it easier to see? >> >> >>>>>> >> >> >>>>> >> >> >>>>> pm-runtime has refcounting in it. When one of the nodes turns on, >> >> >>>>> the pm-runtime will call your driver to say there is a user when >> >> >>>>> this first use turns up. >> >> >>>>> >> >> >>>>> If all the sub-phys turn off and drop their refcount then the driver >> >> >>>>> is called to say there are no more users and you can go to sleep. >> >> >>>> >> >> >>>> >> >> >>>> After a chat w/Martin on IRC, It turns out runtime PM wont help here. >> >> >>>> >> >> >>>> The reason is because there are physically two PHY devices[1]. >> >> >>>> Those 2 >> >> >>>> devices will be treated independely by runtime PM, and have separate >> >> >>>> use-counting, which means doing what I proposed would cause a reset &
Re: [PATCH v2 3/6] phy: meson: add USB2 PHY support for Meson8b and GXBB
On Sun, Sep 11, 2016 at 3:41 PM, Martin Blumenstingl wrote: > This is a new driver for the USB PHY found in Meson8b and GXBB SoCs. > > Signed-off-by: Martin Blumenstingl > Signed-off-by: Jerome Brunet > Tested-by: Kevin Hilman > --- > drivers/phy/Kconfig | 11 ++ > drivers/phy/Makefile | 1 + > drivers/phy/phy-meson-usb2.c | 280 > +++ > 3 files changed, 292 insertions(+) > create mode 100644 drivers/phy/phy-meson-usb2.c > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig > index 19bff3a..6ad87ec 100644 > --- a/drivers/phy/Kconfig > +++ b/drivers/phy/Kconfig > @@ -453,4 +453,15 @@ config PHY_NS2_PCIE > help > Enable this to support the Broadcom Northstar2 PCIe PHY. > If unsure, say N. > + > +config PHY_MESON_USB2 > + tristate "Meson USB2 PHY driver" > + default ARCH_MESON > + depends on OF && (ARCH_MESON || COMPILE_TEST) > + select GENERIC_PHY as pointed out by Arnd Bergmann (see [0]) this is missing a "select USB_COMMON", just like the PHY_SUN4I_USB and PHY_SUN9I_USB drivers as we use of_usb_get_dr_mode_by_phy() to get the mode of the USB controller (as the PHY needs special configuration for host-mode). I will send an update on Sunday. Regards, Martin [0] http://marc.info/?l=linux-usb&m=147386117604824&w=2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
Hi Kishon, On Fri, Sep 16, 2016 at 10:19 AM, Kishon Vijay Abraham I wrote: > Hi, > > On Friday 09 September 2016 09:44 PM, Martin Blumenstingl wrote: >> On Fri, Sep 9, 2016 at 5:33 PM, Kevin Hilman wrote: >>> However, the problem with all of the solutions proposed (runtime PM ones >>> included) is that we're forcing a board-specific design issue (2 devices >>> sharing a reset line) into a driver that should not have any >>> board-specific assumptions in it. >>> >>> For example, if this driver is used on another platform where different >>> PHYs have different reset lines, then one of them (the unlucky one who >>> is not probed first) will never get reset. So any form of per-device >>> ref-counting is not a portable solution. >> maybe we should also consider Ben's solution: he played with the USB >> PHY on his Meson8b board. His approach was to have only one USB PHY >> driver instance which exposes two PHYs. >> The downside of this: the driver would have to know the offset of the >> PHYs (0x0 for the first PHY, 0x20 for the second), but we could handle >> the reset using runtime PM without any hacks. > > I think the offset information can come from the devicetree too. The phy can > be > modeled something like below. > > usb-phys@c000 { > compatible = "amlogic,meson-gxbb-usb2-phy"; > reg = <0x0 0xc000 0x0 0x40>; > #address-cells = <2>; > #size-cells = <2>; > ranges = <0x0 0x0 0x0 0xc000 0x0 0x40>; > resets = <&reset 34>; > > usb0_phy: usb_phy@0 { > #phy-cells = <0>; > reg = <0x0 0x0 0x0 0x20>; > clocks = <&clkc CLKID_USB &clkc CLKID_USB0>; > clock-names = "usb_general", "usb"; > status = "disabled"; > }; > > usb1_phy: usb_phy@20 { > #phy-cells = <0>; > reg = <0x0 0x20 0x0 0x20>; > clocks = <&clkc CLKID_USB &clkc CLKID_USB1>; > clock-names = "usb_general", "usb"; > status = "disabled"; > }; > }; > > This way the driver will be probed only once (the reset can be done during > probe). The phy driver should scan the dt node and for every sub-node it > invokes phy_create? I'll recap what we have discussed so far (so you don't have to re-read the whole thread): The reference driver treats both USB PHYs as separate devices (the datasheet has no information about the PHYs though). The only "special" thing is the shared reset line -> together with Philipp Zabel (the reset framework maintainer) we decided to make reset_control_reset work for shared reset lines. That means we can keep the two PHYs as separate devices inside the .dts, while keeping everything else separate (just like the reference driver) Is this fine for you and Arnd? Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] clk: gxbb: expose USB clocks
USB0_DDR_BRIDGE and USB1_DDR_BRIDGE1 are needed for the related dwc2 usb controller. USB, USB0 and USB1 are needed for the PHYs. Expose these clocks to DT and comment out in clk driver. Signed-off-by: Jerome Brunet Signed-off-by: Martin Blumenstingl --- drivers/clk/meson/gxbb.h | 10 +- include/dt-bindings/clock/gxbb-clkc.h | 5 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 3606e875..c66df2d 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -218,12 +218,12 @@ #define CLKID_AIU47 #define CLKID_UART1 48 #define CLKID_G2D49 -#define CLKID_USB0 50 -#define CLKID_USB1 51 +/* CLKID_USB0 */ +/* CLKID_USB1 */ #define CLKID_RESET 52 #define CLKID_NAND 53 #define CLKID_DOS_PARSER 54 -#define CLKID_USB55 +/* CLKID_USB */ #define CLKID_VDIN1 56 #define CLKID_AHB_ARB0 57 #define CLKID_EFUSE 58 @@ -232,8 +232,8 @@ #define CLKID_AHB_CTRL_BUS 61 #define CLKID_HDMI_INTR_SYNC 62 #define CLKID_HDMI_PCLK 63 -#define CLKID_USB1_DDR_BRIDGE64 -#define CLKID_USB0_DDR_BRIDGE65 +/* CLKID_USB1_DDR_BRIDGE */ +/* CLKID_USB0_DDR_BRIDGE */ #define CLKID_MMC_PCLK 66 #define CLKID_DVIN 67 #define CLKID_UART2 68 diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index 244ea6e..a03463f 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -10,6 +10,11 @@ #define CLKID_CLK8112 #define CLKID_MPLL215 #define CLKID_ETH 36 +#define CLKID_USB0 50 +#define CLKID_USB1 51 +#define CLKID_USB 55 +#define CLKID_USB1_DDR_BRIDGE 64 +#define CLKID_USB0_DDR_BRIDGE 65 #define CLKID_SD_EMMC_A94 #define CLKID_SD_EMMC_B95 #define CLKID_SD_EMMC_C96 -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] usb: dwc2: add support for Meson8b and GXBB SoCs
From: Jerome Brunet Add compatible strings for amlogic Meson8b and GXBB SoCs with the corresponding configuration parameters. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++ drivers/usb/dwc2/platform.c| 34 ++ 2 files changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 20a68bf..2c30a54 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -10,6 +10,8 @@ Required properties: - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc; - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs; - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs; + - "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs; + - "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs; - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index fc6f525..8f7b34c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -181,6 +181,38 @@ static const struct dwc2_core_params params_ltq = { .hibernation= -1, }; +static const struct dwc2_core_params params_amlogic = { + .otg_cap= DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE, + .otg_ver= -1, + .dma_enable = 1, + .dma_desc_enable= 0, + .dma_desc_fs_enable = 0, + .speed = DWC2_SPEED_PARAM_HIGH, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 512, + .host_nperio_tx_fifo_size = 500, + .host_perio_tx_fifo_size= 500, + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = 16, + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = 1, + .ahbcfg = GAHBCFG_HBSTLEN_INCR8 << + GAHBCFG_HBSTLEN_SHIFT, + .uframe_sched = 0, + .external_id_pin_ctl= -1, + .hibernation= -1, +}; + /* * Check the dr_mode against the module configuration and hardware * capabilities. @@ -464,6 +496,8 @@ static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "lantiq,xrx200-usb", .data = ¶ms_ltq }, { .compatible = "snps,dwc2", .data = NULL }, { .compatible = "samsung,s3c6400-hsotg", .data = NULL}, + { .compatible = "amlogic,meson8b-usb", .data = ¶ms_amlogic }, + { .compatible = "amlogic,meson-gxbb-usb", .data = ¶ms_amlogic }, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] usb/phy: Add Amlogic Meson8b and GXBB USB support
This series adds initial support for the DWC2 USB controllers and Meson specific USB PHYs found in Meson8b and GXBB SoCs, which means: - new DWC2 bindings and platform specific core configuration - a PHY driver supporting the USB2 PHY on Meson8b and GXBB SoCs The first DWC2 controller is usually configured in OTG mode, whereas the second DWC2 controller is usually configured in host(-only) mode. Unfortunately no (public) datasheet is available and the reference PHY driver does not contain comments or speaking register name definitions. The nice people from BayLibre have already requested the datasheets (currently we can for example only guess that there is a mux clock inside the PHY, but we don't know it's parents). With this series both DWC2 controllers are configure in host mode, because the reference driver polls some of the PHY registers in OTG mode and then re-configures the dwc2 driver instance accordingly (if anyone is interested, this is the relevant piece of code: [0]). This seems good enough for the beginning though. [0] https://github.com/150balbes/Amlogic_s905-kernel/blob/master/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.c#L642 Jerome Brunet (2): usb: dwc2: add support for Meson8b and GXBB SoCs ARM64: meson-gxbb-p20x: Enable USB Nodes Martin Blumenstingl (5): clk: gxbb: expose USB clocks Documentation: dt-bindings: Add documentation for the Meson USB2 PHYs phy: meson: add USB2 PHY support for Meson8b and GXBB ARM64: meson-gxbb: add USB Nodes ARM64: meson-gxbb-vega-s95: Enable USB Nodes .../devicetree/bindings/phy/meson-usb2-phy.txt | 27 ++ Documentation/devicetree/bindings/usb/dwc2.txt | 2 + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 29 ++ .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 30 +++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi| 52 drivers/clk/meson/gxbb.h | 10 +- drivers/phy/Kconfig| 11 + drivers/phy/Makefile | 1 + drivers/phy/phy-meson-usb2.c | 299 + drivers/usb/dwc2/platform.c| 34 +++ include/dt-bindings/clock/gxbb-clkc.h | 5 + 11 files changed, 495 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/meson-usb2-phy.txt create mode 100644 drivers/phy/phy-meson-usb2.c -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] ARM64: meson-gxbb-p20x: Enable USB Nodes
From: Jerome Brunet Enable both gxbb USB controller and add a 5V regulator for the OTG port VBUS Signed-off-by: Jerome Brunet Signed-off-by: Martin Blumenstingl --- arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 29 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index ce105fe..4493bce 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -93,6 +93,18 @@ compatible = "mmc-pwrseq-emmc"; reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; }; + + usb_vbus: regulator-usb0-vbus { + compatible = "regulator-fixed"; + + regulator-name = "USB0_VBUS"; + + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + + gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; /* This UART is brought out to the DB9 connector */ @@ -149,3 +161,20 @@ vmmc-supply = <&vcc_3v3>; vmmcq-sumpply = <&vddio_boot>; }; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_vbus>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] ARM64: meson-gxbb: add USB Nodes
Add the nodes for the dwc2 USB controller and the related USB PHYs. Currently we force usb0 to host mode because OTG is currently not working in our PHY driver. Signed-off-by: Jerome Brunet Signed-off-by: Martin Blumenstingl --- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 52 + 1 file changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 2e8a3d9..02dfc54 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -151,6 +151,34 @@ #size-cells = <2>; ranges; + usb-phys@c000 { + compatible = "simple-bus"; + reg = <0x0 0xc000 0x0 0x40>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc000 0x0 0x40>; + + usb0_phy: usb_phy@0 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0x0 0x0 0x20>; + resets = <&reset 34>; + clocks = <&clkc CLKID_USB &clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; + status = "disabled"; + }; + + usb1_phy: usb_phy@20 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0x20 0x0 0x20>; + resets = <&reset 34>; + clocks = <&clkc CLKID_USB &clkc CLKID_USB1>; + clock-names = "usb_general", "usb"; + status = "disabled"; + }; + }; + cbus: cbus@c110 { compatible = "simple-bus"; reg = <0x0 0xc110 0x0 0x10>; @@ -496,6 +524,30 @@ }; }; + usb0: usb-controller@c900 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; + reg = <0x0 0xc900 0x0 0x4>; + interrupts = ; + clocks = <&clkc CLKID_USB0_DDR_BRIDGE>; + clock-names = "otg"; + phys = <&usb0_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; + status = "disabled"; + }; + + usb1: usb-controller@c910 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; + reg = <0x0 0xc910 0x0 0x4>; + interrupts = ; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; + clock-names = "otg"; + phys = <&usb1_phy>; + phy-names = "usb2-phy"; + dr_mode = "host"; + status = "disabled"; + }; + ethmac: ethernet@c941 { compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac"; reg = <0x0 0xc941 0x0 0x1 -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] phy: meson: add USB2 PHY support for Meson8b and GXBB
This is a new driver for the USB PHY found in Meson8b and GXBB SoCs. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/phy/Kconfig | 11 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-meson-usb2.c | 299 +++ 3 files changed, 311 insertions(+) create mode 100644 drivers/phy/phy-meson-usb2.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 19bff3a..6ad87ec 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -453,4 +453,15 @@ config PHY_NS2_PCIE help Enable this to support the Broadcom Northstar2 PCIe PHY. If unsure, say N. + +config PHY_MESON_USB2 + tristate "Meson USB2 PHY driver" + default ARCH_MESON + depends on OF && (ARCH_MESON || COMPILE_TEST) + select GENERIC_PHY + help + Enable this to support the Meson USB2 PHYs found in Meson8b + and GXBB SoCs. + If unsure, say N. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90ae198..dd507ac 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -56,3 +56,4 @@ obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o +obj-$(CONFIG_PHY_MESON_USB2) += phy-meson-usb2.o diff --git a/drivers/phy/phy-meson-usb2.c b/drivers/phy/phy-meson-usb2.c new file mode 100644 index 000..8cda138 --- /dev/null +++ b/drivers/phy/phy-meson-usb2.c @@ -0,0 +1,299 @@ +/* + * Meson USB2 PHY driver + * + * Copyright (C) 2016 Martin Blumenstingl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_CONFIG 0x00 + #define REG_CONFIG_CLK_EN BIT(0) + #define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1) + #define REG_CONFIG_CLK_DIV_MASK GENMASK(10, 4) + #define REG_CONFIG_CLK_32k_ALTSEL BIT(15) + #define REG_CONFIG_TEST_TRIGBIT(31) + +#define REG_CTRL 0x04 + #define REG_CTRL_SOFT_PRST BIT(0) + #define REG_CTRL_SOFT_HRESETBIT(1) + #define REG_CTRL_SS_SCALEDOWN_MODE_MASK GENMASK(3, 2) + #define REG_CTRL_CLK_DET_RSTBIT(4) + #define REG_CTRL_INTR_SEL BIT(5) + #define REG_CTRL_CLK_DETECTED BIT(8) + #define REG_CTRL_SOF_SENT_RCVD_TGL BIT(9) + #define REG_CTRL_SOF_TOGGLE_OUT BIT(10) + #define REG_CTRL_POWER_ON_RESET BIT(15) + #define REG_CTRL_SLEEPM BIT(16) + #define REG_CTRL_TX_BITSTUFF_ENN_H BIT(17) + #define REG_CTRL_TX_BITSTUFF_ENNBIT(18) + #define REG_CTRL_COMMON_ON BIT(19) + #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) + #define REG_CTRL_REF_CLK_SEL_SHIFT 20 + #define REG_CTRL_FSEL_MASK GENMASK(24, 22) + #define REG_CTRL_FSEL_SHIFT 22 + #define REG_CTRL_PORT_RESET BIT(25) + #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) + +#define REG_ENDP_INTR 0x08 + +/* bits [31:26], [24:21] and [15:3] seem to be read-only */ +#define REG_ADP_BC 0x0c + #define REG_ADP_BC_VBUS_VLD_EXT_SEL BIT(0) + #define REG_ADP_BC_VBUS_VLD_EXT BIT(1) + #define REG_ADP_BC_OTG_DISABLE BIT(2) + #define REG_ADP_BC_ID_PULLUPBIT(3) + #define REG_ADP_BC_DRV_VBUS BIT(4) + #define REG_ADP_BC_ADP_PRB_EN BIT(5) + #define REG_ADP_BC_ADP_DISCHARGEBIT(6) + #define REG_ADP_BC_ADP_CHARGE BIT(7) + #define REG_ADP_BC_SESS_END BIT(8) + #define REG_ADP_BC_DEVICE_SESS_VLD BIT(9) + #define REG_ADP_BC_B_VALID BIT(10) + #define REG_ADP_BC_A_VALID BIT(11) + #define REG_ADP_BC_ID_DIG BIT(12) + #define REG_ADP_BC_VBUS_VALID BIT(13) + #define REG_ADP_BC_ADP_PROBE
[PATCH 3/7] Documentation: dt-bindings: Add documentation for the Meson USB2 PHYs
Add the documentation for the bindings for the Meson8b and GXBB USB2 PHYs. Signed-off-by: Martin Blumenstingl --- .../devicetree/bindings/phy/meson-usb2-phy.txt | 27 ++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/meson-usb2-phy.txt diff --git a/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt b/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt new file mode 100644 index 000..662b537 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/meson-usb2-phy.txt @@ -0,0 +1,27 @@ +* Amlogic USB2 PHY + +Required properties: +- compatible: Depending on the platform this should be one of: + "amlogic,meson8b-usb2-phy" + "amlogic,meson-gxbb-usb2-phy" +- reg: The base address and length of the registers +- #phys-cells: should be 0 (see phy-bindings.txt in this directory) +- resets: reference to the reset controller +- clocks: phandle and clock identifier for the phy clocks +- clock-names: "usb_general" and "usb" + +Optional properties: +- phy-supply: see phy-bindings.txt in this directory + + +Example: + +usb0_phy: usb_phy@0 { + compatible = "amlogic,meson-gxbb-usb2-phy"; + #phy-cells = <0>; + reg = <0x0 0x0 0x0 0x20>; + resets = <&reset 34>; + clocks = <&clkc CLKID_USB &clkc CLKID_USB0>; + clock-names = "usb_general", "usb"; + phy-supply = <&usb_vbus>; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] ARM64: meson-gxbb-vega-s95: Enable USB Nodes
Enable both gxbb USB controller and add a 5V regulator for the OTG port VBUS Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 30 ++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index 463185d..bad32e6 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -77,6 +77,19 @@ compatible = "mmc-pwrseq-emmc"; reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; }; + + usb_vbus: regulator-usb0-vbus { + compatible = "regulator-fixed"; + + regulator-name = "USB0_VBUS"; + + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + + gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; &uart_AO { @@ -133,3 +146,20 @@ vmmc-supply = <&vcc_3v3>; vmmcq-sumpply = <&vcc_1v8>; }; + +&usb0_phy { + status = "okay"; + phy-supply = <&usb_vbus>; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/7] clk: gxbb: expose USB clocks
On Wed, Sep 7, 2016 at 2:33 AM, Stephen Boyd wrote: > On 09/04, Martin Blumenstingl wrote: >> USB0_DDR_BRIDGE and USB1_DDR_BRIDGE1 are needed for the related >> dwc2 usb controller. USB, USB0 and USB1 are needed for the PHYs. >> Expose these clocks to DT and comment out in clk driver. >> >> Signed-off-by: Jerome Brunet >> Signed-off-by: Martin Blumenstingl > > Is authorship correct on this patch? Did Jerome author it > instead? We (Jerome and I) have both worked on this patch, that's why you have two signed-off-by's. Or is this simply about the order (author = from address should be listed first)? Regards, Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] usb: host: add a generic platform USB roothub driver
Hi Rob, On Fri, Jan 13, 2017 at 9:21 PM, Martin Blumenstingl wrote: > Hi Rob, > > On Fri, Jan 13, 2017 at 9:08 PM, Rob Herring wrote: >> On Wed, Jan 11, 2017 at 04:29:46PM +0100, Martin Blumenstingl wrote: >>> Many SoC platforms have separate devices for the USB PHY which are >>> registered through the generic PHY framework. These PHYs have to be >>> enabled to make the USB controller actually work. They also have to be >>> disabled again on shutdown/suspend. >>> >>> Currently (at least) the following HCI platform drivers are using custom >>> code to obtain all PHYs via devicetree for the roothub/controller and >>> disable/enable them when required: >>> - ehci-platform.c has ehci_platform_power_{on,off} >>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >>> - ohci-platform.c has ohci_platform_power_{on,off} >>> >>> These drivers are not using the generic devicetree USB device bindings >>> yet which were only introduced recently (documentation is available in >>> devicetree/bindings/usb/usb-device.txt). >>> With this new driver the usb2-phy and usb3-phy can be specified directly >>> in the child-node of the corresponding port of the roothub via >>> devicetree. This can be extended by not just parsing PHYs (some of the >>> other drivers listed above are for example also parsing a list of clocks >>> as well) when required. >>> >>> Signed-off-by: Martin Blumenstingl >>> --- >>> .../devicetree/bindings/usb/usb-roothub.txt| 41 ++ >>> drivers/usb/host/Kconfig | 3 + >>> drivers/usb/host/Makefile | 2 + >>> drivers/usb/host/platform-roothub.c| 146 >>> + >>> drivers/usb/host/platform-roothub.h| 14 ++ >>> 5 files changed, 206 insertions(+) >>> create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt >>> create mode 100644 drivers/usb/host/platform-roothub.c >>> create mode 100644 drivers/usb/host/platform-roothub.h >>> >>> diff --git a/Documentation/devicetree/bindings/usb/usb-roothub.txt >>> b/Documentation/devicetree/bindings/usb/usb-roothub.txt >>> new file mode 100644 >>> index ..96e152d3901c >>> --- /dev/null >>> +++ b/Documentation/devicetree/bindings/usb/usb-roothub.txt >>> @@ -0,0 +1,41 @@ >>> +Generic USB root-hub Properties >>> + >>> +similar to the USB device bindings (documented in usb-device.txt from the >>> +current directory) this provides support for configuring the root-hub. >>> + >>> +Required properties: >>> +- compatible: should be at least one of "usb1d6b,3", "usb1d6b,2" >>> +- reg: must be 0. >>> +- address-cells: must be 1 >>> +- size-cells: must be 0 >> >>> +- a sub-node per port supports the following properties: >> >> Make this another section with required and optional sections. > I can do that, but let's wait for the results if we want the PHYs to > be specified at the grand-child or child level > >>> + - reg: the port number on the root-hub (mandatory) >>> + - phys: optional, from the *Generic PHY* bindings (mandatory needed when >>> +phy-names is given) >>> + - phy-names: optional, from the *Generic PHY* bindings; supported names >>> +are "usb2-phy" or "usb3-phy" >>> + >>> +Example: >>> + &usb1 { >>> + #address-cells = <1>; >>> + #size-cells = <0>; >>> + >>> + roothub@0 { >>> + compatible = "usb1d6b,3", "usb1d6b,2"; >> >> Is this discoverable? IIRC, we had decided that ports on the root hub >> are just children of the USB controller node (rather than >> grandchildren). Why does that not work? > if I understand you correctly you are thinking of something like this: > &usb1 { > ...cells... > > port@1 { > reg = <1>; > phys = <&phy2> > } > > port@2 { > reg = <2>; > phys = <&phy2> > } > } > > in that case we need a way to differentiate between "actual device at > port 1" and "configuration for root-hub port 1". > in that example I also cannot specify a compatible string since I > don't know which device might be plugged into that port. coul
Re: [PATCH v2 5/8] phy: amlogic: add Amlogic G12A USB2 PHY Driver
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: [...] > +#include > +#include > +#include > +#include > +#include > +#include > +#include there's a "regmap" include right above. this driver doesn't use syscon so this include can be dropped [...] > +static int phy_meson_g12a_usb2_exit(struct phy *phy) > +{ > + struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); > + > + return reset_control_reset(priv->reset); do you know whether we should reset_control_assert here instead of reset_control_reset? the probe function below already uses reset_control_deassert, so the current implementation is inconsistent. in v1 you replied with "Maybe it would be better, indeed." - if there's a reason why reset_control_assert doesn't work here then I would like to have a comment stating why Apart from these two this is looking good! Human readable BIT/GENMASK #defines for the register bits would be nice, but I'm not sure if you have the details to add these. Regards Martin
Re: [PATCH v2 6/8] phy: amlogic: Add Amlogic G12A USB3 + PCIE Combo PHY Driver
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: [...] > +static int phy_g12a_usb3_init(struct phy *phy) > +{ > + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); > + int data, ret; > + > + /* Switch PHY to USB3 */ > + regmap_update_bits(priv->regmap, PHY_R0, > + PHY_R0_PCIE_USB3_SWITCH, > + PHY_R0_PCIE_USB3_SWITCH); does this automatically clear PHY_R0_PCIE_POWER_STATE (in case the bootloader incorrectly set that)? [...] > +static int phy_g12a_usb3_pcie_init(struct phy *phy) > +{ > + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); > + int ret; > + > + ret = reset_control_reset(priv->reset); > + if (ret) > + return ret; > + > + if (priv->mode == PHY_TYPE_USB3) > + return phy_g12a_usb3_init(phy); > + > + /* Power UP PCIE */ > + regmap_update_bits(priv->regmap, PHY_R0, > + PHY_R0_PCIE_POWER_STATE, > + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c)); similar to my question above: does this automatically clear PHY_R0_PCIE_USB3_SWITCH (in case the bootloader incorrectly set that)? Apart from these two questions this looks good to me! Regards Martin
[PATCH] dt-bindings: usb: dwc2: document the vbus-supply property
Various boards have an external VBUS supply regulator. This regulator depends on the current mode of the controller which is defined as: - dr_mode set to either "host" or "peripheral" (fixed value) - dr_mode set to "otg", based on the OTG status the dwc2 controller internally switches between "host" and "peripheral" mode (selection happens at runtime) Based on the current mode the regulator has to be enabled or disabled: - host: provide power to the connected USB device, thus the regulator has to be enabled - peripheral: the host device to which the controller is connected provides power, thus the regulator has to be disabled Add the dt-bindings documentation for this property so .dts authors know that this property exists and how it behaves. Fixes: 531ef5ebea9639 ("usb: dwc2: add support for host mode external vbus supply") Signed-off-by: Martin Blumenstingl --- Documentation/devicetree/bindings/usb/dwc2.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 6dc3c4a34483..1e8a775a0e72 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -31,6 +31,10 @@ Refer to clk/clock-bindings.txt for generic clock consumer properties Optional properties: - phys: phy provider specifier - phy-names: shall be "usb2-phy" +- vbus-supply: reference to the VBUS regulator. Depending on the current mode + this is enabled (in "host" mode") or disabled (in "peripheral" mode). The + regulator is updated if the controller is configured in "otg" mode and the + status changes between "host" and "peripheral". Refer to phy/phy-bindings.txt for generic phy consumer properties - dr_mode: shall be one of "host", "peripheral" and "otg" Refer to usb/generic.txt -- 2.21.0
Re: [PATCH v2 4/8] dt-bindings: usb: dwc3: Add Amlogic G12A DWC3 Glue Bindings
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: > > Adds the bindings for the Amlogic G12A USB Glue HW. > > The Amlogic G12A SoC Family embeds 2 USB Controllers : > - a DWC3 IP configured as Host for USB2 and USB3 > - a DWC2 IP configured as Peripheral USB2 Only > > A glue connects these both controllers to 2 USB2 PHYs, > and optionnally to an USB3+PCIE Combo PHY shared with the PCIE controller. > > The Glue configures the UTMI 8bit interfaces for the USB2 PHYs, including > routing of the OTG PHY between the DWC3 and DWC2 controllers, and > setups the on-chip OTG mode selection for this PHY. > > The PHYs phandles are passed to the Glue node since the Glue controls the > interface with the PHY, not the DWC3 controller. > > Signed-off-by: Neil Armstrong Reviewed-by: Martin Blumenstingl [...] > + dwc3: usb@ff50 { > + compatible = "snps,dwc3"; > + reg = <0x0 0xff50 0x0 0x10>; > + interrupts = ; > + dr_mode = "host"; > + snps,dis_u2_susphy_quirk; > + snps,quirk-frame-length-adjustment; > + }; in v1 of the patch I asked whether we should pass the PHYs which are connected to the dwc3 controller here as well (instead of only passing them to the USBCTRL node). we can still do this later on, the important part is: USBCTRL interfaces with the PHYs -> that is already part of the binding. Regards Martin
Re: [PATCH] usb: host: xhci-plat: Prevent an abnormally restrictive PHY init skipping
Hello Miquel, On Tue, Mar 26, 2019 at 9:39 AM Miquel Raynal wrote: > > In the past, USB PHY handling has been moved in the HCD core. Some > host controller drivers needing more control of the PHYs, they have > been granted the freedom to handle themselves the PHY states and to > prevent the HCD core to do so in commit 4e88d4c08301 ("usb: add a flag > to skip PHY initialization to struct usb_hcd"). With this change, any > USB host controller could set the hcd->skip_phy_initialization flag so > that the HCD core would just skip the PHY initialization sequence. nit-pick: strictly speaking host controller drivers were able to skip the core's PHY initialization sequence by setting hcd->phy or hcd->usb_phy. My commit just made it easier to understand (at least for me) what's going on > However, in the USB subsystem, there are currently two entirely > different forms of PHY: one is called 'usb_phy' and is > USB-subsystem-wide, while there is also the generic and kernel-wide > 'phy' from the (recent) generic PHY framework. > > When the commit above was introduced, both type of PHYs where handled > by the HCD core. > > Later, commit bc40f5341741 ("USB: core: hcd: drop support for legacy > phys") removed the support for the former type of PHYs in the HCD > core. These 'usb_phy' are still present though, but managed from the > controller drivers only. Hence, setting the > hcd->skip_phy_initialization flag just because a 'usb_phy' is > initialized by a controller driver is a non-sense. > > For instance on Armada CP110, a 'usb_phy' is there to enable the power > supply to the USB host, while there is also a COMPHY block providing > SERDES lanes configuration that is referenced as a PHY from the common > PHY framework. arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts (using this as an example, because it's what I found first) could be changed to use the phy-supply property of the (recent) generic PHY framework. This is documented here: Documentation/devicetree/bindings/phy/phy-bindings.txt as far as I understand both, generic PHY's phy-supply and usb-nop-xceiv's vcc-supply are *always* enabling the supply when the PHY is enabled. for an OTG capable USB controller this may not be correct, because VBUS should only be provided in "host" mode, but not in "peripheral" mode. dwc2 has a special vbus-supply property for this (documentation is currently not reflecting this, but I sent a patch to fix it: [0]) I'm aware that this has nothing to do with your patch, I just wanted to let you know in case you didn't know about it yet (so you can judge for yourself whether another change somewhere is appropriate) > Right now, users of the xhci-plat.c driver either use a 'usb_phy' only > and do not care about the attempt of generic PHY initialization within > the HCD core (as there is none); or they use a single 'phy' and the > code flow does not pass through the block setting > hcd->skip_phy_initialization anyway. > > While there is not users of both PHY types at the same time, drop this > limitation from the xhci-plat.c driver. Note that the tegra driver > probably has the same limitation and could definitely benefit from a > similar change. > > Cc: Johan Hovold > Cc: Martin Blumenstingl > Signed-off-by: Miquel Raynal Acked-by: Martin Blumenstingl thank you very much for the patch and the detailed explanation! Martin [0] https://patchwork.kernel.org/patch/10841803/
Re: [PATCH] usb: host: xhci-plat: Prevent an abnormally restrictive PHY init skipping
Hi Miquel, On Fri, Mar 29, 2019 at 4:16 PM Miquel Raynal wrote: > > Hi Martin, > > Martin Blumenstingl wrote on Tue, > 26 Mar 2019 18:29:25 +0100: > > > Hello Miquel, > > > > On Tue, Mar 26, 2019 at 9:39 AM Miquel Raynal > > wrote: > > > > > > In the past, USB PHY handling has been moved in the HCD core. Some > > > host controller drivers needing more control of the PHYs, they have > > > been granted the freedom to handle themselves the PHY states and to > > > prevent the HCD core to do so in commit 4e88d4c08301 ("usb: add a flag > > > to skip PHY initialization to struct usb_hcd"). With this change, any > > > USB host controller could set the hcd->skip_phy_initialization flag so > > > that the HCD core would just skip the PHY initialization sequence. > > nit-pick: strictly speaking host controller drivers were able to skip > > the core's PHY initialization sequence by setting hcd->phy or > > hcd->usb_phy. > > Indeed! > > > My commit just made it easier to understand (at least > > for me) what's going on > > Actually it also had the effect to merge the two conditions > (having set either hcd->phy or hcd->usb_phy) in one bit of information > which, IMHO, had an impact thereafter. excellent catch - I haven't noticed that before > > > > > However, in the USB subsystem, there are currently two entirely > > > different forms of PHY: one is called 'usb_phy' and is > > > USB-subsystem-wide, while there is also the generic and kernel-wide > > > 'phy' from the (recent) generic PHY framework. > > > > > > When the commit above was introduced, both type of PHYs where handled > > > by the HCD core. > > > > > > Later, commit bc40f5341741 ("USB: core: hcd: drop support for legacy > > > phys") removed the support for the former type of PHYs in the HCD > > > core. These 'usb_phy' are still present though, but managed from the > > > controller drivers only. Hence, setting the > > > hcd->skip_phy_initialization flag just because a 'usb_phy' is > > > initialized by a controller driver is a non-sense. > > > > > > For instance on Armada CP110, a 'usb_phy' is there to enable the power > > > supply to the USB host, while there is also a COMPHY block providing > > > SERDES lanes configuration that is referenced as a PHY from the common > > > PHY framework. > > arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts (using this > > as an example, because it's what I found first) could be changed to > > use the phy-supply property of the (recent) generic PHY framework. > > This is documented here: > > Documentation/devicetree/bindings/phy/phy-bindings.txt > > > > as far as I understand both, generic PHY's phy-supply and > > usb-nop-xceiv's vcc-supply are *always* enabling the supply when the > > PHY is enabled. > > for an OTG capable USB controller this may not be correct, because > > VBUS should only be provided in "host" mode, but not in "peripheral" > > mode. > > dwc2 has a special vbus-supply property for this (documentation is > > currently not reflecting this, but I sent a patch to fix it: [0]) > > > > I'm aware that this has nothing to do with your patch, I just wanted > > to let you know in case you didn't know about it yet (so you can judge > > for yourself whether another change somewhere is appropriate) > > Actually this is really interesting! Thanks for sharing Rob's answer to > your thread. I think this patch still has a meaning but in the mean > time I will convert the usb-phy property to the common PHY framework > using (as Rob told you) a connector and a phy-supply attached to it. that seems like a good plan. the current patch should still be applied, shouldn't it? also can you please CC me on the connector patches (whenever they are ready, I want to see whether we have to update the Amlogic platforms as well) Regards Martin
Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hi Roger, On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros wrote: > +some TI folks > > Hi Martin, > > On 18/02/18 20:44, Martin Blumenstingl wrote: >> Many SoC platforms have separate devices for the USB PHY which are >> registered through the generic PHY framework. These PHYs have to be >> enabled to make the USB controller actually work. They also have to be >> disabled again on shutdown/suspend. >> >> Currently (at least) the following HCI platform drivers are using custom >> code to obtain all PHYs via devicetree for the roothub/controller and >> disable/enable them when required: >> - ehci-platform.c has ehci_platform_power_{on,off} >> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> - ohci-platform.c has ohci_platform_power_{on,off} >> >> With this new wrapper the USB PHYs can be specified directly in the >> USB controller's devicetree node (just like on the drivers listed >> above). This allows SoCs like the Amlogic Meson GXL family to operate >> correctly once this is wired up correctly. These SoCs use a dwc3 >> controller and require all USB PHYs to be initialized (if one of the USB >> PHYs it not initialized then none of USB port works at all). >> >> Signed-off-by: Martin Blumenstingl >> Tested-by: Yixun Lan >> Cc: Neil Armstrong >> Cc: Chunfeng Yun > > This patch is breaking low power cases on TI SoCs when USB is in host mode. > I'll explain why below. based on your explanation and reading the TI PHY drivers I am assuming that the affected SoCs are using the "phy-omap-usb2" driver >> --- >> drivers/usb/core/Makefile | 2 +- >> drivers/usb/core/phy.c| 158 >> ++ >> drivers/usb/core/phy.h| 7 ++ >> 3 files changed, 166 insertions(+), 1 deletion(-) >> create mode 100644 drivers/usb/core/phy.c >> create mode 100644 drivers/usb/core/phy.h >> >> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >> index 92c9cefb4317..18e874b0441e 100644 >> --- a/drivers/usb/core/Makefile >> +++ b/drivers/usb/core/Makefile >> @@ -6,7 +6,7 @@ >> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >> -usbcore-y += port.o >> +usbcore-y += phy.o port.o >> >> usbcore-$(CONFIG_OF) += of.o >> usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o >> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >> new file mode 100644 >> index ..09b7c43c0ea4 >> --- /dev/null >> +++ b/drivers/usb/core/phy.c >> @@ -0,0 +1,158 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * A wrapper for multiple PHYs which passes all phy_* function calls to >> + * multiple (actual) PHY devices. This is comes handy when initializing >> + * all PHYs on a HCD and to keep them all in the same state. >> + * >> + * Copyright (C) 2018 Martin Blumenstingl >> >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "phy.h" >> + >> +struct usb_phy_roothub { >> + struct phy *phy; >> + struct list_headlist; >> +}; >> + >> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >> +{ >> + struct usb_phy_roothub *roothub_entry; >> + >> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); >> + if (!roothub_entry) >> + return ERR_PTR(-ENOMEM); >> + >> + INIT_LIST_HEAD(&roothub_entry->list); >> + >> + return roothub_entry; >> +} >> + >> +static int usb_phy_roothub_add_phy(struct device *dev, int index, >> +struct list_head *list) >> +{ >> + struct usb_phy_roothub *roothub_entry; >> + struct phy *phy = devm_of_phy_get_by_index(dev, dev->of_node, index); >> + >> + if (IS_ERR_OR_NULL(phy)) { >> + if (!phy || PTR_ERR(phy) == -ENODEV) >> + return 0; >> + else >> + return PTR_ERR(phy); >> + } >> + >> + roothub_entry = usb_phy_roothub_alloc(dev); >> + if (IS_ERR(roothub_entry)) >> + return PTR_ERR(roothub_entry); >> + >> + roothub_entry->phy = phy; >> + >> + list_add_tail(&roothub_entry->list, list); >> + >> + return 0; >> +} >>
Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hi Roger, On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros wrote: > Hi, > > On 19/03/18 00:29, Martin Blumenstingl wrote: >> Hi Roger, >> >> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros wrote: >>> +some TI folks >>> >>> Hi Martin, >>> >>> On 18/02/18 20:44, Martin Blumenstingl wrote: >>>> Many SoC platforms have separate devices for the USB PHY which are >>>> registered through the generic PHY framework. These PHYs have to be >>>> enabled to make the USB controller actually work. They also have to be >>>> disabled again on shutdown/suspend. >>>> >>>> Currently (at least) the following HCI platform drivers are using custom >>>> code to obtain all PHYs via devicetree for the roothub/controller and >>>> disable/enable them when required: >>>> - ehci-platform.c has ehci_platform_power_{on,off} >>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >>>> - ohci-platform.c has ohci_platform_power_{on,off} >>>> >>>> With this new wrapper the USB PHYs can be specified directly in the >>>> USB controller's devicetree node (just like on the drivers listed >>>> above). This allows SoCs like the Amlogic Meson GXL family to operate >>>> correctly once this is wired up correctly. These SoCs use a dwc3 >>>> controller and require all USB PHYs to be initialized (if one of the USB >>>> PHYs it not initialized then none of USB port works at all). >>>> >>>> Signed-off-by: Martin Blumenstingl >>>> Tested-by: Yixun Lan >>>> Cc: Neil Armstrong >>>> Cc: Chunfeng Yun >>> >>> This patch is breaking low power cases on TI SoCs when USB is in host mode. >>> I'll explain why below. >> based on your explanation and reading the TI PHY drivers I am assuming >> that the affected SoCs are using the "phy-omap-usb2" driver >> > yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3" I missed that, thanks >>>> --- >>>> drivers/usb/core/Makefile | 2 +- >>>> drivers/usb/core/phy.c| 158 >>>> ++ >>>> drivers/usb/core/phy.h| 7 ++ >>>> 3 files changed, 166 insertions(+), 1 deletion(-) >>>> create mode 100644 drivers/usb/core/phy.c >>>> create mode 100644 drivers/usb/core/phy.h >>>> >>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >>>> index 92c9cefb4317..18e874b0441e 100644 >>>> --- a/drivers/usb/core/Makefile >>>> +++ b/drivers/usb/core/Makefile >>>> @@ -6,7 +6,7 @@ >>>> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >>>> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >>>> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >>>> -usbcore-y += port.o >>>> +usbcore-y += phy.o port.o >>>> >>>> usbcore-$(CONFIG_OF) += of.o >>>> usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o >>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >>>> new file mode 100644 >>>> index ..09b7c43c0ea4 >>>> --- /dev/null >>>> +++ b/drivers/usb/core/phy.c >>>> @@ -0,0 +1,158 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to >>>> + * multiple (actual) PHY devices. This is comes handy when initializing >>>> + * all PHYs on a HCD and to keep them all in the same state. >>>> + * >>>> + * Copyright (C) 2018 Martin Blumenstingl >>>> >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#include "phy.h" >>>> + >>>> +struct usb_phy_roothub { >>>> + struct phy *phy; >>>> + struct list_headlist; >>>> +}; >>>> + >>>> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >>>> +{ >>>> + struct usb_phy_roothub *roothub_entry; >>>> + >>>> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), >>>> GFP_KERNEL); >>>> + if (!roothub_entry) >>>> + return ERR_PTR(-ENOMEM); >&g
Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hello Kishon, On Tue, Mar 20, 2018 at 12:27 PM, Kishon Vijay Abraham I wrote: > Hi, > > On Monday 19 March 2018 09:42 PM, Martin Blumenstingl wrote: >> Hi Roger, >> >> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros wrote: >>> Hi, >>> >>> On 19/03/18 00:29, Martin Blumenstingl wrote: >>>> Hi Roger, >>>> >>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros wrote: >>>>> +some TI folks >>>>> >>>>> Hi Martin, >>>>> >>>>> On 18/02/18 20:44, Martin Blumenstingl wrote: >>>>>> Many SoC platforms have separate devices for the USB PHY which are >>>>>> registered through the generic PHY framework. These PHYs have to be >>>>>> enabled to make the USB controller actually work. They also have to be >>>>>> disabled again on shutdown/suspend. >>>>>> >>>>>> Currently (at least) the following HCI platform drivers are using custom >>>>>> code to obtain all PHYs via devicetree for the roothub/controller and >>>>>> disable/enable them when required: >>>>>> - ehci-platform.c has ehci_platform_power_{on,off} >>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >>>>>> - ohci-platform.c has ohci_platform_power_{on,off} >>>>>> >>>>>> With this new wrapper the USB PHYs can be specified directly in the >>>>>> USB controller's devicetree node (just like on the drivers listed >>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate >>>>>> correctly once this is wired up correctly. These SoCs use a dwc3 >>>>>> controller and require all USB PHYs to be initialized (if one of the USB >>>>>> PHYs it not initialized then none of USB port works at all). >>>>>> >>>>>> Signed-off-by: Martin Blumenstingl >>>>>> Tested-by: Yixun Lan >>>>>> Cc: Neil Armstrong >>>>>> Cc: Chunfeng Yun >>>>> >>>>> This patch is breaking low power cases on TI SoCs when USB is in host >>>>> mode. >>>>> I'll explain why below. >>>> based on your explanation and reading the TI PHY drivers I am assuming >>>> that the affected SoCs are using the "phy-omap-usb2" driver >>>> >>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3" >> I missed that, thanks >> >>>>>> --- >>>>>> drivers/usb/core/Makefile | 2 +- >>>>>> drivers/usb/core/phy.c| 158 >>>>>> ++ >>>>>> drivers/usb/core/phy.h| 7 ++ >>>>>> 3 files changed, 166 insertions(+), 1 deletion(-) >>>>>> create mode 100644 drivers/usb/core/phy.c >>>>>> create mode 100644 drivers/usb/core/phy.h >>>>>> >>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >>>>>> index 92c9cefb4317..18e874b0441e 100644 >>>>>> --- a/drivers/usb/core/Makefile >>>>>> +++ b/drivers/usb/core/Makefile >>>>>> @@ -6,7 +6,7 @@ >>>>>> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >>>>>> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >>>>>> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >>>>>> -usbcore-y += port.o >>>>>> +usbcore-y += phy.o port.o >>>>>> >>>>>> usbcore-$(CONFIG_OF) += of.o >>>>>> usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o >>>>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >>>>>> new file mode 100644 >>>>>> index ..09b7c43c0ea4 >>>>>> --- /dev/null >>>>>> +++ b/drivers/usb/core/phy.c >>>>>> @@ -0,0 +1,158 @@ >>>>>> +// SPDX-License-Identifier: GPL-2.0+ >>>>>> +/* >>>>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to >>>>>> + * multiple (actual) PHY devices. This is comes handy when initializing >>>>>> + * all PHYs on a HCD and to keep them all in the same state. >>>>>> + * >>>>>> + * Copyright (C) 2018 Martin Blumenstingl >>>>>> >&g
Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hi Roger, Hi Chunfeng, On Tue, Mar 20, 2018 at 1:04 PM, Chunfeng Yun wrote: > Hi Martin & Roger: > > On Mon, 2018-03-19 at 17:12 +0100, Martin Blumenstingl wrote: >> Hi Roger, >> >> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros wrote: >> > Hi, >> > >> > On 19/03/18 00:29, Martin Blumenstingl wrote: >> >> Hi Roger, >> >> >> >> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros wrote: >> >>> +some TI folks >> >>> >> >>> Hi Martin, >> >>> >> >>> On 18/02/18 20:44, Martin Blumenstingl wrote: >> >>>> Many SoC platforms have separate devices for the USB PHY which are >> >>>> registered through the generic PHY framework. These PHYs have to be >> >>>> enabled to make the USB controller actually work. They also have to be >> >>>> disabled again on shutdown/suspend. >> >>>> >> >>>> Currently (at least) the following HCI platform drivers are using custom >> >>>> code to obtain all PHYs via devicetree for the roothub/controller and >> >>>> disable/enable them when required: >> >>>> - ehci-platform.c has ehci_platform_power_{on,off} >> >>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> >>>> - ohci-platform.c has ohci_platform_power_{on,off} >> >>>> >> >>>> With this new wrapper the USB PHYs can be specified directly in the >> >>>> USB controller's devicetree node (just like on the drivers listed >> >>>> above). This allows SoCs like the Amlogic Meson GXL family to operate >> >>>> correctly once this is wired up correctly. These SoCs use a dwc3 >> >>>> controller and require all USB PHYs to be initialized (if one of the USB >> >>>> PHYs it not initialized then none of USB port works at all). >> >>>> >> >>>> Signed-off-by: Martin Blumenstingl >> >>>> Tested-by: Yixun Lan >> >>>> Cc: Neil Armstrong >> >>>> Cc: Chunfeng Yun >> >>> >> >>> This patch is breaking low power cases on TI SoCs when USB is in host >> >>> mode. >> >>> I'll explain why below. >> >> based on your explanation and reading the TI PHY drivers I am assuming >> >> that the affected SoCs are using the "phy-omap-usb2" driver >> >> >> > yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3" >> I missed that, thanks >> >> >>>> --- >> >>>> drivers/usb/core/Makefile | 2 +- >> >>>> drivers/usb/core/phy.c| 158 >> >>>> ++ >> >>>> drivers/usb/core/phy.h| 7 ++ >> >>>> 3 files changed, 166 insertions(+), 1 deletion(-) >> >>>> create mode 100644 drivers/usb/core/phy.c >> >>>> create mode 100644 drivers/usb/core/phy.h >> >>>> >> >>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >> >>>> index 92c9cefb4317..18e874b0441e 100644 >> >>>> --- a/drivers/usb/core/Makefile >> >>>> +++ b/drivers/usb/core/Makefile >> >>>> @@ -6,7 +6,7 @@ >> >>>> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >> >>>> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >> >>>> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >> >>>> -usbcore-y += port.o >> >>>> +usbcore-y += phy.o port.o >> >>>> >> >>>> usbcore-$(CONFIG_OF) += of.o >> >>>> usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o >> >>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >> >>>> new file mode 100644 >> >>>> index ..09b7c43c0ea4 >> >>>> --- /dev/null >> >>>> +++ b/drivers/usb/core/phy.c >> >>>> @@ -0,0 +1,158 @@ >> >>>> +// SPDX-License-Identifier: GPL-2.0+ >> >>>> +/* >> >>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to >> >>>> + * multiple (actual) PHY devices. This is comes handy when initializing >> >>>> + * all PHYs on a HCD and to keep them all in the same state. >> >>&g
Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hi Roger, On Wed, Mar 21, 2018 at 12:30 PM, Roger Quadros wrote: > Martin, > > On 21/03/18 00:01, Martin Blumenstingl wrote: >> Hi Roger, Hi Chunfeng, >> >> On Tue, Mar 20, 2018 at 1:04 PM, Chunfeng Yun >> wrote: >>> Hi Martin & Roger: >>> >>> On Mon, 2018-03-19 at 17:12 +0100, Martin Blumenstingl wrote: >>>> Hi Roger, >>>> >>>> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros wrote: >>>>> Hi, >>>>> >>>>> On 19/03/18 00:29, Martin Blumenstingl wrote: >>>>>> Hi Roger, >>>>>> >>>>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros wrote: >>>>>>> +some TI folks >>>>>>> >>>>>>> Hi Martin, >>>>>>> >>>>>>> On 18/02/18 20:44, Martin Blumenstingl wrote: >>>>>>>> Many SoC platforms have separate devices for the USB PHY which are >>>>>>>> registered through the generic PHY framework. These PHYs have to be >>>>>>>> enabled to make the USB controller actually work. They also have to be >>>>>>>> disabled again on shutdown/suspend. >>>>>>>> >>>>>>>> Currently (at least) the following HCI platform drivers are using >>>>>>>> custom >>>>>>>> code to obtain all PHYs via devicetree for the roothub/controller and >>>>>>>> disable/enable them when required: >>>>>>>> - ehci-platform.c has ehci_platform_power_{on,off} >>>>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >>>>>>>> - ohci-platform.c has ohci_platform_power_{on,off} >>>>>>>> >>>>>>>> With this new wrapper the USB PHYs can be specified directly in the >>>>>>>> USB controller's devicetree node (just like on the drivers listed >>>>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate >>>>>>>> correctly once this is wired up correctly. These SoCs use a dwc3 >>>>>>>> controller and require all USB PHYs to be initialized (if one of the >>>>>>>> USB >>>>>>>> PHYs it not initialized then none of USB port works at all). >>>>>>>> >>>>>>>> Signed-off-by: Martin Blumenstingl >>>>>>>> Tested-by: Yixun Lan >>>>>>>> Cc: Neil Armstrong >>>>>>>> Cc: Chunfeng Yun >>>>>>> >>>>>>> This patch is breaking low power cases on TI SoCs when USB is in host >>>>>>> mode. >>>>>>> I'll explain why below. >>>>>> based on your explanation and reading the TI PHY drivers I am assuming >>>>>> that the affected SoCs are using the "phy-omap-usb2" driver >>>>>> >>>>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3" >>>> I missed that, thanks >>>> >>>>>>>> --- >>>>>>>> drivers/usb/core/Makefile | 2 +- >>>>>>>> drivers/usb/core/phy.c| 158 >>>>>>>> ++ >>>>>>>> drivers/usb/core/phy.h| 7 ++ >>>>>>>> 3 files changed, 166 insertions(+), 1 deletion(-) >>>>>>>> create mode 100644 drivers/usb/core/phy.c >>>>>>>> create mode 100644 drivers/usb/core/phy.h >>>>>>>> >>>>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >>>>>>>> index 92c9cefb4317..18e874b0441e 100644 >>>>>>>> --- a/drivers/usb/core/Makefile >>>>>>>> +++ b/drivers/usb/core/Makefile >>>>>>>> @@ -6,7 +6,7 @@ >>>>>>>> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >>>>>>>> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >>>>>>>> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >>>>>>>> -usbcore-y += port.o >>>>>>>> +usbcore-y += phy.o port.o >>>>>>>> >>>>>>>> usbcore-$(CONFIG_OF) += of.o >>>>>>>> usbcore-$(CONFIG_USB_PCI)+= hcd-pci
[PATCH usb-next v1] usb: core: phy: fix return value of usb_phy_roothub_exit()
usb_phy_roothub_exit() should return the error code from the phy_exit() call if exiting the PHY failed. However, since a wrong variable is used usb_phy_roothub_exit() currently always returns 0, even if one of the phy_exit calls returned an error. Fix this by assigning the error code from phy_exit() to the "ret" variable to propagate the error correctly. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 09b7c43c0ea4..f19aaa3c899c 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -111,7 +111,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) list_for_each_entry(roothub_entry, head, list) { err = phy_exit(roothub_entry->phy); if (err) - ret = ret; + ret = err; } return ret; -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC usb-next v2 2/2] usb: core: use phy_exit during suspend if wake up is not supported
If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from entering the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl --- drivers/usb/core/hcd.c | 8 +--- drivers/usb/core/phy.c | 37 + drivers/usb/core/phy.h | 5 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index d1861c5a74de..e794cbee97e9 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -155,3 +155,40 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + if (err) { + if (device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..60901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_rooth
[RFC usb-next v2 1/2] usb: core: split usb_phy_roothub_{init,alloc}
Before this patch usb_phy_roothub_init served two purposes (from a caller's point of view - like hcd.c): - parsing the PHYs and allocating the list entries - calling phy_init on each list entry While this worked so far it has one disadvantage: if we need to call phy_init for each PHY instance then the existing code cannot be re-used. Solve this by splitting off usb_phy_roothub_alloc which only parses the PHYs and allocates the list entries. usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls phy_init on each PHY instance (along with the corresponding cleanup if that failed somewhere). This is a preparation step for adding proper suspend support for some hardware that requires phy_exit to be called during suspend and phy_init to be called during resume. Signed-off-by: Martin Blumenstingl --- drivers/usb/core/hcd.c | 10 +++--- drivers/usb/core/phy.c | 51 +- drivers/usb/core/phy.h | 4 +++- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 777036ae6367..15b0418e3b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); if (IS_ERR(hcd->phy_roothub)) { retval = PTR_ERR(hcd->phy_roothub); - goto err_phy_roothub_init; + goto err_phy_roothub_alloc; } + retval = usb_phy_roothub_init(hcd->phy_roothub); + if (retval) + goto err_phy_roothub_alloc; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, usb_phy_roothub_power_off(hcd->phy_roothub); err_usb_phy_roothub_power_on: usb_phy_roothub_exit(hcd->phy_roothub); -err_phy_roothub_init: +err_phy_roothub_alloc: if (hcd->remove_phy && hcd->usb_phy) { usb_phy_shutdown(hcd->usb_phy); usb_put_phy(hcd->usb_phy); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index f19aaa3c899c..d1861c5a74de 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,19 +19,6 @@ struct usb_phy_roothub { struct list_headlist; }; -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) -{ - struct usb_phy_roothub *roothub_entry; - - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); - if (!roothub_entry) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&roothub_entry->list); - - return roothub_entry; -} - static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -45,9 +32,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return PTR_ERR(phy); } - roothub_entry = usb_phy_roothub_alloc(dev); - if (IS_ERR(roothub_entry)) - return PTR_ERR(roothub_entry); + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; roothub_entry->phy = phy; @@ -56,11 +43,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) { struct usb_phy_roothub *phy_roothub; - struct usb_phy_roothub *roothub_entry; - struct list_head *head; int i, num_phys, err; num_phys = of_count_phandle_with_args(dev->of_node, "phys", @@ -68,16 +53,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) if (num_phys <= 0) return NULL; - phy_roothub = usb_phy_roothub_alloc(dev); - if (IS_ERR(phy_roothub)) - return phy_roothub; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) - goto err_out; + return ERR_PTR(err); } + return phy_roothub; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc); + +int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub) +{
[RFC usb-next v2 0/2] fix HCD PHY suspend handling
This is a follow-up to my previous series "initialize (multiple) PHYs for a HCD": [0]. Roger Quadros reported [1] that it "is breaking low power cases on TI SoCs when USB is in host mode". He further explains that "Not doing the phy_exit() here [when entering suspend] leaves the clocks enabled on our SoC and we're no longer able to reach low power states on system suspend." Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call phy_exit while entering system suspend, because this would "disconnect plugged devices on MTK platforms, due to re-initialize u2 phys when resume" In the discussion (which followed Roger's bug report: [1]) Roger, Chunfeng and me came to the conclusion that we can fix suspend on the TI SoCs without breaking it on the Mediatek SoCs by extending the suspend and resume code in usb/core/phy.c by checking whether the USB controller can wake up the system (which is the case for the Mediatek MTU3 controller, but now for the dwc3 controller used on the TI SoCs): - if the controller can wake up the system (Mediatek MTU3 use-case) we only call usb_phy_roothub_power_off (which calls phy_power_off) when entering system suspend - if the controller however cannot wake up the system (dwc3 on TI SoCs) we additionally call usb_phy_roothub_exit (which calls phy_exit) when entering system suspend - (we undo the previous steps during system resume) The goal of this series is to fix the issue reported by Roger without breaking suspend/resume on the Mediatek SoCs. Since I neither have a TI nor a Mediatek device I am sending this as RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which does NOT support suspend/resume yet. this should be applied on top of [3] "usb: core: phy: fix return value of usb_phy_roothub_exit()" (even though there's no strict dependency, this is the order I wrote the patches in). Changes since v1 (blob attachments) at [4]: - use device_may_wakeup instead of device_can_wakeup as suggested by Roger Quadros - use the controller device from hcd->self.controller as suggested by Chunfeng Yun - compile time fixes thanks to Roger Quadros - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then we now call usb_phy_roothub_exit to keep the PHYs in the correct state if usb_phy_roothub_resume partially failed [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html Martin Blumenstingl (2): usb: core: split usb_phy_roothub_{init,alloc} usb: core: use phy_exit during suspend if wake up is not supported drivers/usb/core/hcd.c | 18 +++ drivers/usb/core/phy.c | 88 +++--- drivers/usb/core/phy.h | 9 +- 3 files changed, 82 insertions(+), 33 deletions(-) -- 2.16.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH usb-next v1] usb: core: phy: fix return value of usb_phy_roothub_exit()
Hi Chunfeng, On Mon, Mar 26, 2018 at 5:43 AM, Chunfeng Yun wrote: > On Sat, 2018-03-24 at 14:56 +0100, Martin Blumenstingl wrote: >> usb_phy_roothub_exit() should return the error code from the phy_exit() >> call if exiting the PHY failed. >> However, since a wrong variable is used usb_phy_roothub_exit() currently >> always returns 0, even if one of the phy_exit calls returned an error. >> Fix this by assigning the error code from phy_exit() to the "ret" >> variable to propagate the error correctly. >> >> Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the >> HCD") >> Signed-off-by: Martin Blumenstingl >> --- >> drivers/usb/core/phy.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >> index 09b7c43c0ea4..f19aaa3c899c 100644 >> --- a/drivers/usb/core/phy.c >> +++ b/drivers/usb/core/phy.c >> @@ -111,7 +111,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub >> *phy_roothub) >> list_for_each_entry(roothub_entry, head, list) { >> err = phy_exit(roothub_entry->phy); >> if (err) >> - ret = ret; >> + ret = err; > Need break the loop? in the original implementation I decided not to break the loop here so phy_exit is called for all PHYs -> only the problematic ones will remain initialized (in the _power_on implementation we can try to fix the state by adding a break and then calling _power_off for all PHYs before the "broken" one where _power_on failed) also if phy_exit fails then something is probably very wrong do you have any specific use-case in mind where the missing break could be a problem? >> } >> >> return ret; > > Regards Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC usb-next v2 1/2] usb: core: split usb_phy_roothub_{init,alloc}
Hi Chunfeng, On Mon, Mar 26, 2018 at 5:37 AM, Chunfeng Yun wrote: > On Sat, 2018-03-24 at 15:21 +0100, Martin Blumenstingl wrote: >> Before this patch usb_phy_roothub_init served two purposes (from a >> caller's point of view - like hcd.c): >> - parsing the PHYs and allocating the list entries >> - calling phy_init on each list entry >> >> While this worked so far it has one disadvantage: if we need to call >> phy_init for each PHY instance then the existing code cannot be re-used. >> Solve this by splitting off usb_phy_roothub_alloc which only parses the >> PHYs and allocates the list entries. >> usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls >> phy_init on each PHY instance (along with the corresponding cleanup if >> that failed somewhere). >> >> This is a preparation step for adding proper suspend support for some >> hardware that requires phy_exit to be called during suspend and phy_init >> to be called during resume. >> >> Signed-off-by: Martin Blumenstingl >> --- >> drivers/usb/core/hcd.c | 10 +++--- >> drivers/usb/core/phy.c | 51 >> +- >> drivers/usb/core/phy.h | 4 +++- >> 3 files changed, 35 insertions(+), 30 deletions(-) >> >> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c >> index 777036ae6367..15b0418e3b6a 100644 >> --- a/drivers/usb/core/hcd.c >> +++ b/drivers/usb/core/hcd.c >> @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, >> } >> >> if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { >> - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); >> + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); >> if (IS_ERR(hcd->phy_roothub)) { >> retval = PTR_ERR(hcd->phy_roothub); >> - goto err_phy_roothub_init; >> + goto err_phy_roothub_alloc; >> } >> >> + retval = usb_phy_roothub_init(hcd->phy_roothub); >> + if (retval) >> + goto err_phy_roothub_alloc; >> + >> retval = usb_phy_roothub_power_on(hcd->phy_roothub); >> if (retval) >> goto err_usb_phy_roothub_power_on; >> @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, >> usb_phy_roothub_power_off(hcd->phy_roothub); >> err_usb_phy_roothub_power_on: >> usb_phy_roothub_exit(hcd->phy_roothub); >> -err_phy_roothub_init: >> +err_phy_roothub_alloc: >> if (hcd->remove_phy && hcd->usb_phy) { >> usb_phy_shutdown(hcd->usb_phy); >> usb_put_phy(hcd->usb_phy); >> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >> index f19aaa3c899c..d1861c5a74de 100644 >> --- a/drivers/usb/core/phy.c >> +++ b/drivers/usb/core/phy.c >> @@ -19,19 +19,6 @@ struct usb_phy_roothub { >> struct list_headlist; >> }; >> >> -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >> -{ >> - struct usb_phy_roothub *roothub_entry; >> - >> - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); >> - if (!roothub_entry) >> - return ERR_PTR(-ENOMEM); >> - >> - INIT_LIST_HEAD(&roothub_entry->list); >> - >> - return roothub_entry; >> -} >> - >> static int usb_phy_roothub_add_phy(struct device *dev, int index, >> struct list_head *list) >> { >> @@ -45,9 +32,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int >> index, >> return PTR_ERR(phy); >> } > >> >> - roothub_entry = usb_phy_roothub_alloc(dev); >> - if (IS_ERR(roothub_entry)) >> - return PTR_ERR(roothub_entry); >> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); >> + if (!roothub_entry) >> + return -ENOMEM; >> >> roothub_entry->phy = phy; >> >> @@ -56,11 +43,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, >> int index, >> return 0; >> } >> >> -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) >> +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >> { >> struct usb_phy_roothub *phy_roothub; >> - struct usb_phy_roothub *roothub_entry; >&g
[RFC usb-next v3 1/2] usb: core: split usb_phy_roothub_{init,alloc}
Before this patch usb_phy_roothub_init served two purposes (from a caller's point of view - like hcd.c): - parsing the PHYs and allocating the list entries - calling phy_init on each list entry While this worked so far it has one disadvantage: if we need to call phy_init for each PHY instance then the existing code cannot be re-used. Solve this by splitting off usb_phy_roothub_alloc which only parses the PHYs and allocates the list entries. usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls phy_init on each PHY instance (along with the corresponding cleanup if that failed somewhere). This is a preparation step for adding proper suspend support for some hardware that requires phy_exit to be called during suspend and phy_init to be called during resume. Signed-off-by: Martin Blumenstingl --- drivers/usb/core/hcd.c | 10 +++--- drivers/usb/core/phy.c | 53 +- drivers/usb/core/phy.h | 4 +++- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 777036ae6367..15b0418e3b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); if (IS_ERR(hcd->phy_roothub)) { retval = PTR_ERR(hcd->phy_roothub); - goto err_phy_roothub_init; + goto err_phy_roothub_alloc; } + retval = usb_phy_roothub_init(hcd->phy_roothub); + if (retval) + goto err_phy_roothub_alloc; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, usb_phy_roothub_power_off(hcd->phy_roothub); err_usb_phy_roothub_power_on: usb_phy_roothub_exit(hcd->phy_roothub); -err_phy_roothub_init: +err_phy_roothub_alloc: if (hcd->remove_phy && hcd->usb_phy) { usb_phy_shutdown(hcd->usb_phy); usb_put_phy(hcd->usb_phy); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index f19aaa3c899c..44f008cda7a8 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,19 +19,6 @@ struct usb_phy_roothub { struct list_headlist; }; -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) -{ - struct usb_phy_roothub *roothub_entry; - - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); - if (!roothub_entry) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&roothub_entry->list); - - return roothub_entry; -} - static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return PTR_ERR(phy); } - roothub_entry = usb_phy_roothub_alloc(dev); - if (IS_ERR(roothub_entry)) - return PTR_ERR(roothub_entry); + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; + + INIT_LIST_HEAD(&roothub_entry->list); roothub_entry->phy = phy; @@ -56,11 +45,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) { struct usb_phy_roothub *phy_roothub; - struct usb_phy_roothub *roothub_entry; - struct list_head *head; int i, num_phys, err; num_phys = of_count_phandle_with_args(dev->of_node, "phys", @@ -68,16 +55,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) if (num_phys <= 0) return NULL; - phy_roothub = usb_phy_roothub_alloc(dev); - if (IS_ERR(phy_roothub)) - return phy_roothub; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) - goto err_out; + return ERR_PTR(err); } + return phy_roothub; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc
[RFC usb-next v3 0/2] fix HCD PHY suspend handling
This is a follow-up to my previous series "initialize (multiple) PHYs for a HCD": [0]. Roger Quadros reported [1] that it "is breaking low power cases on TI SoCs when USB is in host mode". He further explains that "Not doing the phy_exit() here [when entering suspend] leaves the clocks enabled on our SoC and we're no longer able to reach low power states on system suspend." Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call phy_exit while entering system suspend, because this would "disconnect plugged devices on MTK platforms, due to re-initialize u2 phys when resume" In the discussion (which followed Roger's bug report: [1]) Roger, Chunfeng and me came to the conclusion that we can fix suspend on the TI SoCs without breaking it on the Mediatek SoCs by extending the suspend and resume code in usb/core/phy.c by checking whether the USB controller can wake up the system (which is the case for the Mediatek MTU3 controller, but now for the dwc3 controller used on the TI SoCs): - if the controller can wake up the system (Mediatek MTU3 use-case) we only call usb_phy_roothub_power_off (which calls phy_power_off) when entering system suspend - if the controller however cannot wake up the system (dwc3 on TI SoCs) we additionally call usb_phy_roothub_exit (which calls phy_exit) when entering system suspend - (we undo the previous steps during system resume) The goal of this series is to fix the issue reported by Roger without breaking suspend/resume on the Mediatek SoCs. Since I neither have a TI nor a Mediatek device I am sending this as RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which does NOT support suspend/resume yet. this should be applied on top of [3] "usb: core: phy: fix return value of usb_phy_roothub_exit()" (even though there's no strict dependency, this is the order I wrote the patches in). changes since RFC v2 at [5]: - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects patch #1 - spotted by Roger Quadros, thank you!) - fixed swapped conditions using device_may_wakeup() in usb_phy_roothub_resume because we need to call usb_phy_roothub_init if the controller cannot wake up the device (affects patch #2, spotted by Chunfeng Yun, thank you!) - simplified the error condition to "undo" usb_phy_roothub_init if usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested by Chunfeng Yun) - updated the commit message (using Roger's wording) because (quote from Roger "it doesn't prevent the system from entering suspend but just prevents the system from reaching lowest power levels in the suspend state." Changes since RFC v1 (blob attachments) at [4]: - use device_may_wakeup instead of device_can_wakeup as suggested by Roger Quadros - use the controller device from hcd->self.controller as suggested by Chunfeng Yun - compile time fixes thanks to Roger Quadros - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then we now call usb_phy_roothub_exit to keep the PHYs in the correct state if usb_phy_roothub_resume partially failed [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html [5] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006820.html Martin Blumenstingl (2): usb: core: split usb_phy_roothub_{init,alloc} usb: core: use phy_exit during suspend if wake up is not supported drivers/usb/core/hcd.c | 18 +++ drivers/usb/core/phy.c | 88 +++--- drivers/usb/core/phy.h | 9 +- 3 files changed, 82 insertions(+), 33 deletions(-) -- 2.16.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC usb-next v3 2/2] usb: core: use phy_exit during suspend if wake up is not supported
If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from reaching the lowest power levels in the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl --- drivers/usb/core/hcd.c | 8 +--- drivers/usb/core/phy.c | 35 +++ drivers/usb/core/phy.h | 5 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 44f008cda7a8..a39d9bb26a4f 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (!device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + + /* undo _init if _power_on failed */ + if (err && !device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..60901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *p
[PATCH usb-next v4 0/2] fix HCD PHY suspend handling
This is a follow-up to my previous series "initialize (multiple) PHYs for a HCD": [0]. Roger Quadros reported [1] that it "is breaking low power cases on TI SoCs when USB is in host mode". He further explains that "Not doing the phy_exit() here [when entering suspend] leaves the clocks enabled on our SoC and we're no longer able to reach low power states on system suspend." Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call phy_exit while entering system suspend, because this would "disconnect plugged devices on MTK platforms, due to re-initialize u2 phys when resume" In the discussion (which followed Roger's bug report: [1]) Roger, Chunfeng and me came to the conclusion that we can fix suspend on the TI SoCs without breaking it on the Mediatek SoCs by extending the suspend and resume code in usb/core/phy.c by checking whether the USB controller can wake up the system (which is the case for the Mediatek MTU3 controller, but now for the dwc3 controller used on the TI SoCs): - if the controller can wake up the system (Mediatek MTU3 use-case) we only call usb_phy_roothub_power_off (which calls phy_power_off) when entering system suspend - if the controller however cannot wake up the system (dwc3 on TI SoCs) we additionally call usb_phy_roothub_exit (which calls phy_exit) when entering system suspend - (we undo the previous steps during system resume) The goal of this series is to fix the issue reported by Roger without breaking suspend/resume on the Mediatek SoCs. Since I neither have a TI nor a Mediatek device I am sending this as RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which does NOT support suspend/resume yet. this should be applied on top of [3] "usb: core: phy: fix return value of usb_phy_roothub_exit()" (even though there's no strict dependency, this is the order I wrote the patches in). changes since RFC v3 at [6]: - added Chunfeng Yun's Tested-by and Roger Quadros' Reviewed-by (thank you!) - dropped RFC prefix changes since RFC v2 at [5]: - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects patch #1 - spotted by Roger Quadros, thank you!) - fixed swapped conditions using device_may_wakeup() in usb_phy_roothub_resume because we need to call usb_phy_roothub_init if the controller cannot wake up the device (affects patch #2, spotted by Chunfeng Yun, thank you!) - simplified the error condition to "undo" usb_phy_roothub_init if usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested by Chunfeng Yun) - updated the commit message (using Roger's wording) because (quote from Roger "it doesn't prevent the system from entering suspend but just prevents the system from reaching lowest power levels in the suspend state." Changes since RFC v1 (blob attachments) at [4]: - use device_may_wakeup instead of device_can_wakeup as suggested by Roger Quadros - use the controller device from hcd->self.controller as suggested by Chunfeng Yun - compile time fixes thanks to Roger Quadros - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then we now call usb_phy_roothub_exit to keep the PHYs in the correct state if usb_phy_roothub_resume partially failed [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html [5] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006820.html [6] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006847.html Martin Blumenstingl (2): usb: core: split usb_phy_roothub_{init,alloc} usb: core: use phy_exit during suspend if wake up is not supported drivers/usb/core/hcd.c | 18 +++ drivers/usb/core/phy.c | 88 +++--- drivers/usb/core/phy.h | 9 +- 3 files changed, 82 insertions(+), 33 deletions(-) -- 2.16.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb-next v4 1/2] usb: core: split usb_phy_roothub_{init,alloc}
Before this patch usb_phy_roothub_init served two purposes (from a caller's point of view - like hcd.c): - parsing the PHYs and allocating the list entries - calling phy_init on each list entry While this worked so far it has one disadvantage: if we need to call phy_init for each PHY instance then the existing code cannot be re-used. Solve this by splitting off usb_phy_roothub_alloc which only parses the PHYs and allocates the list entries. usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls phy_init on each PHY instance (along with the corresponding cleanup if that failed somewhere). This is a preparation step for adding proper suspend support for some hardware that requires phy_exit to be called during suspend and phy_init to be called during resume. Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros --- drivers/usb/core/hcd.c | 10 +++--- drivers/usb/core/phy.c | 53 +- drivers/usb/core/phy.h | 4 +++- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 777036ae6367..15b0418e3b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); if (IS_ERR(hcd->phy_roothub)) { retval = PTR_ERR(hcd->phy_roothub); - goto err_phy_roothub_init; + goto err_phy_roothub_alloc; } + retval = usb_phy_roothub_init(hcd->phy_roothub); + if (retval) + goto err_phy_roothub_alloc; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, usb_phy_roothub_power_off(hcd->phy_roothub); err_usb_phy_roothub_power_on: usb_phy_roothub_exit(hcd->phy_roothub); -err_phy_roothub_init: +err_phy_roothub_alloc: if (hcd->remove_phy && hcd->usb_phy) { usb_phy_shutdown(hcd->usb_phy); usb_put_phy(hcd->usb_phy); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index f19aaa3c899c..44f008cda7a8 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,19 +19,6 @@ struct usb_phy_roothub { struct list_headlist; }; -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) -{ - struct usb_phy_roothub *roothub_entry; - - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); - if (!roothub_entry) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&roothub_entry->list); - - return roothub_entry; -} - static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return PTR_ERR(phy); } - roothub_entry = usb_phy_roothub_alloc(dev); - if (IS_ERR(roothub_entry)) - return PTR_ERR(roothub_entry); + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; + + INIT_LIST_HEAD(&roothub_entry->list); roothub_entry->phy = phy; @@ -56,11 +45,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) { struct usb_phy_roothub *phy_roothub; - struct usb_phy_roothub *roothub_entry; - struct list_head *head; int i, num_phys, err; num_phys = of_count_phandle_with_args(dev->of_node, "phys", @@ -68,16 +55,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) if (num_phys <= 0) return NULL; - phy_roothub = usb_phy_roothub_alloc(dev); - if (IS_ERR(phy_roothub)) - return phy_roothub; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) - goto err_out; + return ERR_PTR(err); } + return phy_ro
[PATCH usb-next v4 2/2] usb: core: use phy_exit during suspend if wake up is not supported
If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from reaching the lowest power levels in the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros --- drivers/usb/core/hcd.c | 8 +--- drivers/usb/core/phy.c | 35 +++ drivers/usb/core/phy.h | 5 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 44f008cda7a8..a39d9bb26a4f 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (!device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + + /* undo _init if _power_on failed */ + if (err && !device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..60901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void
Re: [PATCH] usb: core: phy: Fix usb_phy_roothub_add_phy if GENERIC_PHY=n
Hello Stefan, On Sat, Mar 31, 2018 at 9:28 PM, Stefan Wahren wrote: > If the generic PHY support is disabled the stub of devm_of_phy_get_by_index > returns ENOSYS. This corner case isn't handled properly by > usb_phy_roothub_add_phy and at least breaks USB support on Raspberry Pi > (bcm2835_defconfig): > > dwc2 2098.usb: dwc2_hcd_init() FAILED, returning -38 > dwc2: probe of 2098.usb failed with error -38 thank you for reporting and proposing a fix! > Fixes: 07dbff0ddbd8 ("usb: core: add a wrapper for the USB PHYs on the HCD") > Signed-off-by: Stefan Wahren > --- > drivers/usb/core/phy.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c > index 09b7c43..c89e9be 100644 > --- a/drivers/usb/core/phy.c > +++ b/drivers/usb/core/phy.c > @@ -39,7 +39,7 @@ static int usb_phy_roothub_add_phy(struct device *dev, int > index, > struct phy *phy = devm_of_phy_get_by_index(dev, dev->of_node, index); > > if (IS_ERR_OR_NULL(phy)) { > - if (!phy || PTR_ERR(phy) == -ENODEV) > + if (!phy || PTR_ERR(phy) == -ENODEV || PTR_ERR(phy) == > -ENOSYS) > return 0; > else > return PTR_ERR(phy); > -- > 2.7.4 I have three patches pending, one of them (the patch from [1]) touches the same function: - "usb: core: phy: fix return value of usb_phy_roothub_exit()" [0] - "usb: core: split usb_phy_roothub_{init, alloc}" [1] - "usb: core: use phy_exit during suspend if wake up is not supported" [2] maybe we should make it more explicit that the whole code is only useful if CONFIG_GENERIC_PHY is enabled what do you think about adding the following two lines at the beginning of usb_phy_roothub_alloc (after patch [1] is applied, before this function was basically called usb_phy_roothub_init) if (!IS_ENABLED(CONFIG_GENERIC_PHY)) return NULL; this should even allow the compiler to optimize away some unused code Regards Martin [0] https://patchwork.kernel.org/patch/10306053/ [1] https://patchwork.kernel.org/patch/10311701/ [2] https://patchwork.kernel.org/patch/10311703/ -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
Hello, (great to hear that this might be useful on Socionext SoCs as well :)) On Wed, Apr 4, 2018 at 2:10 PM, Masahiro Yamada wrote: > 2018-03-04 6:43 GMT+09:00 Martin Blumenstingl > : >> Many SoC platforms have separate devices for the USB PHY which are >> registered through the generic PHY framework. These PHYs have to be >> enabled to make the USB controller actually work. They also have to be >> disabled again on shutdown/suspend. >> >> Currently (at least) the following HCI platform drivers are using custom >> code to obtain all PHYs via devicetree for the roothub/controller and >> disable/enable them when required: >> - ehci-platform.c has ehci_platform_power_{on,off} >> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> - ohci-platform.c has ohci_platform_power_{on,off} >> >> With this new wrapper the USB PHYs can be specified directly in the >> USB controller's devicetree node (just like on the drivers listed >> above). This allows SoCs like the Amlogic Meson GXL family to operate >> correctly once this is wired up correctly. These SoCs use a dwc3 >> controller and require all USB PHYs to be initialized (if one of the USB >> PHYs it not initialized then none of USB port works at all). >> >> Signed-off-by: Martin Blumenstingl >> Tested-by: Yixun Lan >> Cc: Neil Armstrong >> Cc: Chunfeng Yun >> --- >> drivers/usb/core/Makefile | 2 +- >> drivers/usb/core/phy.c| 158 >> ++ >> drivers/usb/core/phy.h| 7 ++ >> 3 files changed, 166 insertions(+), 1 deletion(-) >> create mode 100644 drivers/usb/core/phy.c >> create mode 100644 drivers/usb/core/phy.h >> >> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >> index 92c9cefb4317..18e874b0441e 100644 >> --- a/drivers/usb/core/Makefile >> +++ b/drivers/usb/core/Makefile >> @@ -6,7 +6,7 @@ >> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >> -usbcore-y += port.o >> +usbcore-y += phy.o port.o >> >> usbcore-$(CONFIG_OF) += of.o >> usbcore-$(CONFIG_USB_PCI) += hcd-pci.o >> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >> new file mode 100644 >> index ..09b7c43c0ea4 >> --- /dev/null >> +++ b/drivers/usb/core/phy.c >> @@ -0,0 +1,158 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * A wrapper for multiple PHYs which passes all phy_* function calls to >> + * multiple (actual) PHY devices. This is comes handy when initializing >> + * all PHYs on a HCD and to keep them all in the same state. >> + * >> + * Copyright (C) 2018 Martin Blumenstingl >> >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "phy.h" >> + >> +struct usb_phy_roothub { >> + struct phy *phy; >> + struct list_headlist; >> +}; >> + >> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >> +{ >> + struct usb_phy_roothub *roothub_entry; >> + >> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), >> GFP_KERNEL); >> + if (!roothub_entry) >> + return ERR_PTR(-ENOMEM); >> + >> + INIT_LIST_HEAD(&roothub_entry->list); >> + >> + return roothub_entry; >> +} >> + >> +static int usb_phy_roothub_add_phy(struct device *dev, int index, >> + struct list_head *list) >> +{ >> + struct usb_phy_roothub *roothub_entry; >> + struct phy *phy = devm_of_phy_get_by_index(dev, dev->of_node, index); >> + >> + if (IS_ERR_OR_NULL(phy)) { >> + if (!phy || PTR_ERR(phy) == -ENODEV) >> + return 0; >> + else >> + return PTR_ERR(phy); >> + } >> + >> + roothub_entry = usb_phy_roothub_alloc(dev); >> + if (IS_ERR(roothub_entry)) >> + return PTR_ERR(roothub_entry); >> + >> + roothub_entry->phy = phy; >> + >> + list_add_tail(&roothub_entry->list, list); >> + >> + return 0; >> +} >> + >> +struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) >> +{ >> + struct usb_phy_roothub *phy_roothub; >> + struct us
Re: [PATCH usb-next v4 0/2] fix HCD PHY suspend handling
Hi Greg, On Thu, Apr 5, 2018 at 3:38 PM, Greg KH wrote: > On Thu, Apr 05, 2018 at 11:47:11AM +0300, Roger Quadros wrote: >> Greg, >> >> On 28/03/18 00:26, Martin Blumenstingl wrote: >> > This is a follow-up to my previous series "initialize (multiple) PHYs >> > for a HCD": [0]. >> > >> > Roger Quadros reported [1] that it "is breaking low power cases on TI >> > SoCs when USB is in host mode". He further explains that "Not doing the >> > phy_exit() here [when entering suspend] leaves the clocks enabled on >> > our SoC and we're no longer able to reach low power states on system >> > suspend." >> > Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call >> > phy_exit while entering system suspend, because this would "disconnect >> > plugged devices on MTK platforms, due to re-initialize u2 phys when >> > resume" >> > >> > In the discussion (which followed Roger's bug report: [1]) Roger, >> > Chunfeng and me came to the conclusion that we can fix suspend on the >> > TI SoCs without breaking it on the Mediatek SoCs by extending the >> > suspend and resume code in usb/core/phy.c by checking whether the USB >> > controller can wake up the system (which is the case for the Mediatek >> > MTU3 controller, but now for the dwc3 controller used on the TI SoCs): >> > - if the controller can wake up the system (Mediatek MTU3 use-case) we >> > only call usb_phy_roothub_power_off (which calls phy_power_off) when >> > entering system suspend >> > - if the controller however cannot wake up the system (dwc3 on TI SoCs) >> > we additionally call usb_phy_roothub_exit (which calls phy_exit) when >> > entering system suspend >> > - (we undo the previous steps during system resume) >> > >> > The goal of this series is to fix the issue reported by Roger without >> > breaking suspend/resume on the Mediatek SoCs. >> > Since I neither have a TI nor a Mediatek device I am sending this as >> > RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which >> > does NOT support suspend/resume yet. >> > >> > this should be applied on top of [3] "usb: core: phy: fix return value >> > of usb_phy_roothub_exit()" (even though there's no strict dependency, >> > this is the order I wrote the patches in). >> > >> > changes since RFC v3 at [6]: >> > - added Chunfeng Yun's Tested-by and Roger Quadros' Reviewed-by (thank >> > you!) >> > - dropped RFC prefix >> > >> > changes since RFC v2 at [5]: >> > - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects >> > patch #1 - spotted by Roger Quadros, thank you!) >> > - fixed swapped conditions using device_may_wakeup() in >> > usb_phy_roothub_resume because we need to call usb_phy_roothub_init >> > if the controller cannot wake up the device (affects patch #2, spotted >> > by Chunfeng Yun, thank you!) >> > - simplified the error condition to "undo" usb_phy_roothub_init if >> > usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested >> > by Chunfeng Yun) >> > - updated the commit message (using Roger's wording) because (quote from >> > Roger "it doesn't prevent the system from entering suspend but just >> > prevents the system from reaching lowest power levels in the suspend >> > state." >> > >> > Changes since RFC v1 (blob attachments) at [4]: >> > - use device_may_wakeup instead of device_can_wakeup as suggested by >> > Roger Quadros >> > - use the controller device from hcd->self.controller as suggested by >> > Chunfeng Yun >> > - compile time fixes thanks to Roger Quadros >> > - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then >> > we now call usb_phy_roothub_exit to keep the PHYs in the correct >> > state if usb_phy_roothub_resume partially failed >> > >> > >> > [0] >> > http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html >> > [1] >> > http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html >> > [2] >> > http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html >> > [3] >> > http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html >> > [4] >> > http://lists.infradead.org/pipermail/linux-amlogic/2018
Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD
On Fri, Apr 6, 2018 at 5:48 AM, Masahiro Yamada wrote: > 2018-04-06 5:04 GMT+09:00 Martin Blumenstingl > : >> Hello, >> >> (great to hear that this might be useful on Socionext SoCs as well :)) >> >> On Wed, Apr 4, 2018 at 2:10 PM, Masahiro Yamada >> wrote: >>> 2018-03-04 6:43 GMT+09:00 Martin Blumenstingl >>> : >>>> Many SoC platforms have separate devices for the USB PHY which are >>>> registered through the generic PHY framework. These PHYs have to be >>>> enabled to make the USB controller actually work. They also have to be >>>> disabled again on shutdown/suspend. >>>> >>>> Currently (at least) the following HCI platform drivers are using custom >>>> code to obtain all PHYs via devicetree for the roothub/controller and >>>> disable/enable them when required: >>>> - ehci-platform.c has ehci_platform_power_{on,off} >>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >>>> - ohci-platform.c has ohci_platform_power_{on,off} >>>> >>>> With this new wrapper the USB PHYs can be specified directly in the >>>> USB controller's devicetree node (just like on the drivers listed >>>> above). This allows SoCs like the Amlogic Meson GXL family to operate >>>> correctly once this is wired up correctly. These SoCs use a dwc3 >>>> controller and require all USB PHYs to be initialized (if one of the USB >>>> PHYs it not initialized then none of USB port works at all). >>>> >>>> Signed-off-by: Martin Blumenstingl >>>> Tested-by: Yixun Lan >>>> Cc: Neil Armstrong >>>> Cc: Chunfeng Yun >>>> --- >>>> drivers/usb/core/Makefile | 2 +- >>>> drivers/usb/core/phy.c| 158 >>>> ++ >>>> drivers/usb/core/phy.h| 7 ++ >>>> 3 files changed, 166 insertions(+), 1 deletion(-) >>>> create mode 100644 drivers/usb/core/phy.c >>>> create mode 100644 drivers/usb/core/phy.h >>>> >>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile >>>> index 92c9cefb4317..18e874b0441e 100644 >>>> --- a/drivers/usb/core/Makefile >>>> +++ b/drivers/usb/core/Makefile >>>> @@ -6,7 +6,7 @@ >>>> usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o >>>> usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o >>>> usbcore-y += devio.o notify.o generic.o quirks.o devices.o >>>> -usbcore-y += port.o >>>> +usbcore-y += phy.o port.o >>>> >>>> usbcore-$(CONFIG_OF) += of.o >>>> usbcore-$(CONFIG_USB_PCI) += hcd-pci.o >>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c >>>> new file mode 100644 >>>> index ..09b7c43c0ea4 >>>> --- /dev/null >>>> +++ b/drivers/usb/core/phy.c >>>> @@ -0,0 +1,158 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to >>>> + * multiple (actual) PHY devices. This is comes handy when initializing >>>> + * all PHYs on a HCD and to keep them all in the same state. >>>> + * >>>> + * Copyright (C) 2018 Martin Blumenstingl >>>> >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#include "phy.h" >>>> + >>>> +struct usb_phy_roothub { >>>> + struct phy *phy; >>>> + struct list_headlist; >>>> +}; >>>> + >>>> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) >>>> +{ >>>> + struct usb_phy_roothub *roothub_entry; >>>> + >>>> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), >>>> GFP_KERNEL); >>>> + if (!roothub_entry) >>>> + return ERR_PTR(-ENOMEM); >>>> + >>>> + INIT_LIST_HEAD(&roothub_entry->list); >>>> + >>>> + return roothub_entry; >>>> +} >>>> + >>>> +static int usb_phy_roothub_add_phy(struct device *dev, int index, >>>> + struct list_head *list) >>>> +{ >>>> + struct usb_phy_root
Re: [PATCH] Usb: core: Correct self assignment in phy.c
Hello, thank you for finding this! On Sat, Apr 7, 2018 at 1:04 AM, Rishabh Bhatnagar wrote: > In file drivers/usb/core/phy.c line 114, ret variable is assigned to > itself. The following error was observed: > > kernel/drivers/usb/core/phy.c:114:8: warning: explicitly assigning value of > variable of type 'int' to itself [-Wself-assign] error, forbidden > warning: phy.c:114 > This error was found when compiling with Clang. Change it to ret = err. I found the same bug myself two weeks ago and already sent a patch: [0] it has not made it to Greg's tree yet. Greg asked me to re-send that patch along with some others after -rc1 is out: [1] > Fixes: commit 07dbff0ddbd8 ("usb: core: add a wrapper for the USB PHYs on the > HCD") > Signed-off-by: Rishabh Bhatnagar would you like me to add your Acked-by or Signed-off-by to my patch? > --- > drivers/usb/core/phy.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c > index 09b7c43..f19aaa3 100644 > --- a/drivers/usb/core/phy.c > +++ b/drivers/usb/core/phy.c > @@ -111,7 +111,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub > *phy_roothub) > list_for_each_entry(roothub_entry, head, list) { > err = phy_exit(roothub_entry->phy); > if (err) > - ret = ret; > + ret = err; > } > > return ret; > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project > Regards Martin [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/006977.html -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v5 3/6] usb: core: use phy_exit during suspend if wake up is not supported
If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from reaching the lowest power levels in the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros --- drivers/usb/core/hcd.c | 8 +--- drivers/usb/core/phy.c | 35 +++ drivers/usb/core/phy.h | 5 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 44f008cda7a8..a39d9bb26a4f 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (!device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + + /* undo _init if _power_on failed */ + if (err && !device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..60901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void
[PATCH usb v5 1/6] usb: core: phy: fix return value of usb_phy_roothub_exit()
usb_phy_roothub_exit() should return the error code from the phy_exit() call if exiting the PHY failed. However, since a wrong variable is used usb_phy_roothub_exit() currently always returns 0, even if one of the phy_exit calls returned an error. Clang also reports this bug: kernel/drivers/usb/core/phy.c:114:8: warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign] error, forbidden warning: phy.c:114 Fix this by assigning the error code from phy_exit() to the "ret" variable to propagate the error correctly. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Signed-off-by: Martin Blumenstingl Signed-off-by: Rishabh Bhatnagar --- drivers/usb/core/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 09b7c43c0ea4..f19aaa3c899c 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -111,7 +111,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) list_for_each_entry(roothub_entry, head, list) { err = phy_exit(roothub_entry->phy); if (err) - ret = ret; + ret = err; } return ret; -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v5 2/6] usb: core: split usb_phy_roothub_{init,alloc}
Before this patch usb_phy_roothub_init served two purposes (from a caller's point of view - like hcd.c): - parsing the PHYs and allocating the list entries - calling phy_init on each list entry While this worked so far it has one disadvantage: if we need to call phy_init for each PHY instance then the existing code cannot be re-used. Solve this by splitting off usb_phy_roothub_alloc which only parses the PHYs and allocates the list entries. usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls phy_init on each PHY instance (along with the corresponding cleanup if that failed somewhere). This is a preparation step for adding proper suspend support for some hardware that requires phy_exit to be called during suspend and phy_init to be called during resume. Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros --- drivers/usb/core/hcd.c | 10 +--- drivers/usb/core/phy.c | 53 +- drivers/usb/core/phy.h | 4 +++- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 777036ae6367..15b0418e3b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); if (IS_ERR(hcd->phy_roothub)) { retval = PTR_ERR(hcd->phy_roothub); - goto err_phy_roothub_init; + goto err_phy_roothub_alloc; } + retval = usb_phy_roothub_init(hcd->phy_roothub); + if (retval) + goto err_phy_roothub_alloc; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, usb_phy_roothub_power_off(hcd->phy_roothub); err_usb_phy_roothub_power_on: usb_phy_roothub_exit(hcd->phy_roothub); -err_phy_roothub_init: +err_phy_roothub_alloc: if (hcd->remove_phy && hcd->usb_phy) { usb_phy_shutdown(hcd->usb_phy); usb_put_phy(hcd->usb_phy); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index f19aaa3c899c..44f008cda7a8 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,19 +19,6 @@ struct usb_phy_roothub { struct list_headlist; }; -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) -{ - struct usb_phy_roothub *roothub_entry; - - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); - if (!roothub_entry) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&roothub_entry->list); - - return roothub_entry; -} - static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return PTR_ERR(phy); } - roothub_entry = usb_phy_roothub_alloc(dev); - if (IS_ERR(roothub_entry)) - return PTR_ERR(roothub_entry); + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; + + INIT_LIST_HEAD(&roothub_entry->list); roothub_entry->phy = phy; @@ -56,11 +45,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) { struct usb_phy_roothub *phy_roothub; - struct usb_phy_roothub *roothub_entry; - struct list_head *head; int i, num_phys, err; num_phys = of_count_phandle_with_args(dev->of_node, "phys", @@ -68,16 +55,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) if (num_phys <= 0) return NULL; - phy_roothub = usb_phy_roothub_alloc(dev); - if (IS_ERR(phy_roothub)) - return phy_roothub; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) - goto err_out; + return ERR_PTR(err); } + return phy_roothub; +} +EXPORT_S
[PATCH usb v5 6/6] usb: core: phy: add the SPDX-License-Identifier and include guard
This clarifies the license of the code. While here also add an include guard to the header file. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Suggested-by: Masahiro Yamada Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.h | 12 1 file changed, 12 insertions(+) diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index bbc969383074..8451a7e88d38 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -1,3 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * USB roothub wrapper + * + * Copyright (C) 2018 Martin Blumenstingl + */ + +#ifndef __USB_CORE_PHY_H_ +#define __USB_CORE_PHY_H_ + struct device; struct usb_phy_roothub; @@ -13,3 +23,5 @@ int usb_phy_roothub_suspend(struct device *controller_dev, struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_resume(struct device *controller_dev, struct usb_phy_roothub *phy_roothub); + +#endif /* __USB_CORE_PHY_H_ */ -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v5 4/6] usb: core: phy: make it a no-op if CONFIG_GENERIC_PHY is disabled
If the generic PHY support is disabled the stub of devm_of_phy_get_by_index returns ENOSYS. This corner case isn't handled properly by usb_phy_roothub_add_phy and at least breaks USB support on Raspberry Pi (bcm2835_defconfig): dwc2 2098.usb: dwc2_hcd_init() FAILED, returning -38 dwc2: probe of 2098.usb failed with error -38 Let usb_phy_roothub_alloc() return in case CONFIG_GENERIC_PHY is disabled to fix this issue (compilers might even be smart enough to optimize away most of the code within usb_phy_roothub_alloc and usb_phy_roothub_add_phy if CONFIG_GENERIC_PHY is disabled). All existing usb_phy_roothub_* functions are already NULL-safe, so no special handling is required there. Fixes: 07dbff0ddbd8 ("usb: core: add a wrapper for the USB PHYs on the HCD") Reported-by: Stefan Wahren Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index a39d9bb26a4f..9879767452a2 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -50,6 +50,9 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) struct usb_phy_roothub *phy_roothub; int i, num_phys, err; + if (!IS_ENABLED(CONFIG_GENERIC_PHY)) + return NULL; + num_phys = of_count_phandle_with_args(dev->of_node, "phys", "#phy-cells"); if (num_phys <= 0) -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v5 5/6] usb: core: phy: add missing forward declaration for "struct device"
Currently hcd.c is the only consumer of the usb_phy_roothub logic. This already includes the required header files so struct device is known. However, future consumers might not know about struct device. Add a forward declaration for struct device to fix potential future consumers which don't include any of the struct device API headers. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Suggested-by: Masahiro Yamada Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 60901d44..bbc969383074 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -1,3 +1,4 @@ +struct device; struct usb_phy_roothub; struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v5 0/6] usb/core/phy fixes for v4.17
This is a follow-up to my previous series "initialize (multiple) PHYs for a HCD": [0]. Roger Quadros reported [1] that it "is breaking low power cases on TI SoCs when USB is in host mode". He further explains that "Not doing the phy_exit() here [when entering suspend] leaves the clocks enabled on our SoC and we're no longer able to reach low power states on system suspend." Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call phy_exit while entering system suspend, because this would "disconnect plugged devices on MTK platforms, due to re-initialize u2 phys when resume" In the discussion (which followed Roger's bug report: [1]) Roger, Chunfeng and me came to the conclusion that we can fix suspend on the TI SoCs without breaking it on the Mediatek SoCs by extending the suspend and resume code in usb/core/phy.c by checking whether the USB controller can wake up the system (which is the case for the Mediatek MTU3 controller, but now for the dwc3 controller used on the TI SoCs): - if the controller can wake up the system (Mediatek MTU3 use-case) we only call usb_phy_roothub_power_off (which calls phy_power_off) when entering system suspend - if the controller however cannot wake up the system (dwc3 on TI SoCs) we additionally call usb_phy_roothub_exit (which calls phy_exit) when entering system suspend - (we undo the previous steps during system resume) The goal of this series is to fix the issue reported by Roger without breaking suspend/resume on the Mediatek SoCs. Since I neither have a TI nor a Mediatek device I am sending this as RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which does NOT support suspend/resume yet. Additionally Stefan Wahren reported [7] that booting on a Raspberry Pi with CONFIG_GENERIC_PHY being disabled (which is the case for bcm2835_defconfig) breaks USB. A fix for this is also included. changes since v4 at [8] - updated series title since it now includes fixes for other functionality than suspend - rebased on top of f8cf2f16a7c95a from Linus' tree -> I will re-send an updated version once v4.17-rc1 is out, I just sent it early to get some feedback early! - included patch [3] "usb: core: phy: fix return value of usb_phy_roothub_exit()" in this series - fix the logic if CONFIG_GENERIC_PHY is disabled (as reported by Stefan Wahren, new patch #4) - two minor coding style fixes as suggested by Masahiro Yamada (new patches #4 and #5) changes since RFC v3 at [6]: - added Chunfeng Yun's Tested-by and Roger Quadros' Reviewed-by (thank you!) - dropped RFC prefix changes since RFC v2 at [5]: - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects patch #1 - spotted by Roger Quadros, thank you!) - fixed swapped conditions using device_may_wakeup() in usb_phy_roothub_resume because we need to call usb_phy_roothub_init if the controller cannot wake up the device (affects patch #2, spotted by Chunfeng Yun, thank you!) - simplified the error condition to "undo" usb_phy_roothub_init if usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested by Chunfeng Yun) - updated the commit message (using Roger's wording) because (quote from Roger "it doesn't prevent the system from entering suspend but just prevents the system from reaching lowest power levels in the suspend state." Changes since RFC v1 (blob attachments) at [4]: - use device_may_wakeup instead of device_can_wakeup as suggested by Roger Quadros - use the controller device from hcd->self.controller as suggested by Chunfeng Yun - compile time fixes thanks to Roger Quadros - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then we now call usb_phy_roothub_exit to keep the PHYs in the correct state if usb_phy_roothub_resume partially failed [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html [5] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006820.html [6] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006847.html [7] https://www.spinics.net/lists/linux-usb/msg167472.html [8] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006882.html Martin Blumenstingl (6): usb: core: phy: fix return value of usb_phy_roothub_exit() usb: core: split usb_phy_roothub_{init,alloc} usb: core: use phy_exit during suspend if wake up is not supported usb: core: phy: make it a no-op if CONFIG_GENERIC_PHY is disabled usb: core: phy: add missing forward declaration for "struct device" usb: core: p
Re: [PATCH 0/3] USB: musb: dsps: phy fix and DT-topology support
Hi Johan, On Fri, Apr 13, 2018 at 5:15 PM, Johan Hovold wrote: > I've been carrying a patch out-of-tree since my work on improving the > USB device-tree support which is needed to be able to describe USB > topologies for musb based controllers. > > This patch, which associates the platform controller device with the > glue device device-tree node, did not play well with the recent changes > which added generic phy support to USB core however. I'm the one who added this > Like the recent dwc2 regression fixed by Arnd after the device-tree > #phy-cell changes, the generic phy code in USB core can now also fail > indefinitly with -EPROBE_DEFER when the controller uses a legacy USB > phy. > > The second patch addresses this for musb, which handles its own (legacy > and generic) phys, but something more may possibly now be needed for > other platforms with legacy phys. I'm not sure if I understand the problem yet - could you please explain with your words what "legacy PHYs" are and how the "conflict" with the PHY handling in USB core? I am aware of two PHY subsystems: - drivers/phy -- also called "generic PHY framework" -- uses a "phys" property - drivers/usb/phy -- also called "USB PHY framework" -- AFAIK this should not be used for new drivers -- uses an "usb-phy" property the new PHY handling in USB core only parses the "phys" property and thus should not conflict with "usb-phy" (the legacy property) however, I probably missed something so I'd appreciate an explanation how things can break > In the process of debugging this, I stumbled over another issue which > caused the dsps legacy phy init two be called twice on every probe and > which is fixed by the first patch. > > Johan > > > Johan Hovold (3): > USB: musb: dsps: drop duplicate phy initialisation > USB: musb: host: prevent core phy initialisation > USB: musb: dsps: propagate device-tree node > > drivers/usb/musb/musb_dsps.c | 3 +-- > drivers/usb/musb/musb_host.c | 1 + > 2 files changed, 2 insertions(+), 2 deletions(-) > > -- > 2.17.0 > Regards Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v6 2/6] usb: core: split usb_phy_roothub_{init,alloc}
Before this patch usb_phy_roothub_init served two purposes (from a caller's point of view - like hcd.c): - parsing the PHYs and allocating the list entries - calling phy_init on each list entry While this worked so far it has one disadvantage: if we need to call phy_init for each PHY instance then the existing code cannot be re-used. Solve this by splitting off usb_phy_roothub_alloc which only parses the PHYs and allocates the list entries. usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls phy_init on each PHY instance (along with the corresponding cleanup if that failed somewhere). This is a preparation step for adding proper suspend support for some hardware that requires phy_exit to be called during suspend and phy_init to be called during resume. Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros Tested-by: Keerthy --- drivers/usb/core/hcd.c | 10 +--- drivers/usb/core/phy.c | 53 +- drivers/usb/core/phy.h | 4 +++- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 777036ae6367..15b0418e3b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); if (IS_ERR(hcd->phy_roothub)) { retval = PTR_ERR(hcd->phy_roothub); - goto err_phy_roothub_init; + goto err_phy_roothub_alloc; } + retval = usb_phy_roothub_init(hcd->phy_roothub); + if (retval) + goto err_phy_roothub_alloc; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd, usb_phy_roothub_power_off(hcd->phy_roothub); err_usb_phy_roothub_power_on: usb_phy_roothub_exit(hcd->phy_roothub); -err_phy_roothub_init: +err_phy_roothub_alloc: if (hcd->remove_phy && hcd->usb_phy) { usb_phy_shutdown(hcd->usb_phy); usb_put_phy(hcd->usb_phy); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index f19aaa3c899c..44f008cda7a8 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -19,19 +19,6 @@ struct usb_phy_roothub { struct list_headlist; }; -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) -{ - struct usb_phy_roothub *roothub_entry; - - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); - if (!roothub_entry) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&roothub_entry->list); - - return roothub_entry; -} - static int usb_phy_roothub_add_phy(struct device *dev, int index, struct list_head *list) { @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return PTR_ERR(phy); } - roothub_entry = usb_phy_roothub_alloc(dev); - if (IS_ERR(roothub_entry)) - return PTR_ERR(roothub_entry); + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return -ENOMEM; + + INIT_LIST_HEAD(&roothub_entry->list); roothub_entry->phy = phy; @@ -56,11 +45,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index, return 0; } -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) { struct usb_phy_roothub *phy_roothub; - struct usb_phy_roothub *roothub_entry; - struct list_head *head; int i, num_phys, err; num_phys = of_count_phandle_with_args(dev->of_node, "phys", @@ -68,16 +55,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) if (num_phys <= 0) return NULL; - phy_roothub = usb_phy_roothub_alloc(dev); - if (IS_ERR(phy_roothub)) - return phy_roothub; + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL); + if (!phy_roothub) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&phy_roothub->list); for (i = 0; i < num_phys; i++) { err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list); if (err) - goto err_out; + return ERR_PTR(err); } + return phy_ro
[PATCH usb v6 1/6] usb: core: phy: fix return value of usb_phy_roothub_exit()
usb_phy_roothub_exit() should return the error code from the phy_exit() call if exiting the PHY failed. However, since a wrong variable is used usb_phy_roothub_exit() currently always returns 0, even if one of the phy_exit calls returned an error. Clang also reports this bug: kernel/drivers/usb/core/phy.c:114:8: warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign] error, forbidden warning: phy.c:114 Fix this by assigning the error code from phy_exit() to the "ret" variable to propagate the error correctly. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Signed-off-by: Martin Blumenstingl Signed-off-by: Rishabh Bhatnagar Tested-by: Keerthy --- drivers/usb/core/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 09b7c43c0ea4..f19aaa3c899c 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -111,7 +111,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) list_for_each_entry(roothub_entry, head, list) { err = phy_exit(roothub_entry->phy); if (err) - ret = ret; + ret = err; } return ret; -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v6 4/6] usb: core: phy: make it a no-op if CONFIG_GENERIC_PHY is disabled
If the generic PHY support is disabled the stub of devm_of_phy_get_by_index returns ENOSYS. This corner case isn't handled properly by usb_phy_roothub_add_phy and at least breaks USB support on Raspberry Pi (bcm2835_defconfig): dwc2 2098.usb: dwc2_hcd_init() FAILED, returning -38 dwc2: probe of 2098.usb failed with error -38 Let usb_phy_roothub_alloc() return in case CONFIG_GENERIC_PHY is disabled to fix this issue (compilers might even be smart enough to optimize away most of the code within usb_phy_roothub_alloc and usb_phy_roothub_add_phy if CONFIG_GENERIC_PHY is disabled). All existing usb_phy_roothub_* functions are already NULL-safe, so no special handling is required there. Fixes: 07dbff0ddbd8 ("usb: core: add a wrapper for the USB PHYs on the HCD") Reported-by: Stefan Wahren Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index a39d9bb26a4f..9879767452a2 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -50,6 +50,9 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) struct usb_phy_roothub *phy_roothub; int i, num_phys, err; + if (!IS_ENABLED(CONFIG_GENERIC_PHY)) + return NULL; + num_phys = of_count_phandle_with_args(dev->of_node, "phys", "#phy-cells"); if (num_phys <= 0) -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v6 3/6] usb: core: use phy_exit during suspend if wake up is not supported
If the USB controller can wake up the system (which is the case for example with the Mediatek USB3 IP) then we must not call phy_exit during suspend to ensure that the USB controller doesn't have to re-enumerate the devices during resume. However, if the USB controller cannot wake up the system (which is the case for example on various TI platforms using a dwc3 controller) then we must call phy_exit during suspend. Otherwise the PHY driver keeps the clocks enabled, which prevents the system from reaching the lowest power levels in the suspend state. Solve this by introducing two new functions in the PHY wrapper which are dedicated to the suspend and resume handling. If the controller can wake up the system the new usb_phy_roothub_suspend function will simply call usb_phy_roothub_power_off. However, if wake up is not supported by the controller it will also call usb_phy_roothub_exit. The also new usb_phy_roothub_resume function takes care of calling usb_phy_roothub_init (if the controller can't wake up the system) in addition to usb_phy_roothub_power_on. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the HCD core") Reported-by: Roger Quadros Suggested-by: Roger Quadros Suggested-by: Chunfeng Yun Signed-off-by: Martin Blumenstingl Tested-by: Chunfeng Yun Reviewed-by: Roger Quadros Tested-by: Keerthy --- drivers/usb/core/hcd.c | 8 +--- drivers/usb/core/phy.c | 35 +++ drivers/usb/core/phy.h | 5 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15b0418e3b6a..78bae4ecd68b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_SUSPENDED; if (!PMSG_IS_AUTO(msg)) - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, + hcd->phy_roothub); /* Did we race with a root-hub wakeup event? */ if (rhdev->do_remote_wakeup) { @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } if (!PMSG_IS_AUTO(msg)) { - status = usb_phy_roothub_power_on(hcd->phy_roothub); + status = usb_phy_roothub_resume(hcd->self.sysdev, + hcd->phy_roothub); if (status) return status; } @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; - usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 44f008cda7a8..a39d9bb26a4f 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub) phy_power_off(roothub_entry->phy); } EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off); + +int usb_phy_roothub_suspend(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + usb_phy_roothub_power_off(phy_roothub); + + /* keep the PHYs initialized so the device can wake up the system */ + if (device_may_wakeup(controller_dev)) + return 0; + + return usb_phy_roothub_exit(phy_roothub); +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend); + +int usb_phy_roothub_resume(struct device *controller_dev, + struct usb_phy_roothub *phy_roothub) +{ + int err; + + /* if the device can't wake up the system _exit was called */ + if (!device_may_wakeup(controller_dev)) { + err = usb_phy_roothub_init(phy_roothub); + if (err) + return err; + } + + err = usb_phy_roothub_power_on(phy_roothub); + + /* undo _init if _power_on failed */ + if (err && !device_may_wakeup(controller_dev)) + usb_phy_roothub_exit(phy_roothub); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_resume); diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index eb31253201ad..60901d44 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -7,3 +7,8 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_power_on(struc
[PATCH usb v6 0/6] usb/core/phy fixes for v4.17
This is a follow-up to my previous series "initialize (multiple) PHYs for a HCD": [0]. Roger Quadros reported [1] that it "is breaking low power cases on TI SoCs when USB is in host mode". He further explains that "Not doing the phy_exit() here [when entering suspend] leaves the clocks enabled on our SoC and we're no longer able to reach low power states on system suspend." Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call phy_exit while entering system suspend, because this would "disconnect plugged devices on MTK platforms, due to re-initialize u2 phys when resume" In the discussion (which followed Roger's bug report: [1]) Roger, Chunfeng and me came to the conclusion that we can fix suspend on the TI SoCs without breaking it on the Mediatek SoCs by extending the suspend and resume code in usb/core/phy.c by checking whether the USB controller can wake up the system (which is the case for the Mediatek MTU3 controller, but now for the dwc3 controller used on the TI SoCs): - if the controller can wake up the system (Mediatek MTU3 use-case) we only call usb_phy_roothub_power_off (which calls phy_power_off) when entering system suspend - if the controller however cannot wake up the system (dwc3 on TI SoCs) we additionally call usb_phy_roothub_exit (which calls phy_exit) when entering system suspend - (we undo the previous steps during system resume) The goal of this series is to fix the issue reported by Roger without breaking suspend/resume on the Mediatek SoCs. Since I neither have a TI nor a Mediatek device I am sending this as RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which does NOT support suspend/resume yet. Additionally Stefan Wahren reported [7] that booting on a Raspberry Pi with CONFIG_GENERIC_PHY being disabled (which is the case for bcm2835_defconfig) breaks USB. A fix for this is also included. changes since v5 at [9] - rebased on top of v4.17-rc1 - added Keerthy's Tested-by to the first three patches (thank you!) - fixed a checkpatch warning (which was introduced in v4.17-rc1's checkpatch.pl) in patch #6 by using "/* SPDX-License-Identifier" instead of "// SPDX-License-Identifier" changes since v4 at [8] - updated series title since it now includes fixes for other functionality than suspend - rebased on top of f8cf2f16a7c95a from Linus' tree -> I will re-send an updated version once v4.17-rc1 is out, I just sent it early to get some feedback early! - included patch [3] "usb: core: phy: fix return value of usb_phy_roothub_exit()" in this series - fix the logic if CONFIG_GENERIC_PHY is disabled (as reported by Stefan Wahren, new patch #4) - two minor coding style fixes as suggested by Masahiro Yamada (new patches #4 and #5) changes since RFC v3 at [6]: - added Chunfeng Yun's Tested-by and Roger Quadros' Reviewed-by (thank you!) - dropped RFC prefix changes since RFC v2 at [5]: - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects patch #1 - spotted by Roger Quadros, thank you!) - fixed swapped conditions using device_may_wakeup() in usb_phy_roothub_resume because we need to call usb_phy_roothub_init if the controller cannot wake up the device (affects patch #2, spotted by Chunfeng Yun, thank you!) - simplified the error condition to "undo" usb_phy_roothub_init if usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested by Chunfeng Yun) - updated the commit message (using Roger's wording) because (quote from Roger "it doesn't prevent the system from entering suspend but just prevents the system from reaching lowest power levels in the suspend state." Changes since RFC v1 (blob attachments) at [4]: - use device_may_wakeup instead of device_can_wakeup as suggested by Roger Quadros - use the controller device from hcd->self.controller as suggested by Chunfeng Yun - compile time fixes thanks to Roger Quadros - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then we now call usb_phy_roothub_exit to keep the PHYs in the correct state if usb_phy_roothub_resume partially failed [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html [5] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006820.html [6] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006847.html [7] https://www.spinics.net/lists/linux-usb/msg167472.html [8] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006882.html [9] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/0070
[PATCH usb v6 6/6] usb: core: phy: add the SPDX-License-Identifier and include guard
This clarifies the license of the code. While here also add an include guard to the header file. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Suggested-by: Masahiro Yamada Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.h | 12 1 file changed, 12 insertions(+) diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index bbc969383074..88a3c037e9df 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -1,3 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * USB roothub wrapper + * + * Copyright (C) 2018 Martin Blumenstingl + */ + +#ifndef __USB_CORE_PHY_H_ +#define __USB_CORE_PHY_H_ + struct device; struct usb_phy_roothub; @@ -13,3 +23,5 @@ int usb_phy_roothub_suspend(struct device *controller_dev, struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_resume(struct device *controller_dev, struct usb_phy_roothub *phy_roothub); + +#endif /* __USB_CORE_PHY_H_ */ -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH usb v6 5/6] usb: core: phy: add missing forward declaration for "struct device"
Currently hcd.c is the only consumer of the usb_phy_roothub logic. This already includes the required header files so struct device is known. However, future consumers might not know about struct device. Add a forward declaration for struct device to fix potential future consumers which don't include any of the struct device API headers. Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD") Suggested-by: Masahiro Yamada Signed-off-by: Martin Blumenstingl --- drivers/usb/core/phy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 60901d44..bbc969383074 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -1,3 +1,4 @@ +struct device; struct usb_phy_roothub; struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); -- 2.17.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] USB: musb: dsps: phy fix and DT-topology support
Hello Johan, On Thu, Apr 19, 2018 at 9:43 AM, Johan Hovold wrote: > On Wed, Apr 18, 2018 at 09:18:30PM +0200, Martin Blumenstingl wrote: >> Hi Johan, >> >> On Fri, Apr 13, 2018 at 5:15 PM, Johan Hovold wrote: >> > I've been carrying a patch out-of-tree since my work on improving the >> > USB device-tree support which is needed to be able to describe USB >> > topologies for musb based controllers. >> > >> > This patch, which associates the platform controller device with the >> > glue device device-tree node, did not play well with the recent changes >> > which added generic phy support to USB core however. >> I'm the one who added this >> >> > Like the recent dwc2 regression fixed by Arnd after the device-tree >> > #phy-cell changes, the generic phy code in USB core can now also fail >> > indefinitly with -EPROBE_DEFER when the controller uses a legacy USB >> > phy. >> > >> > The second patch addresses this for musb, which handles its own (legacy >> > and generic) phys, but something more may possibly now be needed for >> > other platforms with legacy phys. >> I'm not sure if I understand the problem yet - could you please >> explain with your words what "legacy PHYs" are and how the "conflict" >> with the PHY handling in USB core? >> >> I am aware of two PHY subsystems: >> - drivers/phy >> -- also called "generic PHY framework" >> -- uses a "phys" property > > Right, and these are sometimes referred to as generic PHYs, as opposed > to... > >> - drivers/usb/phy >> -- also called "USB PHY framework" >> -- AFAIK this should not be used for new drivers > > ...the legacy ones. > >> -- uses an "usb-phy" property > > This is unfortunately not always the case however; some legacy USB phys > are also referred to using a "phys" property... oh, I was not aware of that. this explains the issue you're seeing... thank you for the explanation! >> the new PHY handling in USB core only parses the "phys" property and >> thus should not conflict with "usb-phy" (the legacy property) > >> however, I probably missed something so I'd appreciate an explanation >> how things can break > > ...and that is the problem. Specifically, since last fall when a number > of legacy-phy nodes had a #phy-cells property added to them (to silence > DTC warnings), the generic PHY subsubsystem can now return -EPROBE_DEFER > indefinitely when looking up a phy as it finds a matching device-tree > node, but for which there will never be a generic phy registered (since > it's handled by a legacy-phy driver). > > I referred to Arnd's workaround for "usb-nop-xceiv" devices > > b7563e2796f8 ("phy: work around 'phys' references to > usb-nop-xceiv devices") > > which has some more background on this. thank you for this pointer too > So if we have any other host controllers out there using > "phys"-properties with legacy phys other than "usb-nop-xceiv", then > these will now fail to register (with -EPROBE_DEFER) unless > hcd->skip_phy_initialization is set (or we blacklist them as well in the > generic phy code). > > I'm not aware of any further examples, but we're sure to find out soon > enough if there are. > > Perhaps we should blacklist also "ti,am335x-usb-phy" in the generic phy > code even if hcd->skip_phy_initialization is still needed for musb for > the time being anyway. > > Johan Regards Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH usb v6 6/6] usb: core: phy: add the SPDX-License-Identifier and include guard
Hi Greg, On Sun, Apr 22, 2018 at 3:01 PM, Greg KH wrote: > On Wed, Apr 18, 2018 at 09:39:51PM +0200, Martin Blumenstingl wrote: >> This clarifies the license of the code. While here also add an include >> guard to the header file. >> >> Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the >> HCD") >> Suggested-by: Masahiro Yamada >> Signed-off-by: Martin Blumenstingl >> --- >> drivers/usb/core/phy.h | 12 >> 1 file changed, 12 insertions(+) >> >> diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h >> index bbc969383074..88a3c037e9df 100644 >> --- a/drivers/usb/core/phy.h >> +++ b/drivers/usb/core/phy.h >> @@ -1,3 +1,13 @@ >> +/* SPDX-License-Identifier: GPL-2.0+ */ > > Do you _really_ mean GPLv2 or anything later? drivers/usb/core/hcd.c uses the same license identifier that code is much more "valuable" than my few lines which manage a list of PHYs - so I'm fine with "GPLv2 or anything later" > I have to ask... if you see any problems with this (for example that phy.h couldn't be used from some special module with another license, ...) then please let me know Regards Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] usb: dwc3: support clocks and resets for DWC3 core
Hello, On Thu, Apr 19, 2018 at 1:03 PM, Masahiro Yamada wrote: > Historically, the clocks and resets are handled on the glue layer > side instead of the DWC3 core. For simple cases, dwc3-of-simple.c > takes care of arbitrary number of clocks and resets. The DT node > structure typically looks like as follows: > > dwc3-glue { > compatible = "foo,dwc3"; > clocks = ...; > resets = ...; > ... > > dwc3 { > compatible = "snps,dwc3"; > ... > }; > } > > By supporting the clocks and the reset in the dwc3/core.c, it will > be turned into a single node: > > dwc3 { > compatible = "foo,dwc3", "snps,dwc3"; > clocks = ...; > resets = ...; > ... > } > > This commit adds the binding of clocks and resets specific to this IP. > The number of clocks should generally be the same across SoCs, it is > just some SoCs either tie clocks together or do not provide software > control of some of the clocks. > > I took the clock names from the Synopsys datasheet: "ref" (ref_clk), > "bus_early" (bus_clk_early), and "suspend" (suspend_clk). looking at the code: this could mean that dwc3-exynos.c can be removed mid-term (assuming the PHY and regulator handling can be moved/removed/changed) does the datasheet state anything about the clock speeds? from Documentation/devicetree/bindings/usb/dwc3-xilinx.txt: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS operation and >= 60MHz for HS operation > I found only one reset line in the datasheet, hence the reset-names > property is omitted. does the datasheet state whether this is a level or a pulsed reset line? on Amlogic Meson GXL, GXM and AXG SoCs we use a pulsed (and shared) reset line (see ff0a632f08759e "usb: dwc3: of-simple: add support for shared and pulsed reset lines") because the reset line is shared between various components (USB2 PHY, USB3 PHY, dwc3 controller, ...) your current approach (having a vendor-specific "foo,dwc3" binding along with the generic "snps,dwc3") would allow having per-"of_device_id" settings which could indicate whether the reset lines are level or pulsed reset if these are "implementation specific" > Supporting those clocks and resets is the requirement for new platforms. just to confirm: with this series your goal is to replace the wrapper node which is needed due to dwc3-of-simple.c ? would other drivers which currently create a wrapper node (like dwc3-keystone.c) keep their wrapper node or do you have any plans for removing it for the other "wrapper" drivers too? > Enforcing the new binding breaks existing platforms since they specify > clocks and resets in their glue layer node, but nothing in the core > node. I listed such exceptional cases in the DT binding. The driver > code is loosened up to accept no clock/reset. This change is based > on the discussion [1]. (snip) Regards Martin -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] usb: dwc3: support clocks and resets for DWC3 core
(adding Yixun from Amlogic to this mail) On Sat, Apr 28, 2018 at 4:41 AM, Masahiro Yamada wrote: > Hi Martin, > > > 2018-04-24 2:44 GMT+09:00 Martin Blumenstingl > : >> Hello, >> >> On Thu, Apr 19, 2018 at 1:03 PM, Masahiro Yamada >> wrote: >>> Historically, the clocks and resets are handled on the glue layer >>> side instead of the DWC3 core. For simple cases, dwc3-of-simple.c >>> takes care of arbitrary number of clocks and resets. The DT node >>> structure typically looks like as follows: >>> >>> dwc3-glue { >>> compatible = "foo,dwc3"; >>> clocks = ...; >>> resets = ...; >>> ... >>> >>> dwc3 { >>> compatible = "snps,dwc3"; >>> ... >>> }; >>> } >>> >>> By supporting the clocks and the reset in the dwc3/core.c, it will >>> be turned into a single node: >>> >>> dwc3 { >>> compatible = "foo,dwc3", "snps,dwc3"; >>> clocks = ...; >>> resets = ...; >>> ... >>> } >>> >>> This commit adds the binding of clocks and resets specific to this IP. >>> The number of clocks should generally be the same across SoCs, it is >>> just some SoCs either tie clocks together or do not provide software >>> control of some of the clocks. >>> >>> I took the clock names from the Synopsys datasheet: "ref" (ref_clk), >>> "bus_early" (bus_clk_early), and "suspend" (suspend_clk). >> looking at the code: this could mean that dwc3-exynos.c can be removed >> mid-term (assuming the PHY and regulator handling can be >> moved/removed/changed) >> >> does the datasheet state anything about the clock speeds? from >> Documentation/devicetree/bindings/usb/dwc3-xilinx.txt: >> "bus_clk" Master/Core clock, have to be >= 125 MHz for SS operation >> and >= 60MHz for HS operation >> >>> I found only one reset line in the datasheet, hence the reset-names >>> property is omitted. >> does the datasheet state whether this is a level or a pulsed reset line? >> on Amlogic Meson GXL, GXM and AXG SoCs we use a pulsed (and shared) >> reset line (see ff0a632f08759e "usb: dwc3: of-simple: add support for >> shared and pulsed reset lines") because the reset line is shared >> between various components (USB2 PHY, USB3 PHY, dwc3 controller, ...) >> your current approach (having a vendor-specific "foo,dwc3" binding >> along with the generic "snps,dwc3") would allow having >> per-"of_device_id" settings which could indicate whether the reset >> lines are level or pulsed reset if these are "implementation specific" > > Let me ask a question about your reset controller. > (drivers/reset/reset-meson.c) > > All reset ID supports .reset, .assert, .deassert > Is this correct? as far as I know: yes (though I have only ever verified this with the Ethernet controller's reset line) > > I believe you and I use the same DWC3 core IP. this is possible - but I am not sure since I don't have access to Amlogic's internal resources where this should be documented (my knowledge mostly comes from reading Amlogic's out-of-tree kernel code and porting that to mainline) > > I suspect the difference is in the reset controller side. > > In my case, the reset line is asserted by default. > (that is, all FFs in the RTL are put into the initial state > on power-on) > That's why only reset_deassert() will work for me, I think. > > What about your case? Is the reset line in deassert state on power-on? > Then, the reset must be explicitly pulsed to put FFs into > the initial state. Is this correct? let me give you a bit of context first: the Amlogic Meson AXG, GXL and GXM SoCs have one reset line for "USB components". this is shared among: - the dwc3 controller - (depending on the SoC) 2 or 3 USB2 PHYs - a USB3 PHY - some OTG detection logic within the registers of the USB3 PHY (there is also a gate clock which is assigned to the same components) based on my tests I believe that the reset line is "de-asserted" (= USB components are working) by default. asserting that reset line should stop the state machine of all USB components. de-asserting it again should bring all USB components into a defined state. (I'm not sure though if these are HW defaults or if there's some logic in the bootrom / early stage [pre u-boot] bootloaders) that sai
dwc2 (on Meson8b) doesn't detect "hot-plugged" USB devices
Hello, I was a bit surprised to see that hot-plugging USB devices on Amlogic Meson8b (for example: Odroid-C1) is broken. to be fair: I *think* it worked before, but I cannot guarantee it nor can I say when it broke all examples below are from an Odroid-C1 board with Amlogic Meson8b (S805) SoC. this connects a (fixed, soldered down) 4-port USB hub to the dwc2 controller (which is in "host" mode) during boot I see: [1.651687] dwc2 c90c.usb: c90c.usb supply vusb_d not found, using dummy regulator [1.654434] dwc2 c90c.usb: c90c.usb supply vusb_a not found, using dummy regulator [1.732374] dwc2 c90c.usb: dwc2_check_params: Invalid parameter lpm=1 [1.733526] dwc2 c90c.usb: dwc2_check_params: Invalid parameter lpm_clock_gating=1 [1.741427] dwc2 c90c.usb: dwc2_check_params: Invalid parameter besl=1 [1.748305] dwc2 c90c.usb: dwc2_check_params: Invalid parameter hird_threshold_en=1 [1.756491] dwc2 c90c.usb: DWC OTG Controller [1.760993] dwc2 c90c.usb: new USB bus registered, assigned bus number 1 [1.768046] dwc2 c90c.usb: irq 24, io mem 0xc90c [1.773947] hub 1-0:1.0: USB hub found [1.777063] hub 1-0:1.0: 1 port detected ... [2.212432] usb 1-1: new high-speed USB device number 2 using dwc2 [2.464742] hub 1-1:1.0: USB hub found [2.465118] hub 1-1:1.0: 4 ports detected if a USB device is plugged into one of the four USB ports during boot then it is detected automatically. if I plug in devices later they are not detected automatically (I have to run "lsusb -v" due to some reason, then hot-plugged devices are being detected) un-plugging USB devices is recognized instantly (no "lsusb" trickery is required) is this a known issue? how can I help debugging? any help is appreciated! below is the output of all dwc2 debugfs files. Regards Martin [rootodroidc1 c90c.usb]# cat dr_mode host [rootodroidc1 c90c.usb]# cat fifo Non-periodic FIFOs: RXFIFO: Size 0 NPTXFIFO: Size 0, Start 0x Periodic TXFIFOs: [rootodroidc1 c90c.usb]# cat hw_params op_mode : 5 arch : 2 dma_desc_enable : 1 enable_dynamic_fifo : 1 en_multiple_tx_fifo : 0 rx_fifo_size : 2048 host_nperio_tx_fifo_size : 2048 dev_nperio_tx_fifo_size : 0 host_perio_tx_fifo_size : 2048 nperio_tx_q_depth : 4 host_perio_tx_q_depth : 4 dev_token_q_depth : 8 max_transfer_size : 524287 max_packet_count : 1023 host_channels : 16 hs_phy_type : 1 fs_phy_type : 0 i2c_enable: 0 num_dev_ep: 2 num_dev_perio_in_ep : 0 total_fifo_size : 1984 power_optimized : 1 utmi_phy_data_width : 1 snpsid: 0x4f54310a dev_ep_dirs : 0x0 [rootodroidc1 c90c.usb]# cat params otg_cap : 2 dma_desc_enable : 0 dma_desc_fs_enable: 0 speed : 0 enable_dynamic_fifo : 1 en_multiple_tx_fifo : 0 host_rx_fifo_size : 512 host_nperio_tx_fifo_size : 500 host_perio_tx_fifo_size : 500 max_transfer_size : 524287 max_packet_count : 1023 host_channels : 16 phy_type : 1 phy_utmi_width: 16 phy_ulpi_ddr : 0 phy_ulpi_ext_vbus : 0 i2c_enable: 0 ulpi_fs_ls: 0 host_support_fs_ls_low_power : 0 host_ls_low_power_phy_clk : 0 ts_dline : 0 reload_ctl: 1 ahbcfg: 0xa uframe_sched : 0 external_id_pin_ctl : 0 power_down: 1 lpm : 0 lpm_clock_gating : 0 besl : 0 hird_threshold_en : 0 hird_threshold: 4 host_dma : 1 g_dma : 0 g_dma_desc: 0 g_rx_fifo_size: 0 g_np_tx_fifo_size : 0 g_tx_fifo_size[0] : 0 g_tx_fifo_size[1] : 0 g_tx_fifo_size[2] : 0 g_tx_fifo_size[3] : 0 g_tx_fifo_size[4] : 0 g_tx_fifo_size[5] : 0 g_tx_fifo_size[6] : 0 g_tx_fifo_size[7] : 0 g_tx_fifo_size[8] : 0 g_tx_fifo_size[9] : 0 g_tx_fifo_size[10]: 0 g_tx_fifo_size[11]: 0 g_tx_fifo_size[12]: 0 g_tx_fifo_size[13]: 0 g_tx_fifo_size[14]: 0 g_tx_fifo_size[15]: 0 [rootodroidc1 c90c.usb]# cat state DCFG=0x, DCTL=0x, DSTS=0x DIEPMSK=0x, DOEPMASK=0x GINTMSK=0xf000, GINTSTS=0x0001 DAINTMSK=0x, DAINT=0x G
Re: dwc2 (on Meson8b) doesn't detect "hot-plugged" USB devices
Hello Minas, On Mon, May 7, 2018 at 3:27 PM, Minas Harutyunyan wrote: > Hi Martin, > > On 5/7/2018 12:28 AM, Martin Blumenstingl wrote: >> Hello, >> >> I was a bit surprised to see that hot-plugging USB devices on Amlogic >> Meson8b (for example: Odroid-C1) is broken. >> to be fair: I *think* it worked before, but I cannot guarantee it nor >> can I say when it broke >> >> all examples below are from an Odroid-C1 board with Amlogic Meson8b (S805) >> SoC. >> this connects a (fixed, soldered down) 4-port USB hub to the dwc2 >> controller (which is in "host" mode) >> >> during boot I see: >> [1.651687] dwc2 c90c.usb: c90c.usb supply vusb_d not >> found, using dummy regulator >> [1.654434] dwc2 c90c.usb: c90c.usb supply vusb_a not >> found, using dummy regulator >> [1.732374] dwc2 c90c.usb: dwc2_check_params: Invalid parameter lpm=1 >> [1.733526] dwc2 c90c.usb: dwc2_check_params: Invalid parameter >> lpm_clock_gating=1 >> [1.741427] dwc2 c90c.usb: dwc2_check_params: Invalid parameter besl=1 >> [1.748305] dwc2 c90c.usb: dwc2_check_params: Invalid parameter >> hird_threshold_en=1 >> [1.756491] dwc2 c90c.usb: DWC OTG Controller >> [1.760993] dwc2 c90c.usb: new USB bus registered, assigned bus >> number 1 >> [1.768046] dwc2 c90c.usb: irq 24, io mem 0xc90c >> [1.773947] hub 1-0:1.0: USB hub found >> [1.777063] hub 1-0:1.0: 1 port detected >> ... >> [2.212432] usb 1-1: new high-speed USB device number 2 using dwc2 >> [2.464742] hub 1-1:1.0: USB hub found >> [2.465118] hub 1-1:1.0: 4 ports detected >> >> if a USB device is plugged into one of the four USB ports during boot >> then it is detected automatically. >> if I plug in devices later they are not detected automatically (I have >> to run "lsusb -v" due to some reason, then hot-plugged devices are >> being detected) >> un-plugging USB devices is recognized instantly (no "lsusb" trickery >> is required) >> >> is this a known issue? how can I help debugging? >> any help is appreciated! >> >> below is the output of all dwc2 debugfs files. >> >> >> Regards >> Martin >> >> >> [rootodroidc1 c90c.usb]# cat dr_mode >> host >> [rootodroidc1 c90c.usb]# cat fifo >> Non-periodic FIFOs: >> RXFIFO: Size 0 >> NPTXFIFO: Size 0, Start 0x >> >> Periodic TXFIFOs: >> [rootodroidc1 c90c.usb]# cat hw_params >> op_mode : 5 >> arch : 2 >> dma_desc_enable : 1 >> enable_dynamic_fifo : 1 >> en_multiple_tx_fifo : 0 >> rx_fifo_size : 2048 >> host_nperio_tx_fifo_size : 2048 >> dev_nperio_tx_fifo_size : 0 >> host_perio_tx_fifo_size : 2048 >> nperio_tx_q_depth : 4 >> host_perio_tx_q_depth : 4 >> dev_token_q_depth : 8 >> max_transfer_size : 524287 >> max_packet_count : 1023 >> host_channels : 16 >> hs_phy_type : 1 >> fs_phy_type : 0 >> i2c_enable: 0 >> num_dev_ep: 2 >> num_dev_perio_in_ep : 0 >> total_fifo_size : 1984 >> power_optimized : 1 >> utmi_phy_data_width : 1 >> snpsid: 0x4f54310a >> dev_ep_dirs : 0x0 >> [rootodroidc1 c90c.usb]# cat params >> otg_cap : 2 >> dma_desc_enable : 0 >> dma_desc_fs_enable: 0 >> speed : 0 >> enable_dynamic_fifo : 1 >> en_multiple_tx_fifo : 0 >> host_rx_fifo_size : 512 >> host_nperio_tx_fifo_size : 500 >> host_perio_tx_fifo_size : 500 >> max_transfer_size : 524287 >> max_packet_count : 1023 >> host_channels : 16 >> phy_type : 1 >> phy_utmi_width: 16 >> phy_ulpi_ddr : 0 >> phy_ulpi_ext_vbus : 0 >> i2c_enable: 0 >> ulpi_fs_ls: 0 >> host_support_fs_ls_low_power : 0 >> host_ls_low_power_phy_clk : 0 >> ts_dline : 0 >> reload_ctl: 1 >> ahbcfg: 0xa >> uframe_sched
Re: [PATCH 1/1] usb: chipidea: host: fix disconnection detect issue
Hi Peter, Hi Mats, On Wed, Jun 6, 2018 at 4:04 AM, Peter Chen wrote: > The commit 4e88d4c08301 ("usb: add a flag to skip PHY > initialization to struct usb_hcd") delete the assignment > for hcd->usb_phy, it causes usb_phy_notify_connect{disconnect) > are not called, the USB PHY driver is not notified of hot plug > event, then the disconnection will not be detected by hardware. ouch, I totally missed that thank you for taking time for bisecting, debugging and fixing this! > Fixes: 4e88d4c08301 ("usb: add a flag to skip PHY initialization > to struct usb_hcd") > Cc: Martin Blumenstingl > Reported-by: Mats Karrman > Signed-off-by: Peter Chen Acked-by: Martin Blumenstingl > --- > drivers/usb/chipidea/host.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c > index af45aa3222b5..4638d9b066be 100644 > --- a/drivers/usb/chipidea/host.c > +++ b/drivers/usb/chipidea/host.c > @@ -124,8 +124,11 @@ static int host_start(struct ci_hdrc *ci) > > hcd->power_budget = ci->platdata->power_budget; > hcd->tpl_support = ci->platdata->tpl_support; > - if (ci->phy || ci->usb_phy) > + if (ci->phy || ci->usb_phy) { > hcd->skip_phy_initialization = 1; > + if (ci->usb_phy) > + hcd->usb_phy = ci->usb_phy; > + } > > ehci = hcd_to_ehci(hcd); > ehci->caps = ci->hw_bank.cap; > -- > 2.14.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/3] initialize (multiple) PHYs in xhci-plat
Hi Greg, On Mon, Oct 2, 2017 at 2:44 PM, Greg KH wrote: > On Mon, Oct 02, 2017 at 02:35:08PM +0200, Jerome Brunet wrote: >> On Sun, 2017-10-01 at 22:32 +0200, Martin Blumenstingl wrote: >> > Hello Greg, Hello Mathias, >> > >> > On Mon, Sep 18, 2017 at 10:49 AM, Greg KH >> > wrote: >> > > On Sun, Sep 17, 2017 at 10:51:31PM +0200, Martin Blumenstingl wrote: >> > > > Hello Mathias, Hello Greg, >> > > > >> > > > On Sun, Sep 3, 2017 at 11:38 PM, Martin Blumenstingl >> > > > wrote: >> > > > > This series is the outcome of a discussion with Felipe Balbi, >> > > > > see [0] and [1]. >> > > > > The quick-summary of this is: >> > > > > - dwc3 already takes one USB2 and one USB3 PHY and initializes these >> > > > > correct >> > > > > - some other HCI platform drivers (like ehci-platform.c, xhci-mtk.c >> > > > > and >> > > > > ohci-platform.c) do not have a limitation on the number of PHYs - >> > > > > they >> > > > > support one PHY per actual host port >> > > > > - Amlogic Meson GXL and GXM SoCs come with a dwc3 IP block which has >> > > > > two >> > > > > or three USB2 ports enabled on the internal root-hub. The SoCs also >> > > > > provide separate USB2 PHYs, one per port. All USB2 PHYs (which are >> > > > > internally "connected" to the dwc3 roothub) need to be powered on, >> > > > > otherwise USB devices cannot be enumerated (even if just one PHY is >> > > > > disabled and if the device is plugged into another, enabled port) >> > > > > >> > > > > In my first attempt to get USB supported on the GXL and GXM SoCs I >> > > > > tried >> > > > > to work-around the problem that I could not pass multiple PHYs to the >> > > > > dwc3 controller. >> > > > > This was rejected by Rob Herring (which was definitely the thing to >> > > > > do >> > > > > in >> > > > > my opinion), see [2] >> > > > > >> > > > > This series adds a new "platform-roothub". This can be configured >> > > > > through >> > > > > devicetree by passing a child-node with "reg = <0>" to the USB >> > > > > controller. Additionally there has to be a child-node for each port >> > > > > on >> > > > > the root-hub. Each of the child-nodes takes a "phys" and "phy-names" >> > > > > property. This allows modeling the root-hub in devicetree similar to >> > > > > the >> > > > > USB device binding (documented in devicetree/bindings/usb/usb- >> > > > > device.txt) >> > > > > This avoids and backwards-compatibility problems (which was a concern >> > > > > regardless of the solution, see [3]) since the binding for the >> > > > > root-hub >> > > > > was previously not specified (and we're not using the "phys" >> > > > > property of >> > > > > the controller, which might have served different purposes before, >> > > > > depending on the drivers). >> > > > > >> > > > > Additionally this integrates the new platform-roothub into >> > > > > xhci-plat.c >> > > > > which automatically enables it for the dwc3 driver (in host-mode). >> > > > > >> > > > > >> > > > > Changes since RFCv3 at [6]: >> > > > > - moved the DT binding change from patch #3 to patch #1 as suggested >> > > > > by Rob Herring (and slightly adjusted the commit message to account >> > > > > for that) >> > > > > - added Tested-by from Chunfeng Yun (who confirmed that the whole >> > > > > concept and implementation works fine on Mediatek SoCs - many >> > > > > thanks >> > > > > again!) to patch #2 >> > > > > - added Rob Herring's ACK to patches 1 and 3 >> > > > > - dropped RFC status (RFCv3 -> PATCH v4) >> > > > >> > > > I just wanted to rebase this to v4.14-rc1 (now that this is out) - >> > > > however I noticed that v4 still applies to v4.14-rc1 cleanly (the >> > &g
Re: [PATCH v4 2/3] usb: host: add a generic platform USB roothub driver
Hi Mathias, thank you for taking the time to go through my patch On Wed, Oct 4, 2017 at 3:05 PM, Mathias Nyman wrote: > On 04.09.2017 00:38, Martin Blumenstingl wrote: >> >> Many SoC platforms have separate devices for the USB PHY which are >> registered through the generic PHY framework. These PHYs have to be >> enabled to make the USB controller actually work. They also have to be >> disabled again on shutdown/suspend. >> >> Currently (at least) the following HCI platform drivers are using custom >> code to obtain all PHYs via devicetree for the roothub/controller and >> disable/enable them when required: >> - ehci-platform.c has ehci_platform_power_{on,off} >> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} >> - ohci-platform.c has ohci_platform_power_{on,off} >> >> These drivers are not using the generic devicetree USB device bindings >> yet which were only introduced recently (documentation is available in >> devicetree/bindings/usb/usb-device.txt). >> With this new driver the usb2-phy and usb3-phy can be specified directly >> in the child-node of the corresponding port of the roothub via >> devicetree. This can be extended by not just parsing PHYs (some of the >> other drivers listed above are for example also parsing a list of clocks >> as well) when required. > > > usb_add_hcd() in usb/core/hcd.c is already finding, initializing and turning > on a phy, would it make sense to expand that one to support several phys > instead? > > xhci will add two hcd's one for USB2 and one for USB3 that is a great suggestion - thank you for bringing this up! as a benefit we would add multiple PHY support for all the other use-cases I found (at least: ehci-platform.c, xhci-mtk.c, ohci-platform.c) - instead of just handling this in xhci-plat.c I have one quick question regarding usb/core/hcd.c: are hcd_bus_suspend() and hcd_bus_resume() the right places to power_{off,on} the PHYs during suspend? (currently usb/core/hcd.c doesn't touch the PHY during suspend/resume - xhci-mtk.c on the other hand seems to require it during a suspend/resume cycle) >> >> Signed-off-by: Martin Blumenstingl >> Tested-by: Chunfeng Yun >> --- >> drivers/usb/host/Kconfig| 3 + >> drivers/usb/host/Makefile | 2 + >> drivers/usb/host/platform-roothub.c | 180 >> >> drivers/usb/host/platform-roothub.h | 12 +++ >> 4 files changed, 197 insertions(+) >> create mode 100644 drivers/usb/host/platform-roothub.c >> create mode 100644 drivers/usb/host/platform-roothub.h >> > > Instead of creating platform-roothub files could this content > be added into into core/hcd.*, core/phy.* and host/xhci-plat.c OK, I will try this and send a patch so we can have a look at the potential result and start a discussion based on that (if required) > >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig >> index fa5692dec832..b8b05c786b2a 100644 >> --- a/drivers/usb/host/Kconfig >> +++ b/drivers/usb/host/Kconfig >> @@ -805,6 +805,9 @@ config USB_HCD_SSB >> >> If unsure, say N. >> >> +config USB_PLATFORM_ROOTHUB >> + bool >> + >> config USB_HCD_TEST_MODE >> bool "HCD test mode support" >> ---help--- >> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile >> index cf2691fffcc0..dc817f82d632 100644 >> --- a/drivers/usb/host/Makefile >> +++ b/drivers/usb/host/Makefile >> @@ -29,6 +29,8 @@ obj-$(CONFIG_USB_WHCI_HCD)+= whci/ >> >> obj-$(CONFIG_USB_PCI) += pci-quirks.o >> >> +obj-$(CONFIG_USB_PLATFORM_ROOTHUB) += platform-roothub.o >> + >> obj-$(CONFIG_USB_EHCI_HCD)+= ehci-hcd.o >> obj-$(CONFIG_USB_EHCI_PCI)+= ehci-pci.o >> obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o >> diff --git a/drivers/usb/host/platform-roothub.c >> b/drivers/usb/host/platform-roothub.c >> new file mode 100644 >> index ..70d2d97aa8b2 >> --- /dev/null >> +++ b/drivers/usb/host/platform-roothub.c >> @@ -0,0 +1,180 @@ >> +/* >> + * platform roothub driver - a virtual PHY device which passes all phy_* >> + * function calls to multiple (actual) PHY devices. This is comes handy >> when >> + * initializing all PHYs on a root-hub (to keep them all in the same >> state). >> + * >> + * Copyright (C) 2017 Martin Blumenstingl >> >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License v
[RFC usb-next v5 3/3] usb: core: hcd: integrate the PHY roothub wrapper
This integrates the PHY roothub wrapper into the core hcd infrastructure. Multiple PHYs which are part of the roothub devicetree node (which is a sub-node of the sysdev's node) are now managed (= powered on/off when needed), by the new usb_phy_roothub code. One example where this is required is the Amlogic GXL and GXM SoCs: They are using a dwc3 USB controller with up to three ports enabled on the internal roothub. Using only the top-level "phy" properties does not work here since one can only specify one "usb2-phy" and one "usb3-phy", while actually at least two "usb2-phy" have to be specified. Signed-off-by: Martin Blumenstingl --- drivers/usb/core/hcd.c | 30 +- include/linux/usb/hcd.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 67aa3d039b9b..56704dd10c15 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -50,6 +50,7 @@ #include #include "usb.h" +#include "phy.h" /*-*/ @@ -2292,7 +2293,11 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "suspend", status); } - return status; + + if (status == 0) + return usb_phy_roothub_power_off(hcd->phy_roothub); + else + return status; } int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) @@ -2307,6 +2312,11 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); return 0; } + + status = usb_phy_roothub_power_on(hcd->phy_roothub); + if (status) + return status; + if (!hcd->driver->bus_resume) return -ENOENT; if (HCD_RH_RUNNING(hcd)) @@ -2344,6 +2354,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) } } else { hcd->state = old_state; + usb_phy_roothub_power_off(hcd->phy_roothub); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); if (status != -ESHUTDOWN) @@ -2780,6 +2791,16 @@ int usb_add_hcd(struct usb_hcd *hcd, } } + hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev); + if (IS_ERR(hcd->phy_roothub)) { + retval = PTR_ERR(hcd->phy_roothub); + goto err_phy_roothub_init; + } + + retval = usb_phy_roothub_power_on(hcd->phy_roothub); + if (retval) + goto err_usb_phy_roothub_power_on; + dev_info(hcd->self.controller, "%s\n", hcd->product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ @@ -2944,6 +2965,10 @@ int usb_add_hcd(struct usb_hcd *hcd, err_register_bus: hcd_buffer_destroy(hcd); err_create_buf: + usb_phy_roothub_power_off(hcd->phy_roothub); +err_usb_phy_roothub_power_on: + usb_phy_roothub_exit(hcd->phy_roothub); +err_phy_roothub_init: if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); @@ -3028,6 +3053,9 @@ void usb_remove_hcd(struct usb_hcd *hcd) usb_deregister_bus(&hcd->self); hcd_buffer_destroy(hcd); + usb_phy_roothub_power_off(hcd->phy_roothub); + usb_phy_roothub_exit(hcd->phy_roothub); + if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index a1f03ebfde47..6915b2afc209 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -103,6 +103,7 @@ struct usb_hcd { */ struct usb_phy *usb_phy; struct phy *phy; + struct usb_phy_roothub *phy_roothub; /* Flags that need to be manipulated atomically because they can * change while the host controller is running. Always use -- 2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC usb-next v5 0/3] initialize (multiple) PHYs on the roothub
ding example) - rebased to apply against latest usb-next [0] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001945.html [1] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001947.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001818.html [3] http://lists.infradead.org/pipermail/linux-amlogic/2017-January/001948.html [4] http://marc.info/?l=linux-usb&m=148414866303604&w=2 [5] https://www.spinics.net/lists/linux-usb/msg158967.html [6] https://www.spinics.net/lists/devicetree/msg190426.html [7] http://lists.infradead.org/pipermail/linux-amlogic/2017-October/004881.html [8] http://lists.infradead.org/pipermail/linux-amlogic/2017-October/004920.html [9] http://lists.infradead.org/pipermail/linux-amlogic/2017-September/004685.html Martin Blumenstingl (3): dt-bindings: usb: add the documentation for USB root-hub usb: core: add a wrapper for the USB PHYs on the root-hub usb: core: hcd: integrate the PHY roothub wrapper .../devicetree/bindings/usb/usb-roothub.txt| 46 ++ Documentation/devicetree/bindings/usb/usb-xhci.txt | 7 + drivers/usb/core/Makefile | 2 +- drivers/usb/core/hcd.c | 30 +++- drivers/usb/core/phy.c | 184 + drivers/usb/core/phy.h | 7 + include/linux/usb/hcd.h| 1 + 7 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt create mode 100644 drivers/usb/core/phy.c create mode 100644 drivers/usb/core/phy.h -- 2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC usb-next v5 2/3] usb: core: add a wrapper for the USB PHYs on the root-hub
Many SoC platforms have separate devices for the USB PHY which are registered through the generic PHY framework. These PHYs have to be enabled to make the USB controller actually work. They also have to be disabled again on shutdown/suspend. Currently (at least) the following HCI platform drivers are using custom code to obtain all PHYs via devicetree for the roothub/controller and disable/enable them when required: - ehci-platform.c has ehci_platform_power_{on,off} - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} - ohci-platform.c has ohci_platform_power_{on,off} These drivers are not using the generic devicetree USB device bindings (for the root-hub) yet which were only introduced recently (documentation is available in devicetree/bindings/usb/usb-device.txt). With this new wrapper the usb2-phy and usb3-phy can be specified directly in the child-node of the corresponding port of the roothub via devicetree. This allows SoCs like the Amlogic Meson GXL family to operate correctly because all USB PHYs are initialized (instead of the first USB PHY only). Signed-off-by: Martin Blumenstingl --- drivers/usb/core/Makefile | 2 +- drivers/usb/core/phy.c| 184 ++ drivers/usb/core/phy.h| 7 ++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/core/phy.c create mode 100644 drivers/usb/core/phy.h diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 250ec1d662d9..b6e181d08bf6 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -5,7 +5,7 @@ usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o usbcore-y += devio.o notify.o generic.o quirks.o devices.o -usbcore-y += port.o +usbcore-y += phy.o port.o usbcore-$(CONFIG_OF) += of.o usbcore-$(CONFIG_USB_PCI) += hcd-pci.o diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c new file mode 100644 index ..d90a55b2ae08 --- /dev/null +++ b/drivers/usb/core/phy.c @@ -0,0 +1,184 @@ +/* + * USB PHY roothub driver - a wrapper for multiple PHYs which passes all phy_* + * function calls to multiple (actual) PHY devices. This is comes handy when + * initializing all PHYs on a root-hub and to keep them all in the same state. + * + * Copyright (C) 2017 Martin Blumenstingl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "phy.h" + +#define ROOTHUB_PORTNUM0 + +struct usb_phy_roothub { + struct phy *phy; + struct list_headlist; +}; + +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev) +{ + struct usb_phy_roothub *roothub_entry; + + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); + if (!roothub_entry) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&roothub_entry->list); + + return roothub_entry; +} + +static int usb_phy_roothub_add_phy(struct device *dev, + struct device_node *port_np, + const char *con_id, struct list_head *list) +{ + struct usb_phy_roothub *roothub_entry; + struct phy *phy = devm_of_phy_get(dev, port_np, con_id); + + if (IS_ERR_OR_NULL(phy)) { + if (!phy || PTR_ERR(phy) == -ENODEV) + return 0; + else + return PTR_ERR(phy); + } + + roothub_entry = usb_phy_roothub_alloc(dev); + if (IS_ERR(roothub_entry)) + return PTR_ERR(roothub_entry); + + roothub_entry->phy = phy; + + list_add_tail(&roothub_entry->list, list); + + return 0; +} + +struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev) +{ + struct device_node *roothub_np, *port_np; + struct usb_phy_roothub *phy_roothub; + struct usb_phy_roothub *roothub_entry; + struct list_head *head; + int err; + + roothub_np = usb_of_get_child_node(dev->of_node, ROOTHUB_PORTNUM); + if (!of_device_is_available(roothub_np)) { + dev_err(dev, "no roothub node found\n"); + return NULL; + } + + phy_roothub = usb_phy_roothub_alloc(dev); + if (IS_ERR(phy_roothub)) + return phy_roothub; + + for_each_available_child_of_node(roothub_np, port_np) { + err = usb_phy_roothub_add_phy(dev, port_np, "usb2-phy", + &phy_roothub->list)