]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.30/dib8000-make-32-bits-read-atomic.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.30 / dib8000-make-32-bits-read-atomic.patch
1 From 5ac64ba12aca3bef18e61c866583155a3bbf81c4 Mon Sep 17 00:00:00 2001
2 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
3 Date: Fri, 13 Dec 2013 10:35:03 -0300
4 Subject: [media] dib8000: make 32 bits read atomic
5
6 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
7
8 commit 5ac64ba12aca3bef18e61c866583155a3bbf81c4 upstream.
9
10 As the dvb-frontend kthread can be called anytime, it can race
11 with some get status ioctl. So, it seems better to avoid one to
12 race with the other while reading a 32 bits register.
13 I can't see any other reason for having a mutex there at I2C, except
14 to provide such kind of protection, as the I2C core already has a
15 mutex to protect I2C transfers.
16
17 Note: instead of this approach, it could eventually remove the dib8000
18 specific mutex for it, and either group the 4 ops into one xfer or
19 to manually control the I2C mutex. The main advantage of the current
20 approach is that the changes are smaller and more puntual.
21
22 Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
23 Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
24 Acked-by: Patrick Boettcher <pboettcher@kernellabs.com>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26
27 ---
28 drivers/media/dvb-frontends/dib8000.c | 33 +++++++++++++++++++++++++--------
29 1 file changed, 25 insertions(+), 8 deletions(-)
30
31 --- a/drivers/media/dvb-frontends/dib8000.c
32 +++ b/drivers/media/dvb-frontends/dib8000.c
33 @@ -157,15 +157,10 @@ static u16 dib8000_i2c_read16(struct i2c
34 return ret;
35 }
36
37 -static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
38 +static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg)
39 {
40 u16 ret;
41
42 - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
43 - dprintk("could not acquire lock");
44 - return 0;
45 - }
46 -
47 state->i2c_write_buffer[0] = reg >> 8;
48 state->i2c_write_buffer[1] = reg & 0xff;
49
50 @@ -183,6 +178,21 @@ static u16 dib8000_read_word(struct dib8
51 dprintk("i2c read error on %d", reg);
52
53 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
54 +
55 + return ret;
56 +}
57 +
58 +static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
59 +{
60 + u16 ret;
61 +
62 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
63 + dprintk("could not acquire lock");
64 + return 0;
65 + }
66 +
67 + ret = __dib8000_read_word(state, reg);
68 +
69 mutex_unlock(&state->i2c_buffer_lock);
70
71 return ret;
72 @@ -192,8 +202,15 @@ static u32 dib8000_read32(struct dib8000
73 {
74 u16 rw[2];
75
76 - rw[0] = dib8000_read_word(state, reg + 0);
77 - rw[1] = dib8000_read_word(state, reg + 1);
78 + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
79 + dprintk("could not acquire lock");
80 + return 0;
81 + }
82 +
83 + rw[0] = __dib8000_read_word(state, reg + 0);
84 + rw[1] = __dib8000_read_word(state, reg + 1);
85 +
86 + mutex_unlock(&state->i2c_buffer_lock);
87
88 return ((rw[0] << 16) | (rw[1]));
89 }