mbox series

[0/8] USB: add device-tree support for interfaces

Message ID 20171109170723.10960-1-johan@kernel.org
Headers show
Series USB: add device-tree support for interfaces | expand

Message

Johan Hovold Nov. 9, 2017, 5:07 p.m. UTC
This series adds support for representing USB interfaces in device tree
by implementing support for "interface nodes" and "combined nodes" from
the OF specification.

This is needed to be able to describe non-discoverable properties of
permanently attached USB devices and their interfaces such as any
i2c-clients connected to a USB-i2c bridge (e.g. the dln2 mfd) or,
eventually, devices connected to usb-serial converters (to be used with
serdev).

As part of this series the current binding for USB devices is cleaned
up and some already-used properties of "host-controller nodes" and "hub
nodes" are explicitly defined.

While doing this work I realised that a broken binding for USB-port LED
triggers had recently been merged. This trigger implementation assumes
an undocumented and conflicting binding for USB (root) hub ports, which
in fact lack a representation in device tree (the child nodes of hub
nodes represent the attached USB devices):

	80dc6e1cd85f ("dt-bindings: leds: document new trigger-sources property")

In this series I only address an of_node leak in the trigger
implementation and add a FIXME about the port/device mixup. Note that
some broadcom dts have already started using such a "port" binding:

	a503cf0cbe66 ("ARM: dts: BCM53573: Specify USB ports of on-SoC controllers")
	69d22c70ac9a ("ARM: dts: BCM5301X: Specify USB ports for each controller")

To fix this, any triggers need to be described using properties of the
host-controller (or hub) rather than of their children.

Johan


Johan Hovold (8):
  dt-bindings: usb: fix example hub node name
  dt-bindings: usb: fix reg-property port-number range
  dt-bindings: usb: clean up compatible property
  dt-bindings: usb: document hub and host-controller properties
  dt-bindings: usb: add interface binding
  USB: add device-tree support for interfaces
  USB: ledtrig-usbport: fix of-node leak
  USB: of: clean up device-node helper

 .../devicetree/bindings/usb/usb-device.txt         | 99 +++++++++++++++++++---
 drivers/usb/core/ledtrig-usbport.c                 | 10 ++-
 drivers/usb/core/message.c                         | 18 ++--
 drivers/usb/core/of.c                              | 95 ++++++++++++++++++---
 drivers/usb/core/usb.c                             |  3 +-
 include/linux/usb/of.h                             | 21 ++++-
 6 files changed, 208 insertions(+), 38 deletions(-)

Comments

Rob Herring (Arm) Nov. 16, 2017, 2:43 p.m. UTC | #1
On Thu, Nov 09, 2017 at 06:07:15PM +0100, Johan Hovold wrote:
> This series adds support for representing USB interfaces in device tree
> by implementing support for "interface nodes" and "combined nodes" from
> the OF specification.
> 
> This is needed to be able to describe non-discoverable properties of
> permanently attached USB devices and their interfaces such as any
> i2c-clients connected to a USB-i2c bridge (e.g. the dln2 mfd) or,
> eventually, devices connected to usb-serial converters (to be used with
> serdev).

In the original OF binding, the firmware dynamically generated the tree 
for the active configuration AIUI. That doesn't really fit for the 
(mostly) static FDT usage and why we stopped at the device level. So how 
do we handle multiple configs? Or can we assume that if say the I2C bus 
is used, then there's only one config and interface that can use it?

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johan Hovold Nov. 16, 2017, 4:12 p.m. UTC | #2
On Thu, Nov 16, 2017 at 08:43:21AM -0600, Rob Herring wrote:
> On Thu, Nov 09, 2017 at 06:07:15PM +0100, Johan Hovold wrote:
> > This series adds support for representing USB interfaces in device tree
> > by implementing support for "interface nodes" and "combined nodes" from
> > the OF specification.
> > 
> > This is needed to be able to describe non-discoverable properties of
> > permanently attached USB devices and their interfaces such as any
> > i2c-clients connected to a USB-i2c bridge (e.g. the dln2 mfd) or,
> > eventually, devices connected to usb-serial converters (to be used with
> > serdev).
> 
> In the original OF binding, the firmware dynamically generated the tree 
> for the active configuration AIUI. That doesn't really fit for the 
> (mostly) static FDT usage and why we stopped at the device level. So how 
> do we handle multiple configs? Or can we assume that if say the I2C bus 
> is used, then there's only one config and interface that can use it?

Multiple configuration can be used to implement different sets of
functionality. A hypothetical device could have one i2c controller in
one configuration and two in another. Most devices will only have one
configuration though.

A USB interface implements some functionality of the device (and this is
what Linux USB drivers bind to). So even for single-configuration
devices, you need to be able to say which i2c controller (bus) you are
describing.

[ And as a simplification, the combined nodes can be used for most cases
were we only have one configuration with a single interface. ]

Note that a new set of interfaces (in the kernel device model) is
created when a new USB device configuration is selected. These new
interfaces will be associated with any matching device-tree interface
nodes and that these would be distinct from any nodes that matches
another configuration.

So I don't think there's any problem with dealing with the rare cases of
multi-configuration devices. 

Johan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring (Arm) Nov. 16, 2017, 6:33 p.m. UTC | #3
On Thu, Nov 16, 2017 at 10:12 AM, Johan Hovold <johan@kernel.org> wrote:
> On Thu, Nov 16, 2017 at 08:43:21AM -0600, Rob Herring wrote:
>> On Thu, Nov 09, 2017 at 06:07:15PM +0100, Johan Hovold wrote:
>> > This series adds support for representing USB interfaces in device tree
>> > by implementing support for "interface nodes" and "combined nodes" from
>> > the OF specification.
>> >
>> > This is needed to be able to describe non-discoverable properties of
>> > permanently attached USB devices and their interfaces such as any
>> > i2c-clients connected to a USB-i2c bridge (e.g. the dln2 mfd) or,
>> > eventually, devices connected to usb-serial converters (to be used with
>> > serdev).
>>
>> In the original OF binding, the firmware dynamically generated the tree
>> for the active configuration AIUI. That doesn't really fit for the
>> (mostly) static FDT usage and why we stopped at the device level. So how
>> do we handle multiple configs? Or can we assume that if say the I2C bus
>> is used, then there's only one config and interface that can use it?
>
> Multiple configuration can be used to implement different sets of
> functionality. A hypothetical device could have one i2c controller in
> one configuration and two in another. Most devices will only have one
> configuration though.

Right, but ultimately the device has the physical interface (pins) and
we could have multiple USB interfaces pointing to the single physical
interface. How do we represent that without duplicating the DT data in
both interfaces? I guess we can do a phandle to the I2C bus as we do
sometimes.

> A USB interface implements some functionality of the device (and this is
> what Linux USB drivers bind to). So even for single-configuration
> devices, you need to be able to say which i2c controller (bus) you are
> describing.

Are you saying the mapping of USB interface to physical interface
cannot be implied by the specific device? Say, we had something like
this:

usb-device {
  i2c-bus@0 {};
  i2c-bus@1 {};
};

Where 0 and 1 are based on the pin out of the device. There's no way
for the driver to figure out the mapping of USB interfaces to i2c bus?
How does the user writing the DT do it?

> [ And as a simplification, the combined nodes can be used for most cases
> were we only have one configuration with a single interface. ]
>
> Note that a new set of interfaces (in the kernel device model) is
> created when a new USB device configuration is selected. These new
> interfaces will be associated with any matching device-tree interface
> nodes and that these would be distinct from any nodes that matches
> another configuration.
>
> So I don't think there's any problem with dealing with the rare cases of
> multi-configuration devices.

Perhaps it is rare enough that we don't worry about the above case.

I'm not saying we shouldn't follow the OF spec here, but I also think
our usecases have changed a bit in 20 years so we could want to do
something different.

The other part of this is how do we make this usecase work on non-DT
systems or DT systems where the USB topology is not fully described
because you're just hotplugging the USB device.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johan Hovold Nov. 17, 2017, 4:30 p.m. UTC | #4
On Thu, Nov 16, 2017 at 12:33:33PM -0600, Rob Herring wrote:
> On Thu, Nov 16, 2017 at 10:12 AM, Johan Hovold <johan@kernel.org> wrote:
> > On Thu, Nov 16, 2017 at 08:43:21AM -0600, Rob Herring wrote:
> >> On Thu, Nov 09, 2017 at 06:07:15PM +0100, Johan Hovold wrote:
> >> > This series adds support for representing USB interfaces in device tree
> >> > by implementing support for "interface nodes" and "combined nodes" from
> >> > the OF specification.
> >> >
> >> > This is needed to be able to describe non-discoverable properties of
> >> > permanently attached USB devices and their interfaces such as any
> >> > i2c-clients connected to a USB-i2c bridge (e.g. the dln2 mfd) or,
> >> > eventually, devices connected to usb-serial converters (to be used with
> >> > serdev).
> >>
> >> In the original OF binding, the firmware dynamically generated the tree
> >> for the active configuration AIUI. That doesn't really fit for the
> >> (mostly) static FDT usage and why we stopped at the device level. So how
> >> do we handle multiple configs? Or can we assume that if say the I2C bus
> >> is used, then there's only one config and interface that can use it?
> >
> > Multiple configuration can be used to implement different sets of
> > functionality. A hypothetical device could have one i2c controller in
> > one configuration and two in another. Most devices will only have one
> > configuration though.
> 
> Right, but ultimately the device has the physical interface (pins) and
> we could have multiple USB interfaces pointing to the single physical
> interface. How do we represent that without duplicating the DT data in
> both interfaces? I guess we can do a phandle to the I2C bus as we do
> sometimes.

Yeah, that could lead to some duplication. Also note that configurations
can have different properties such as maximum power consumption, and
that, again hypothetically, some of those external i2c clients may not
be available in every configuration.

> > A USB interface implements some functionality of the device (and this is
> > what Linux USB drivers bind to). So even for single-configuration
> > devices, you need to be able to say which i2c controller (bus) you are
> > describing.
> 
> Are you saying the mapping of USB interface to physical interface
> cannot be implied by the specific device? Say, we had something like
> this:
> 
> usb-device {
>   i2c-bus@0 {};
>   i2c-bus@1 {};
> };
> 
> Where 0 and 1 are based on the pin out of the device. There's no way
> for the driver to figure out the mapping of USB interfaces to i2c bus?

Not without extra information, no.

> How does the user writing the DT do it?

By verifying the actual device used and encoding it in DT. Remember that
USB typically deals with classes of devices and interfaces. The same USB
(interface) driver can be used for a multitude of devices from various
vendors, who could have ended up wiring those physical connectors
differently. So either this information needs to added to the driver
(e.g. supplement the generic class matching with, say, VID/PID and match
data entries), or it is provided through DT, which seems preferred.

Take for example the generic cdc-acm driver which typically matches on
the interface class and knows nothing about any (other) physical ports.

> > [ And as a simplification, the combined nodes can be used for most cases
> > were we only have one configuration with a single interface. ]
> >
> > Note that a new set of interfaces (in the kernel device model) is
> > created when a new USB device configuration is selected. These new
> > interfaces will be associated with any matching device-tree interface
> > nodes and that these would be distinct from any nodes that matches
> > another configuration.
> >
> > So I don't think there's any problem with dealing with the rare cases of
> > multi-configuration devices.
> 
> Perhaps it is rare enough that we don't worry about the above case.
> 
> I'm not saying we shouldn't follow the OF spec here, but I also think
> our usecases have changed a bit in 20 years so we could want to do
> something different.

Fair enough, but it seems to me that we actually want to describe also
interfaces in DT to avoid encoding interface-node mappings and implement
lookups in every driver.

For completeness, I should also point out that there are USB interfaces
implementing various forms of MFDs. I already mentioned the dln2 driver,
where all cell components would be described as the children of an
interface (or combined node), for example:

	usb-device {	// combined node, since only one interface
		gpio {}:
		i2c {};
		spi {};
	};

So we do not have a one-controller-per-interface mapping here.

For USB serial, there are examples of both 1-1 and 1-many mappings and
my current plan for describing them as follows:

	usb-device2 {	// combined node (single interface)
		serial@0 {};
		serial@1 {};
	};

	usb-device3 {
		interface@0 {
			serial@0 {};
		};
		interface@1 {
			serial@0 {};
		};
	};

And note that in the former case, the driver indeed also needs to be
aware of the physical port mapping (for its interface).

But perhaps I'm getting ahead of myself here.

> The other part of this is how do we make this usecase work on non-DT
> systems or DT systems where the USB topology is not fully described
> because you're just hotplugging the USB device.

Yep, that remains to be determined, but that's not directly related to
this series, which primarly extends and what we currently have (which is
a way of describing permanently attached hubs and devices).

It should be possible to generate and insert device-tree nodes when node
look-up fails during bus enumeration. If we ever get support for loading
overlays from user space, these could then be attached to leaf nodes
(whose drivers would need to be reprobed or at least notified).

But I haven't thought too much about that yet.

Johan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html