Re: [PATCH v2 1/3] usb: typec: Add typec_port_register_altmodes_from_fwnode()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 4/9/21 12:54 PM, Heikki Krogerus wrote:
> Hi Hans,
> 
> On Thu, Apr 08, 2021 at 10:31:27PM +0200, Hans de Goede wrote:
>> This can be used by Type-C controller drivers which use a standard
>> usb-connector fwnode, with altmodes sub-node, to describe the available
>> altmodes.
>>
>> Note there are is no devicetree bindings documentation for the altmodes
>> node, this is deliberate. ATM the fwnodes used to register the altmodes
>> are only used internally to pass platform info from a drivers/platform/x86
>> driver to the type-c subsystem.
>>
>> When a devicetree user of this functionally comes up and the dt-bindings
>> have been hashed out the internal use can be adjusted to match the
>> dt-bindings.
>>
>> Currently the typec_port_register_altmodes_from_fwnode() function expects
>> an "altmodes" child fwnode on port->dev with this "altmodes" fwnode having
>> child fwnodes itself with each child containing 2 integer properties:
>>
>> 1. A "svid" property, which sets the id of the altmode, e.g. displayport
>> altmode has a svid of 0xff01.
>>
>> 2. A "vdo" property, typically used as a bitmask describing the
>> capabilities of the altmode, the bits in the vdo are specified in the
>> specification of the altmode.
>>
>> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
>> ---
>> Changes in v2:
>> - Drop the unnecessary fwnode parameter from
>>   typec_port_register_altmodes_from_fwnode()
>> - Document the expected "altmodes" fwnode in the commit message for now
>>   as v2 of the patch-set drops the dt-bindings since there are not DT
>>   users for this yet
>> ---
>>  drivers/usb/typec/class.c | 55 +++++++++++++++++++++++++++++++++++++++
>>  include/linux/usb/typec.h |  6 +++++
>>  2 files changed, 61 insertions(+)
>>
>> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
>> index 45f0bf65e9ab..a82344fe1650 100644
>> --- a/drivers/usb/typec/class.c
>> +++ b/drivers/usb/typec/class.c
>> @@ -1978,6 +1978,61 @@ typec_port_register_altmode(struct typec_port *port,
>>  }
>>  EXPORT_SYMBOL_GPL(typec_port_register_altmode);
>>  
>> +void typec_port_register_altmodes_from_fwnode(struct typec_port *port,
>> +	const struct typec_altmode_ops *ops, void *drvdata,
>> +	struct typec_altmode **altmodes, size_t n)
> 
> Couldn't we just call this typec_port_register_altmodes()?

Ack, will fix for v3.

>> +{
>> +	struct fwnode_handle *altmodes_node, *child;
>> +	struct typec_altmode_desc desc;
>> +	struct typec_altmode *alt;
>> +	size_t index = 0;
>> +	u32 svid, vdo;
>> +	int ret;
>> +
>> +	altmodes_node = device_get_named_child_node(&port->dev, "altmodes");
>> +	if (!altmodes_node)
>> +		return; /* No altmodes specified */
>> +
>> +	child = NULL;
>> +	while ((child = fwnode_get_next_child_node(altmodes_node, child))) {
> 
> fwnode_for_each_child_node()?

Ack, will fix for v3.

> 
>> +		ret = fwnode_property_read_u32(child, "svid", &svid);
>> +		if (ret) {
>> +			dev_err(&port->dev, "Error reading svid for altmode %s\n",
>> +				fwnode_get_name(child));
>> +			continue;
>> +		}
>> +
>> +		ret = fwnode_property_read_u32(child, "vdo", &vdo);
>> +		if (ret) {
>> +			dev_err(&port->dev, "Error reading vdo for altmode %s\n",
>> +				fwnode_get_name(child));
>> +			continue;
>> +		}
>> +
>> +		if (index >= n) {
>> +			dev_err(&port->dev, "Error not enough space for altmode %s\n",
>> +				fwnode_get_name(child));
>> +			continue;
>> +		}
>> +
>> +		desc.svid = svid;
>> +		desc.vdo = vdo;
>> +		desc.mode = index + 1;
>> +		alt = typec_port_register_altmode(port, &desc);
>> +		if (IS_ERR(alt)) {
>> +			dev_err(&port->dev, "Error registering altmode %s\n",
>> +				fwnode_get_name(child));
>> +			continue;
>> +		}
>> +
>> +		alt->ops = ops;
>> +		typec_altmode_set_drvdata(alt, drvdata);
>> +		altmodes[index] = alt;
>> +		index++;
>> +	}
>> +}
>> +EXPORT_SYMBOL_GPL(typec_port_register_altmodes_from_fwnode);
> 
> This is OK by me, but I've been wondering if it would be more clear to
> just have a function fwnode_for_each_altmode() (I don't know if the
> name is good enough).
> 
> int fwnode_for_each_altmode(struct fwnode_handle *fwnode,
>                             int (*fn)(struct typec_altmode_desc *, void *),
>                             void *data)
> {
>         struct fwnode_handle *altmodes_node, *child;
>         struct typec_altmode_desc desc;
> 	u32 svid, vdo;
> 	int ret;
> 
> 	altmodes_node = fwnode_get_named_child_node(fwnode, "altmodes");
> 	if (!altmodes_node)
> 		return 0; /* No altmodes specified */
> 
>         fwnode_for_each_child_node(altmodes_node, child) {
>                 ...
>                 /* read the properties */
>                 ...
> 
> 		desc.svid = svid;
> 		desc.vdo = vdo;
> 		desc.mode = index + 1;
> 
>                 /* We need to add this member to struct typec_altmode_desc! */
>                 desc.fwnode = client;
> 
>                 ret = fn(&desc, data);
>                 if (ret)
>                         return ret;
>         }
> 
>         return 0;
> }
> 
> Something like that. It would leave the registration of the alternate
> modes to the drivers, which I think would actually be better.
> 
> If there ever is need, this can be also used for other things besides
> mode registration.
> 
> What do you think?

I think adding such a helper might make sense once we actually have
a need for the doing "other things" for all altmodes in a fwnode beside
registering them.

And even then I think it would still make sense to have a
typec_port_register_altmodes() helper for drivers to use, but that
could then be a wrapper around fwnode_for_each_altmode().

Since ATM we have only 1 user for a fwnode_for_each_altmode()
helper adding it now seems premature to me.

But if you have a strong preference for adding it now, then I can
do that for v3.

If you let me know which way you want to go on this, then I'll
prepare a v3.

Regards,

Hans




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux