Re: [PATCH] i2c: mux: pca954x: Disable cacheing of the last channel

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

 



On Thu, Nov 14, 2019 at 01:47:02PM +0530, shubhrajyoti.datta@xxxxxxxxx wrote:
> From: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxxxxx>

Typo in the subject.

Run get_maintainers.pl and Cc the right people.

> In case of multimaster configuration the last channel cached value is
> not reliable. Basically the first processor/master does a write to the
> mux and then to the intended slave, it caches the value.
> Now the second processor/processor does a write to mux on another
> channel and writes to another slave.
> The first processor/master when it attempts to write the slave
> skips the mux as it relies on the mux channel being the same as the
> intended. This causes an issue.
> 
> To fix that write always to the mux address.
> 
> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxxxxx>
> ---
>  Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 1 +
>  drivers/i2c/muxes/i2c-mux-pca954x.c                       | 6 +++++-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> index 30ac6a6..fc4c0b0 100644
> --- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
> @@ -34,6 +34,7 @@ Optional Properties:
>      - first cell is the pin number
>      - second cell is used to specify flags.
>      See also Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> +  - no-channel-cache: Write the mux channel always.
>  
>  Example:
>  
> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
> index 923aa3a..37d32b0 100644
> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
> @@ -85,6 +85,7 @@ struct pca954x {
>  	const struct chip_desc *chip;
>  
>  	u8 last_chan;		/* last register value */
> +	u8 last_chan_unchached;	/* write channel register always */
>  	/* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */
>  	s8 idle_state;
>  
> @@ -244,7 +245,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
>  		regval = 1 << chan;
>  
>  	/* Only select the channel if its different from the last channel */
> -	if (data->last_chan != regval) {
> +	if (last_chan_unchached && data->last_chan != regval) {
>  		ret = pca954x_reg_write(muxc->parent, client, regval);
>  		data->last_chan = ret < 0 ? 0 : regval;
>  	}
> @@ -479,6 +480,9 @@ static int pca954x_probe(struct i2c_client *client,
>  	if (idle_disconnect_dt)
>  		data->idle_state = MUX_IDLE_DISCONNECT;
>  
> +	data->last_chan_unchached = np &&
> +		of_property_read_bool(np, "no-channel-cache");
> +
>  	ret = pca954x_irq_setup(muxc);
>  	if (ret)
>  		goto fail_cleanup;
> -- 
> 2.1.1
> 



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux