]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.180/media-m88ds3103-serialize-reset-messages-in-m88ds310.patch
Linux 4.9.180
[thirdparty/kernel/stable-queue.git] / releases / 4.9.180 / media-m88ds3103-serialize-reset-messages-in-m88ds310.patch
1 From d6e35f062dd3aece99b1661cff68508524b70ca9 Mon Sep 17 00:00:00 2001
2 From: James Hutchinson <jahutchinson99@googlemail.com>
3 Date: Sun, 13 Jan 2019 16:13:47 -0500
4 Subject: media: m88ds3103: serialize reset messages in m88ds3103_set_frontend
5
6 [ Upstream commit 981fbe3da20a6f35f17977453bce7dfc1664d74f ]
7
8 Ref: https://bugzilla.kernel.org/show_bug.cgi?id=199323
9
10 Users are experiencing problems with the DVBSky S960/S960C USB devices
11 since the following commit:
12
13 9d659ae: ("locking/mutex: Add lock handoff to avoid starvation")
14
15 The device malfunctions after running for an indeterminable period of
16 time, and the problem can only be cleared by rebooting the machine.
17
18 It is possible to encourage the problem to surface by blocking the
19 signal to the LNB.
20
21 Further debugging revealed the cause of the problem.
22
23 In the following capture:
24 - thread #1325 is running m88ds3103_set_frontend
25 - thread #42 is running ts2020_stat_work
26
27 a> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 80
28 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 08
29 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 68 3f
30 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 08 ff
31 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
32 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
33 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 3d
34 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
35 b> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 00
36 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
37 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
38 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
39 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 21
40 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
41 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
42 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
43 [42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 66
44 [42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
45 [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
46 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
47 [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 60 02 10 0b
48 [1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
49
50 Two i2c messages are sent to perform a reset in m88ds3103_set_frontend:
51
52 a. 0x07, 0x80
53 b. 0x07, 0x00
54
55 However, as shown in the capture, the regmap mutex is being handed over
56 to another thread (ts2020_stat_work) in between these two messages.
57
58 >From here, the device responds to every i2c message with an 07 message,
59 and will only return to normal operation following a power cycle.
60
61 Use regmap_multi_reg_write to group the two reset messages, ensuring
62 both are processed before the regmap mutex is unlocked.
63
64 Signed-off-by: James Hutchinson <jahutchinson99@googlemail.com>
65 Reviewed-by: Antti Palosaari <crope@iki.fi>
66 Signed-off-by: Sean Young <sean@mess.org>
67 Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
68 Signed-off-by: Sasha Levin <sashal@kernel.org>
69 ---
70 drivers/media/dvb-frontends/m88ds3103.c | 9 ++++-----
71 1 file changed, 4 insertions(+), 5 deletions(-)
72
73 diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
74 index 31f16105184c0..59a4563c0466e 100644
75 --- a/drivers/media/dvb-frontends/m88ds3103.c
76 +++ b/drivers/media/dvb-frontends/m88ds3103.c
77 @@ -309,6 +309,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
78 u16 u16tmp;
79 u32 tuner_frequency_khz, target_mclk;
80 s32 s32tmp;
81 + static const struct reg_sequence reset_buf[] = {
82 + {0x07, 0x80}, {0x07, 0x00}
83 + };
84
85 dev_dbg(&client->dev,
86 "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
87 @@ -321,11 +324,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
88 }
89
90 /* reset */
91 - ret = regmap_write(dev->regmap, 0x07, 0x80);
92 - if (ret)
93 - goto err;
94 -
95 - ret = regmap_write(dev->regmap, 0x07, 0x00);
96 + ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2);
97 if (ret)
98 goto err;
99
100 --
101 2.20.1
102