summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Scheller <d.scheller@gmx.net>2017-04-09 16:38:11 -0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-06-20 09:39:27 -0300
commit725e93eba1769b61545da06366be908eedd688a0 (patch)
tree38e635be44b2f975747b518391320066ac412340
parent5d6d93a123c76ffd73667e87483756f0deb41214 (diff)
downloadop-kernel-dev-725e93eba1769b61545da06366be908eedd688a0.zip
op-kernel-dev-725e93eba1769b61545da06366be908eedd688a0.tar.gz
[media] dvb-frontends/cxd2841er: do I2C reads in one go
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> Acked-by: Abylay Ospan <aospan@netup.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index b06a8a2..575d08a 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,
OpenPOWER on IntegriCloud