diff mbox series

[v2,6/9] usb: roles: Find the muxes by also matching against the device node

Message ID 20190130160259.46919-7-heikki.krogerus@linux.intel.com (mailing list archive)
State Superseded
Headers show
Series device connection: Add support for device graphs | expand

Commit Message

Heikki Krogerus Jan. 30, 2019, 4:02 p.m. UTC
When the connections are defined in firmware, struct
device_connection will have the fwnode member pointing to
the device node (struct fwnode_handle) of the requested
device, and the endpoint will not be used at all in that
case.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/roles/class.c | 21 ++++++++++++++++++---
 include/linux/usb/role.h  |  1 +
 2 files changed, 19 insertions(+), 3 deletions(-)

Comments

Jun Li Feb. 11, 2019, 9:58 a.m. UTC | #1
Hi Heikki,

> @@ -84,7 +85,12 @@ enum usb_role usb_role_switch_get_role(struct
> usb_role_switch *sw)  }  EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
> 
> -static int __switch_match(struct device *dev, const void *name)
> +static int switch_fwnode_match(struct device *dev, const void *fwnode)
> +{
> +	return dev_fwnode(dev) == fwnode;

You missed the comment
https://lkml.org/lkml/2019/1/22/437

return dev_fwnode(dev->parent) == fwnode;

Jun
Heikki Krogerus Feb. 11, 2019, 10:46 a.m. UTC | #2
On Mon, Feb 11, 2019 at 09:58:04AM +0000, Jun Li wrote:
> Hi Heikki,
> 
> > @@ -84,7 +85,12 @@ enum usb_role usb_role_switch_get_role(struct
> > usb_role_switch *sw)  }  EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
> > 
> > -static int __switch_match(struct device *dev, const void *name)
> > +static int switch_fwnode_match(struct device *dev, const void *fwnode)
> > +{
> > +	return dev_fwnode(dev) == fwnode;
> 
> You missed the comment
> https://lkml.org/lkml/2019/1/22/437
> 
> return dev_fwnode(dev->parent) == fwnode;

That's actually not the case. struct usb_role_switch_desc has a member
for fwnode, and that's what we use with the actual mux device. Check
usb_role_switch_register():

        ...
        sw->dev.fwnode = desc->fwnode;
        ...

Sorry for not realizing it before.


thanks,
Heikki Krogerus Feb. 11, 2019, 12:40 p.m. UTC | #3
On Mon, Feb 11, 2019 at 12:46:29PM +0200, Heikki Krogerus wrote:
> On Mon, Feb 11, 2019 at 09:58:04AM +0000, Jun Li wrote:
> > Hi Heikki,
> > 
> > > @@ -84,7 +85,12 @@ enum usb_role usb_role_switch_get_role(struct
> > > usb_role_switch *sw)  }  EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
> > > 
> > > -static int __switch_match(struct device *dev, const void *name)
> > > +static int switch_fwnode_match(struct device *dev, const void *fwnode)
> > > +{
> > > +	return dev_fwnode(dev) == fwnode;
> > 
> > You missed the comment
> > https://lkml.org/lkml/2019/1/22/437
> > 
> > return dev_fwnode(dev->parent) == fwnode;
> 
> That's actually not the case. struct usb_role_switch_desc has a member
> for fwnode, and that's what we use with the actual mux device. Check
> usb_role_switch_register():
> 
>         ...
>         sw->dev.fwnode = desc->fwnode;
>         ...
> 
> Sorry for not realizing it before.

Just to clarify. The current patch is OK. No changes needed.


thanks,
Jun Li Feb. 12, 2019, 6:03 a.m. UTC | #4
> -----Original Message-----
> From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Sent: 2019年2月11日 18:46
> To: Jun Li <jun.li@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Andy Shevchenko
> <andy.shevchenko@gmail.com>; Chen Yu <chenyu56@huawei.com>; Hans de
> Goede <hdegoede@redhat.com>; linux-usb@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2 6/9] usb: roles: Find the muxes by also matching against the
> device node
> 
> On Mon, Feb 11, 2019 at 09:58:04AM +0000, Jun Li wrote:
> > Hi Heikki,
> >
> > > @@ -84,7 +85,12 @@ enum usb_role usb_role_switch_get_role(struct
> > > usb_role_switch *sw)  }
> > > EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
> > >
> > > -static int __switch_match(struct device *dev, const void *name)
> > > +static int switch_fwnode_match(struct device *dev, const void
> > > +*fwnode) {
> > > +	return dev_fwnode(dev) == fwnode;
> >
> > You missed the comment
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkm
> >
> l.org%2Flkml%2F2019%2F1%2F22%2F437&amp;data=02%7C01%7Cjun.li%40nx
> p.com
> > %7C8c2d40d5e5d246da34ad08d6900e31cf%7C686ea1d3bc2b4c6fa92cd99c5
> c301635
> > %7C0%7C0%7C636854788040965224&amp;sdata=db4gvXKc9InWiltsweetxXYr
> tPbtfX
> > jshPh%2FnvA24ig%3D&amp;reserved=0
> >
> > return dev_fwnode(dev->parent) == fwnode;
> 
> That's actually not the case. struct usb_role_switch_desc has a member for fwnode,
> and that's what we use with the actual mux device. Check
> usb_role_switch_register():
> 
>         ...
>         sw->dev.fwnode = desc->fwnode;
>         ...
> 
> Sorry for not realizing it before.

So desc->fwnode should be initialized before do usb_role_switch_register()?
But seems usb_role_switch_desc is a read-only object so can't be set at runtime.

usb_controller_node {
	...
	usb-role-switch;

	port {
		sw_provider_node: endpoint {
			remote-endpoint = <&sw_consumer_node>;
		};
	};
};

typec_node {
	...
	port {
		sw_consumer_node: endpoint {
			remote-endpoint = <&sw_provider_node>;
		};
	};
};

Is my understanding correct?

Thanks
Jun
> 
> 
> thanks,
> 
> --
> heikki
Heikki Krogerus Feb. 12, 2019, 8:50 a.m. UTC | #5
Hi,

On Tue, Feb 12, 2019 at 06:03:42AM +0000, Jun Li wrote:
> > > return dev_fwnode(dev->parent) == fwnode;
> > 
> > That's actually not the case. struct usb_role_switch_desc has a member for fwnode,
> > and that's what we use with the actual mux device. Check
> > usb_role_switch_register():
> > 
> >         ...
> >         sw->dev.fwnode = desc->fwnode;
> >         ...
> > 
> > Sorry for not realizing it before.
> 
> So desc->fwnode should be initialized before do usb_role_switch_register()?
> But seems usb_role_switch_desc is a read-only object so can't be set at runtime.

It can. Even though usb_role_switch_register() takes read-only
parameter, nothing's preventing you from passing data even from the
stack (the content of the descriptor is copied in any case).

Expecting the descriptor to be read-only just means it can be
read-only, but it does not have to be.

> usb_controller_node {
> 	...
> 	usb-role-switch;
> 
> 	port {
> 		sw_provider_node: endpoint {
> 			remote-endpoint = <&sw_consumer_node>;
> 		};
> 	};
> };
> 
> typec_node {
> 	...
> 	port {
> 		sw_consumer_node: endpoint {
> 			remote-endpoint = <&sw_provider_node>;
> 		};
> 	};
> };

That looks roughly correct to me.


thanks,
Jun Li Feb. 12, 2019, 10:41 a.m. UTC | #6
Hi
> -----Original Message-----
> From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Sent: 2019年2月12日 16:51
> To: Jun Li <jun.li@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Andy Shevchenko
> <andy.shevchenko@gmail.com>; Chen Yu <chenyu56@huawei.com>; Hans de
> Goede <hdegoede@redhat.com>; linux-usb@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2 6/9] usb: roles: Find the muxes by also matching against the
> device node
> 
> Hi,
> 
> On Tue, Feb 12, 2019 at 06:03:42AM +0000, Jun Li wrote:
> > > > return dev_fwnode(dev->parent) == fwnode;
> > >
> > > That's actually not the case. struct usb_role_switch_desc has a
> > > member for fwnode, and that's what we use with the actual mux
> > > device. Check
> > > usb_role_switch_register():
> > >
> > >         ...
> > >         sw->dev.fwnode = desc->fwnode;
> > >         ...
> > >
> > > Sorry for not realizing it before.
> >
> > So desc->fwnode should be initialized before do usb_role_switch_register()?
> > But seems usb_role_switch_desc is a read-only object so can't be set at runtime.
> 
> It can. Even though usb_role_switch_register() takes read-only parameter, nothing's
> preventing you from passing data even from the stack (the content of the descriptor
> is copied in any case).
> 
> Expecting the descriptor to be read-only just means it can be read-only, but it does
> not have to be.

Understood, thanks.

> @@ -32,6 +32,7 @@ typedef enum usb_role (*usb_role_switch_get_t)(struct
> device *dev);
>   * usb_role_switch_register() before registering the switch.
>   */
>  struct usb_role_switch_desc {
> +	struct fwnode_handle *fwnode;
You may add some description for this new member
/**
 * struct usb_role_switch_desc - USB Role Switch Descriptor
 * @ fwnode 

> 
> > usb_controller_node {
> > 	...
> > 	usb-role-switch;
> >
> > 	port {
> > 		sw_provider_node: endpoint {
> > 			remote-endpoint = <&sw_consumer_node>;
> > 		};
> > 	};
> > };
> >
> > typec_node {
> > 	...
> > 	port {
> > 		sw_consumer_node: endpoint {
> > 			remote-endpoint = <&sw_provider_node>;
> > 		};
> > 	};
> > };
> 
> That looks roughly correct to me.
> 
> 
> thanks,
> 
> --
> heikki
Heikki Krogerus Feb. 12, 2019, 11:24 a.m. UTC | #7
Hi,

On Tue, Feb 12, 2019 at 10:41:28AM +0000, Jun Li wrote:
> > @@ -32,6 +32,7 @@ typedef enum usb_role (*usb_role_switch_get_t)(struct
> > device *dev);
> >   * usb_role_switch_register() before registering the switch.
> >   */
> >  struct usb_role_switch_desc {
> > +	struct fwnode_handle *fwnode;
> You may add some description for this new member
> /**
>  * struct usb_role_switch_desc - USB Role Switch Descriptor
>  * @ fwnode 

You are correct. I need to fix that one.

thanks,
diff mbox series

Patch

diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index 99116af07f1d..f45d8df5cfb8 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -8,6 +8,7 @@ 
  */
 
 #include <linux/usb/role.h>
+#include <linux/property.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -84,7 +85,12 @@  enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
 
-static int __switch_match(struct device *dev, const void *name)
+static int switch_fwnode_match(struct device *dev, const void *fwnode)
+{
+	return dev_fwnode(dev) == fwnode;
+}
+
+static int switch_name_match(struct device *dev, const void *name)
 {
 	return !strcmp((const char *)name, dev_name(dev));
 }
@@ -94,8 +100,16 @@  static void *usb_role_switch_match(struct device_connection *con, int ep,
 {
 	struct device *dev;
 
-	dev = class_find_device(role_class, NULL, con->endpoint[ep],
-				__switch_match);
+	if (con->fwnode) {
+		if (!fwnode_property_present(con->fwnode, con->id))
+			return NULL;
+
+		dev = class_find_device(role_class, NULL, con->fwnode,
+					switch_fwnode_match);
+	} else {
+		dev = class_find_device(role_class, NULL, con->endpoint[ep],
+					switch_name_match);
+	}
 
 	return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
@@ -266,6 +280,7 @@  usb_role_switch_register(struct device *parent,
 	sw->get = desc->get;
 
 	sw->dev.parent = parent;
+	sw->dev.fwnode = desc->fwnode;
 	sw->dev.class = role_class;
 	sw->dev.type = &usb_role_dev_type;
 	dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent));
diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h
index edc51be4a77c..9684a8734757 100644
--- a/include/linux/usb/role.h
+++ b/include/linux/usb/role.h
@@ -32,6 +32,7 @@  typedef enum usb_role (*usb_role_switch_get_t)(struct device *dev);
  * usb_role_switch_register() before registering the switch.
  */
 struct usb_role_switch_desc {
+	struct fwnode_handle *fwnode;
 	struct device *usb2_port;
 	struct device *usb3_port;
 	struct device *udc;