public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
To: Alexander Sverdlin <alexander.sverdlin-OYasijW0DpE@public.gmane.org>
Cc: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	Lawnick Michael 61283229
	<michael.lawnick-OYasijW0DpE@public.gmane.org>,
	Maxime Ripard
	<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: Re: [PATCH] of: i2c: Add DT bindings for idle states to PCA954x mux driver
Date: Tue, 16 Dec 2014 13:07:30 +0200	[thread overview]
Message-ID: <5722849.lDq3gpSIfD@avalon> (raw)
In-Reply-To: <548FE8B2.9010400-OYasijW0DpE@public.gmane.org>

Hi Alexander,

On Tuesday 16 December 2014 09:09:22 Alexander Sverdlin wrote:
> Hello Laurent,
> 
> On 15/12/14 09:40, ext Laurent Pinchart wrote:
> >> of: i2c: Add DT bindings for idle states to PCA954x mux driver
> >> 
> >> Introduce two new device tree bindings to specify idle state of PCA954x
> >> 
> >> family of I2C multiplexors:
> >>   - idle-state: specifies particular child bus to be selected in idle;
> >>   - idle-disconnect: signals that mux should disconnect all child buses
> >>   in idle;
> > 
> > Could you please briefly explain your use case(s) for those two properties
> > ?
>
> idle-state specifies which bus will be connected when there is no data
> transfer. i2c-mux-gpio also has "idle-state" (though, it can replace both
> connect and disconnect cases in my patch). i2c-mux-pinctrl has special
> "idle" convention, specifying idle state as last in the list of states.
> Again, it can serve for both my properties.
> 
> idle-disconnect is what we actually use for some security reasons (so that
> I2C bus of the external SFP cage is not connected to the rest of I2C bus
> in idle).

Thank you for the explanation. I would add it to the DT bindings 
documentation, or at least to the commit message.

I understand the use cases of the idle-disconnect property. What do you use 
idle-state for, when the idle state is different from disconnecting the bus ?

> >> Signed-off-by: Alexander Sverdlin <alexander.sverdlin-OYasijW0DpE@public.gmane.org>
> >> ---
> >> 
> >>  .../devicetree/bindings/i2c/i2c-mux-pca954x.txt    |    3 +
> >>  drivers/i2c/muxes/i2c-mux-pca954x.c                |   51 ++++++++++++--
> >>  2 files changed, 48 insertions(+), 6 deletions(-)
> >> 
> >> diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> >> b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt index
> >> 34a3fb6..1fbe287 100644
> >> --- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> >> +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> >> 
> >> @@ -16,6 +16,9 @@ Required Properties:
> >>  Optional Properties:
> >>    - reset-gpios: Reference to the GPIO connected to the reset input.
> >> 
> >> +  - idle-state: Child bus connected in idle state (specified by its
> >> "reg" value)
> >> +  - idle-disconnect: Boolean; if defined, forces mux to disconnect all
> >> children
> >> +    in idle state
> >> 
> >>  Example:
> >> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c
> >> b/drivers/i2c/muxes/i2c-mux-pca954x.c index ec11b40..69cf603 100644
> >> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
> >> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
> >> @@ -43,6 +43,7 @@
> >>  #include <linux/module.h>
> >>  #include <linux/pm.h>
> >>  #include <linux/slab.h>
> >> +#include <linux/of.h>
> > 
> > Could you please keep headers sorted alphabetically ?
> 
> Yes...
> 
> >>  #define PCA954X_MAX_NCHANS 8
> >> 
> >> @@ -62,6 +63,8 @@ struct pca954x {
> >> 
> >>  	struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
> >>  	
> >>  	u8 last_chan;		/* last register value */
> >> 
> >> +	bool idle_disconnect;
> >> +	s8 idle_chan;		/* valid if not negative */
> >> 
> >>  };
> >>  
> >>  struct chip_desc {
> >> 
> >> @@ -172,10 +175,20 @@ static int pca954x_deselect_mux(struct i2c_adapter
> >> *adap, void *client, u32 chan)
> >> 
> >>  {
> >>  
> >>  	struct pca954x *data = i2c_get_clientdata(client);
> >> 
> >> +	struct pca954x_platform_data *pdata =
> >> +		dev_get_platdata(&((struct i2c_client *)client)->dev);
> >> +
> >> +	if ((pdata && pdata->modes[chan].deselect_on_exit) ||
> >> +	    data->idle_disconnect) {
> > 
> > I would copy pdata->modes[chan].deselect_on_exit to data->idle_disconnect
> > in the probe function, so you could avoiding accessing pdata here.
> 
> Unfortunately, this pdata has different (per-channel) semantics. I cannot
> really understand, why it was done this way, but anyway it's not possible
> to use one global bit to represent per-channel bits without changing the
> behavior.
> 
> I'm not keen to brake out-of-tree code (if any), but may be it will be
> decided to drop this per-channel deselect_on_exit, because it's not used at
> least in the kernel tree...

I'd vote for removing deselect_on_exit from platform data, but I won't insist.

> >> +		/* Deselect active channel */
> >> +		data->last_chan = 0;
> >> +		return pca954x_reg_write(adap, client, data->last_chan);
> >> +	}
> >> 
> >> -	/* Deselect active channel */
> >> -	data->last_chan = 0;
> >> -	return pca954x_reg_write(adap, client, data->last_chan);
> >> +	if (data->idle_chan >= 0)
> >> +		return pca954x_select_chan(adap, client, data->idle_chan);
> >> +
> >> +	return 0;
> >>  }
> >>  
> >>  /*
> >> @@ -186,6 +199,7 @@ static int pca954x_probe(struct i2c_client *client,
> >>  {
> >>  	struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
> >>  	struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
> >> +	struct device_node *of_node = client->dev.of_node;
> >>  	struct gpio_desc *gpio;
> >>  	int num, force, class;
> >>  	struct pca954x *data;
> >> @@ -216,6 +230,27 @@ static int pca954x_probe(struct i2c_client *client,
> >>  	data->type = id->driver_data;
> >>  	data->last_chan = 0;		   /* force the first selection */
> >> 
> >> +	data->idle_chan = -1;		   /* no forced idle state */
> >> +
> >> +	if (of_node) {
> >> +		u32 ch;
> >> +
> >> +		if (of_property_read_bool(of_node, "idle-disconnect"))
> >> +			data->idle_disconnect = true;
> >> +
> >> +		if (!of_property_read_u32_index(of_node, "idle-state", 0, &ch)) {
> >> +			if (ch < PCA954X_MAX_NCHANS) {
> >> +				data->idle_chan = ch;
> >> +				/* Force idle state from the beginning */
> >> +				ret = pca954x_select_chan(adap, client, ch);
> >> +				if (ret)
> >> +					return ret;
> >> +			} else {
> >> +				dev_warn(&client->dev,
> >> +				         "Invalid idle-state property\n");
> >> +			}
> >> +		}
> >> +	}
> >> 
> >>  	/* Now create an adapter for each channel */
> >>  	for (num = 0; num < chips[data->type].nchans; num++) {
> >> @@ -234,8 +269,7 @@ static int pca954x_probe(struct i2c_client *client,
> >>  		data->virt_adaps[num] =
> >>  			i2c_add_mux_adapter(adap, &client->dev, client,
> >>  				force, num, class, pca954x_select_chan,
> >> -				(pdata && pdata->modes[num].deselect_on_exit)
> >> -					? pca954x_deselect_mux : NULL);
> >> +				pca954x_deselect_mux);
> >> 
> >>  		if (data->virt_adaps[num] == NULL) {
> >>  			ret = -ENODEV;
> >> @@ -281,7 +315,12 @@ static int pca954x_resume(struct device *dev)
> >>  	struct pca954x *data = i2c_get_clientdata(client);
> >>  	
> >>  	data->last_chan = 0;
> >> 
> >> -	return i2c_smbus_write_byte(client, 0);
> >> +	/* Restore idle state on resume */
> >> +	if (data->idle_chan >= 0)
> >> +		return pca954x_select_chan(to_i2c_adapter(client->dev.parent),
> >> +		                           client, data->idle_chan);
> >> +	else
> >> +		return i2c_smbus_write_byte(client, 0);
> >> 
> >>  }
> >>  #endif

-- 
Regards,

Laurent Pinchart

  parent reply	other threads:[~2014-12-16 11:07 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-15  1:25 [PATCH] of: i2c: Add DT bindings for idle states to PCA954x mux driver Alexander Sverdlin
     [not found] ` <548E387E.2020502-OYasijW0DpE@public.gmane.org>
2014-12-15  8:40   ` Laurent Pinchart
2014-12-15 12:08     ` Michael Lawnick
2014-12-16  8:09     ` Alexander Sverdlin
     [not found]       ` <548FE8B2.9010400-OYasijW0DpE@public.gmane.org>
2014-12-16 11:07         ` Laurent Pinchart [this message]
2014-12-16 12:49           ` Alexander Sverdlin
     [not found]             ` <54902A49.7030804-OYasijW0DpE@public.gmane.org>
2014-12-16 13:38               ` Laurent Pinchart
2014-12-16 20:13                 ` Alexander Sverdlin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5722849.lDq3gpSIfD@avalon \
    --to=laurent.pinchart-rylnwiuwjnjg/c1bvhzhaw@public.gmane.org \
    --cc=alexander.sverdlin-OYasijW0DpE@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org \
    --cc=michael.lawnick-OYasijW0DpE@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox