Re: [PATCH] max9286: simplify i2c-mux parsing

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

 



Hi Jacopo,

On 21/11/2019 17:35, Jacopo Mondi wrote:
> Hi Kieran,
> 
> On Thu, Nov 21, 2019 at 04:56:31PM +0000, Kieran Bingham wrote:
>>  - Identify each enabled i2c-mux channel in a single pass
>>
>> The parse_dt function iterates each node in the i2c-mux for each endpoint looking for a match.
>> The only purpose of these iterations is to determine if the corresponding i2c-channel
>> is enabled. (status = 'okay').
>>
>> Iterate the i2c-mux nodes in a single pass storing the enable state
>> in a local i2c_mux_mask for use when parsing the endpoints.
>>
> 
> I very much agree with this :)

Great,

> 
>> Signed-off-by: Kieran Bingham <kieran.bingham@xxxxxxxxxxxxxxxx>
>> ---
>>  drivers/media/i2c/max9286.c | 84 +++++++++++++++----------------------
>>  1 file changed, 34 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
>> index 34cb6f3b40c2..a36132becdc7 100644
>> --- a/drivers/media/i2c/max9286.c
>> +++ b/drivers/media/i2c/max9286.c
>> @@ -1097,55 +1097,6 @@ static int max9286_is_bound(struct device *dev, void *data)
>>  	return 0;
>>  }
>>
>> -static struct device_node *max9286_get_i2c_by_id(struct device_node *parent,
>> -						 u32 id)
>> -{
>> -	struct device_node *i2c_mux;
>> -	struct device_node *child;
>> -
>> -	/* Balance the of_node_put() performed by of_find_node_by_name() */
>> -	of_node_get(parent);
>> -
>> -	i2c_mux = of_find_node_by_name(parent, "i2c-mux");
>> -	if (!i2c_mux) {
>> -		printk("max9286: Failed to find i2c-mux node\n");
>> -		return NULL;
>> -	}
>> -
>> -	for_each_child_of_node(i2c_mux, child) {
>> -		u32 i2c_id = 0;
>> -
>> -		if (of_node_cmp(child->name, "i2c") != 0)
>> -			continue;
>> -		of_property_read_u32(child, "reg", &i2c_id);
>> -		if (id == i2c_id)
>> -			return child;
>> -	}
>> -
>> -	return NULL;
>> -}
>> -
>> -static int max9286_check_i2c_bus_by_id(struct device *dev, int id)
>> -{
>> -	struct device_node *i2c_np;
>> -
>> -	i2c_np = max9286_get_i2c_by_id(dev->of_node, id);
>> -	if (!i2c_np) {
>> -		dev_err(dev, "Failed to find corresponding i2c@%u\n", id);
>> -		return -ENODEV;
>> -	}
>> -
>> -	if (!of_device_is_available(i2c_np)) {
>> -		dev_dbg(dev, "Skipping port %u with disabled I2C bus\n", id);
>> -		of_node_put(i2c_np);
>> -		return -ENODEV;
>> -	}
>> -
>> -	of_node_put(i2c_np);
>> -
>> -	return 0;
>> -}
>> -
>>  static void max9286_cleanup_dt(struct max9286_priv *priv)
>>  {
>>  	struct max9286_source *source;
>> @@ -1167,11 +1118,44 @@ static void max9286_cleanup_dt(struct max9286_priv *priv)
>>  static int max9286_parse_dt(struct max9286_priv *priv)
>>  {
>>  	struct device *dev = &priv->client->dev;
>> +	struct device_node *i2c_mux;
>> +	struct device_node *child = NULL;
>>  	struct device_node *ep_np = NULL;
> 
> Nit: could you re-use child or ep_np ?

Yes, that would reduce local vars. I'll do this now.


> 
>> +	unsigned int i2c_mux_mask = 0;
>>  	int ret;
>>
>> +	/* Balance the of_node_put() performed by of_find_node_by_name() */
> 
> Do you need this comment ?


It was non-obvious to me at least when I added it /why/ I had to get it.
But perhaps now I've got further along, it's more clear why.

DT references are a pain :-D
Lots of places where they are implicitly reduced in loops etc..



>> +	of_node_get(dev->of_node);
>> +	i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux");
>> +	if (!i2c_mux) {
>> +		dev_err(dev, "Failed to find i2c-mux node\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* Identify which i2c-mux channels are enabled */
>> +	for_each_child_of_node(i2c_mux, child) {
>> +		u32 id = 0;
>> +
>> +		if (of_node_cmp(child->name, "i2c") != 0)
>> +			continue;
> 
> With the new bindings in yaml format and the associated verification,
> this should not happen.

Aha, yes I think you're right - well in that case I'm happy to drop it,
and simplify the code.
>> +
>> +		of_property_read_u32(child, "reg", &id);
>> +		if (id >= MAX9286_NUM_GMSL)
>> +			continue;
>> +
>> +		if (!of_device_is_available(child)) {
>> +			dev_dbg(dev, "Skipping port %u with disabled I2C bus\n", id);
>> +			continue;
>> +		}
>> +
>> +		i2c_mux_mask |= BIT(id);
>> +	}
>> +	of_node_put(child);
>> +	of_node_put(i2c_mux);
>> +
>>  	v4l2_async_notifier_init(&priv->notifier);
>>
>> +	/* Parse the endpoints */
>>  	for_each_endpoint_of_node(dev->of_node, ep_np) {
> 
> dev->of_node is reused here, do you need to get it again ?

Urggh, no idea ... I'll investigate.
The earlier one crashed on me, this one did not ... but better to get it
'right'.


> All minors though, squash this on the next max9286 submission if you
> feel to.

Thanks.

--
Kieran


> 
> Thanks
>    j
> 
>>  		struct max9286_source *source;
>>  		struct of_endpoint ep;
>> @@ -1214,7 +1198,7 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>>  		}
>>
>>  		/* Skip if the corresponding GMSL link is unavailable. */
>> -		if (max9286_check_i2c_bus_by_id(dev, ep.port))
>> +		if (!(i2c_mux_mask & BIT(ep.port)))
>>  			continue;
>>
>>  		if (priv->sources[ep.port].fwnode) {
>> --
>> 2.20.1
>>

-- 
Regards
--
Kieran



[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux