Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-04-06 Thread Masahiro Yamada
2018-04-06 14:15 GMT+09:00 Martin Blumenstingl
:

>>
>> When will this be available in Linus' tree?   In the current MW?
> this is already available in Linus' tree. the commit for this specific
> patch (#3) is known as 07dbff0ddbd86c


Oh, great!  Thank you.



>> Sure, I can send a patch after some flaws are ironed-out.
> great, thank you!
> could you also let me know once you have tested this on one of your SoCs?

I will.





-- 
Best Regards
Masahiro Yamada
--
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

2018-04-05 Thread Martin Blumenstingl
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(_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(_entry->list, list);
 +
 +   return 0;
 +}
 +
 +struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
 +{
 +   struct usb_phy_roothub *phy_roothub;
 +   struct usb_phy_roothub *roothub_entry;
 +   struct list_head *head;
 +   int i, num_phys, err;
 

Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-04-05 Thread Masahiro Yamada
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(_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(_entry->list, list);
>>> +
>>> +   return 0;
>>> +}
>>> +
>>> +struct usb_phy_roothub *usb_phy_roothub_init(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",
>>> + "#phy-cells");
>>> +   if (num_phys <= 0)
>>> +   return NULL;
>>> +
>>> +

Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-04-05 Thread 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(_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(_entry->list, list);
>> +
>> +   return 0;
>> +}
>> +
>> +struct usb_phy_roothub *usb_phy_roothub_init(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",
>> + "#phy-cells");
>> +   if (num_phys <= 0)
>> +   return NULL;
>> +
>> +   phy_roothub = usb_phy_roothub_alloc(dev);
>> +   if (IS_ERR(phy_roothub))
>> +   return phy_roothub;
>> +
>> +   for (i = 0; i < num_phys; i++) {
>> +   err = usb_phy_roothub_add_phy(dev, 

Re: [usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-04-04 Thread Masahiro Yamada
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(_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(_entry->list, list);
> +
> +   return 0;
> +}
> +
> +struct usb_phy_roothub *usb_phy_roothub_init(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",
> + "#phy-cells");
> +   if (num_phys <= 0)
> +   return NULL;
> +
> +   phy_roothub = usb_phy_roothub_alloc(dev);
> +   if (IS_ERR(phy_roothub))
> +   return phy_roothub;
> +
> +   for (i = 0; i < num_phys; i++) {
> +   err = usb_phy_roothub_add_phy(dev, i, _roothub->list);
> +   if (err)
> +   goto err_out;
> +   }
> +
> +   head = _roothub->list;


I think phy_roothub->phy is always empty,
and only phy_roothub->list is used.


I just wondered if we can directly put 'struct list_head' into
'struct usb_hcd'.






[usb-next PATCH v11 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-03 Thread 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(_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(_entry->list, list);
+
+   return 0;
+}
+
+struct usb_phy_roothub *usb_phy_roothub_init(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",
+ "#phy-cells");
+   if (num_phys <= 0)
+   return NULL;
+
+   phy_roothub = usb_phy_roothub_alloc(dev);
+   if (IS_ERR(phy_roothub))
+   return phy_roothub;
+
+   for (i = 0; i < num_phys; i++) {
+   err = usb_phy_roothub_add_phy(dev, i, _roothub->list);
+   if (err)
+   goto err_out;
+   }
+
+   head = _roothub->list;
+
+   list_for_each_entry(roothub_entry, head, list) {
+   err = phy_init(roothub_entry->phy);
+   if (err)
+   goto err_exit_phys;
+   }
+
+   return phy_roothub;
+
+err_exit_phys:
+   list_for_each_entry_continue_reverse(roothub_entry, head, list)
+   phy_exit(roothub_entry->phy);
+
+err_out:
+   return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_init);
+
+int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub)
+{
+