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 >