Message ID | 20170409193828.18458-3-d.scheller.oss@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Acked-by: Abylay Ospan <aospan@netup.ru> 2017-04-09 15:38 GMT-04:00 Daniel Scheller <d.scheller.oss@gmail.com>: > From: Daniel Scheller <d.scheller@gmx.net> > > Doing the I2C read operation with two calls to i2c_transfer() causes the > exclusive I2C bus lock of the underlying adapter to be released. While this > isn't an issue if only one demodulator is attached to the bus, having two > or even more causes troubles in that concurrent accesses to the different > demods will cause all kinds of issues due to wrong data being returned on > read operations (for example, the TS config register will be set wrong). > This changes the read_regs() function to do the operation in one go (by > calling i2c_transfer with the whole msg list instead of one by one) to not > loose the I2C bus lock, fixing all sorts of random runtime failures. > > Signed-off-by: Daniel Scheller <d.scheller@gmx.net> > --- > drivers/media/dvb-frontends/cxd2841er.c | 13 ++----------- > 1 file changed, 2 insertions(+), 11 deletions(-) > > diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c > index 60d85ce..525d006 100644 > --- a/drivers/media/dvb-frontends/cxd2841er.c > +++ b/drivers/media/dvb-frontends/cxd2841er.c > @@ -282,17 +282,8 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv, > } > }; > > - ret = i2c_transfer(priv->i2c, &msg[0], 1); > - if (ret >= 0 && ret != 1) > - ret = -EIO; > - if (ret < 0) { > - dev_warn(&priv->i2c->dev, > - "%s: i2c rw failed=%d addr=%02x reg=%02x\n", > - KBUILD_MODNAME, ret, i2c_addr, reg); > - return ret; > - } > - ret = i2c_transfer(priv->i2c, &msg[1], 1); > - if (ret >= 0 && ret != 1) > + ret = i2c_transfer(priv->i2c, msg, 2); > + if (ret >= 0 && ret != 2) > ret = -EIO; > if (ret < 0) { > dev_warn(&priv->i2c->dev, > -- > 2.10.2 >
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index 60d85ce..525d006 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -282,17 +282,8 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv, } }; - ret = i2c_transfer(priv->i2c, &msg[0], 1); - if (ret >= 0 && ret != 1) - ret = -EIO; - if (ret < 0) { - dev_warn(&priv->i2c->dev, - "%s: i2c rw failed=%d addr=%02x reg=%02x\n", - KBUILD_MODNAME, ret, i2c_addr, reg); - return ret; - } - ret = i2c_transfer(priv->i2c, &msg[1], 1); - if (ret >= 0 && ret != 1) + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret >= 0 && ret != 2) ret = -EIO; if (ret < 0) { dev_warn(&priv->i2c->dev,