]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.16.3/media-au0828-only-alt-setting-logic-when-needed.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.16.3 / media-au0828-only-alt-setting-logic-when-needed.patch
1 From 64ea37bbd8a5815522706f0099ad3f11c7537e15 Mon Sep 17 00:00:00 2001
2 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
3 Date: Sun, 8 Jun 2014 13:54:57 -0300
4 Subject: media: au0828: Only alt setting logic when needed
5
6 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
7
8 commit 64ea37bbd8a5815522706f0099ad3f11c7537e15 upstream.
9
10 It seems that there's a bug at au0828 hardware/firmware
11 related to alternate setting: when the device is already at
12 alt 5, a further call causes the URBs to receive -ESHUTDOWN.
13
14 I found two different encarnations of this issue:
15
16 1) at qv4l2, it fails the second time we try to open the
17 video screen;
18 2) at xawtv, when audio underrun occurs, with is very
19 frequent, at least on my test machine.
20
21 The fix is simple: just check if alt=5 before calling
22 set_usb_interface().
23
24 Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26
27 ---
28 drivers/media/usb/au0828/au0828-video.c | 34 ++++++++++++++++----------------
29 1 file changed, 17 insertions(+), 17 deletions(-)
30
31 --- a/drivers/media/usb/au0828/au0828-video.c
32 +++ b/drivers/media/usb/au0828/au0828-video.c
33 @@ -787,11 +787,27 @@ static int au0828_i2s_init(struct au0828
34
35 /*
36 * Auvitek au0828 analog stream enable
37 - * Please set interface0 to AS5 before enable the stream
38 */
39 static int au0828_analog_stream_enable(struct au0828_dev *d)
40 {
41 + struct usb_interface *iface;
42 + int ret;
43 +
44 dprintk(1, "au0828_analog_stream_enable called\n");
45 +
46 + iface = usb_ifnum_to_if(d->usbdev, 0);
47 + if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
48 + dprintk(1, "Changing intf#0 to alt 5\n");
49 + /* set au0828 interface0 to AS5 here again */
50 + ret = usb_set_interface(d->usbdev, 0, 5);
51 + if (ret < 0) {
52 + printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
53 + return -EBUSY;
54 + }
55 + }
56 +
57 + /* FIXME: size should be calculated using d->width, d->height */
58 +
59 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
60 au0828_writereg(d, 0x106, 0x00);
61 /* set x position */
62 @@ -1002,15 +1018,6 @@ static int au0828_v4l2_open(struct file
63 return -ERESTARTSYS;
64 }
65 if (dev->users == 0) {
66 - /* set au0828 interface0 to AS5 here again */
67 - ret = usb_set_interface(dev->usbdev, 0, 5);
68 - if (ret < 0) {
69 - mutex_unlock(&dev->lock);
70 - printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
71 - kfree(fh);
72 - return -EBUSY;
73 - }
74 -
75 au0828_analog_stream_enable(dev);
76 au0828_analog_stream_reset(dev);
77
78 @@ -1252,13 +1259,6 @@ static int au0828_set_format(struct au08
79 }
80 }
81
82 - /* set au0828 interface0 to AS5 here again */
83 - ret = usb_set_interface(dev->usbdev, 0, 5);
84 - if (ret < 0) {
85 - printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
86 - return -EBUSY;
87 - }
88 -
89 au0828_analog_stream_enable(dev);
90
91 return 0;