From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932077AbaBKT3w (ORCPT ); Tue, 11 Feb 2014 14:29:52 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:40405 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751487AbaBKTH6 (ORCPT ); Tue, 11 Feb 2014 14:07:58 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mauro Carvalho Chehab , Patrick Boettcher Subject: [PATCH 3.10 45/79] [media] dib8000: make 32 bits read atomic Date: Tue, 11 Feb 2014 11:05:49 -0800 Message-Id: <20140211184722.255664894@linuxfoundation.org> X-Mailer: git-send-email 1.8.5.1.163.gd7aced9 In-Reply-To: <20140211184720.928667275@linuxfoundation.org> References: <20140211184720.928667275@linuxfoundation.org> User-Agent: quilt/0.61-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mauro Carvalho Chehab commit 5ac64ba12aca3bef18e61c866583155a3bbf81c4 upstream. As the dvb-frontend kthread can be called anytime, it can race with some get status ioctl. So, it seems better to avoid one to race with the other while reading a 32 bits register. I can't see any other reason for having a mutex there at I2C, except to provide such kind of protection, as the I2C core already has a mutex to protect I2C transfers. Note: instead of this approach, it could eventually remove the dib8000 specific mutex for it, and either group the 4 ops into one xfer or to manually control the I2C mutex. The main advantage of the current approach is that the changes are smaller and more puntual. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Acked-by: Patrick Boettcher Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-frontends/dib8000.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -157,15 +157,10 @@ static u16 dib8000_i2c_read16(struct i2c return ret; } -static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) +static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg) { u16 ret; - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg >> 8; state->i2c_write_buffer[1] = reg & 0xff; @@ -183,6 +178,21 @@ static u16 dib8000_read_word(struct dib8 dprintk("i2c read error on %d", reg); ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; + + return ret; +} + +static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) +{ + u16 ret; + + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { + dprintk("could not acquire lock"); + return 0; + } + + ret = __dib8000_read_word(state, reg); + mutex_unlock(&state->i2c_buffer_lock); return ret; @@ -192,8 +202,15 @@ static u32 dib8000_read32(struct dib8000 { u16 rw[2]; - rw[0] = dib8000_read_word(state, reg + 0); - rw[1] = dib8000_read_word(state, reg + 1); + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { + dprintk("could not acquire lock"); + return 0; + } + + rw[0] = __dib8000_read_word(state, reg + 0); + rw[1] = __dib8000_read_word(state, reg + 1); + + mutex_unlock(&state->i2c_buffer_lock); return ((rw[0] << 16) | (rw[1])); }