aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuah Khan <shuahkh@osg.samsung.com>2014-11-21 19:17:08 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-11-25 10:32:49 -0500
commiteb336eab3e6ccb9b100b934a2d5677dfaa66d4de (patch)
tree6a9254c59eeaecb6fa447a3ea8381f1a3147767d
parent83f56f7cbd070c0d9772221aa61198ef74c96cc4 (diff)
[media] media/au0828: Fix IR stop, poll to not access device during disconnect
au0828 IR stop and poll routines continue to access device while usb disconnect is in progress. There is small window between device disconnect and usb interface is set to null. This results in filling the log with several of the following error messages. Fix it to detect device disconnect condition and avoid device access. Nov 20 18:58:02 anduin kernel: [ 102.949819] au0828: au0828_usb_disconnect() Nov 20 18:58:02 anduin kernel: [ 102.950046] au0828: send_control_msg() Failed sending control message, error -71. Nov 20 18:58:02 anduin kernel: [ 102.950052] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950056] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950061] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950065] au0828: recv_control_msg() Failed receiving control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950069] au0828: recv_control_msg() Failed receiving control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950072] au0828: recv_control_msg() Failed receiving control message, error -19. Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/usb/au0828/au0828-core.c8
-rw-r--r--drivers/media/usb/au0828/au0828-input.c11
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index bc064803b6c7..082ae6ba492f 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -153,6 +153,14 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
153 153
154 dprintk(1, "%s()\n", __func__); 154 dprintk(1, "%s()\n", __func__);
155 155
156 /* there is a small window after disconnect, before
157 dev->usbdev is NULL, for poll (e.g: IR) try to access
158 the device and fill the dmesg with error messages.
159 Set the status so poll routines can check and avoid
160 access after disconnect.
161 */
162 dev->dev_state = DEV_DISCONNECTED;
163
156 au0828_rc_unregister(dev); 164 au0828_rc_unregister(dev);
157 /* Digital TV */ 165 /* Digital TV */
158 au0828_dvb_unregister(dev); 166 au0828_dvb_unregister(dev);
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 11a8daec5939..b0f067971979 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -129,6 +129,10 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
129 int prv_bit, bit, width; 129 int prv_bit, bit, width;
130 bool first = true; 130 bool first = true;
131 131
132 /* do nothing if device is disconnected */
133 if (ir->dev->dev_state == DEV_DISCONNECTED)
134 return 0;
135
132 /* Check IR int */ 136 /* Check IR int */
133 rc = au8522_rc_read(ir, 0xe1, -1, buf, 1); 137 rc = au8522_rc_read(ir, 0xe1, -1, buf, 1);
134 if (rc < 0 || !(buf[0] & (1 << 4))) { 138 if (rc < 0 || !(buf[0] & (1 << 4))) {
@@ -255,8 +259,11 @@ static void au0828_rc_stop(struct rc_dev *rc)
255 259
256 cancel_delayed_work_sync(&ir->work); 260 cancel_delayed_work_sync(&ir->work);
257 261
258 /* Disable IR */ 262 /* do nothing if device is disconnected */
259 au8522_rc_clear(ir, 0xe0, 1 << 4); 263 if (ir->dev->dev_state != DEV_DISCONNECTED) {
264 /* Disable IR */
265 au8522_rc_clear(ir, 0xe0, 1 << 4);
266 }
260} 267}
261 268
262static int au0828_probe_i2c_ir(struct au0828_dev *dev) 269static int au0828_probe_i2c_ir(struct au0828_dev *dev)