[media] au0828: Fix DVB resume when streaming
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Sun, 10 Aug 2014 02:14:21 +0000 (23:14 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Thu, 21 Aug 2014 20:25:10 +0000 (15:25 -0500)
When DVB is streaming and suspend is called, it will call
au0828_stop_transport(), with will clean the streaming flag.

Due to that, stop_urb_transfer() will be called twice,
causing an oops.

So, we need another flag to be used at resume, telling it
to restart DVB.

While here, add a logic at stop_urb_transfer() to prevent
it of being called twice, and convert the usb_streaming
flag into boolean.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/usb/au0828/au0828-dvb.c
drivers/media/usb/au0828/au0828.h

index bc4ea5397e92875541a2759ece63475facd7b050..821f86e92cde3321ec23d9f0066204a46b061621 100644 (file)
@@ -121,7 +121,7 @@ static void urb_completion(struct urb *purb)
                return;
        }
 
-       if (dev->urb_streaming == 0) {
+       if (!dev->urb_streaming) {
                dprintk(2, "%s: not streaming!\n", __func__);
                return;
        }
@@ -159,7 +159,10 @@ static int stop_urb_transfer(struct au0828_dev *dev)
 
        dprintk(2, "%s()\n", __func__);
 
-       dev->urb_streaming = 0;
+       if (!dev->urb_streaming)
+               return 0;
+
+       dev->urb_streaming = false;
        for (i = 0; i < URB_COUNT; i++) {
                if (dev->urbs[i]) {
                        usb_kill_urb(dev->urbs[i]);
@@ -229,7 +232,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
                }
        }
 
-       dev->urb_streaming = 1;
+       dev->urb_streaming = true;
        ret = 0;
 
 err:
@@ -323,7 +326,7 @@ static void au0828_restart_dvb_streaming(struct work_struct *work)
                                              restart_streaming);
        struct au0828_dvb *dvb = &dev->dvb;
 
-       if (dev->urb_streaming == 0)
+       if (!dev->urb_streaming)
                return;
 
        dprintk(1, "Restarting streaming...!\n");
@@ -628,6 +631,7 @@ void au0828_dvb_suspend(struct au0828_dev *dev)
                stop_urb_transfer(dev);
                au0828_stop_transport(dev, 1);
                mutex_unlock(&dvb->lock);
+               dev->need_urb_start = 1;
        }
 }
 
@@ -635,7 +639,7 @@ void au0828_dvb_resume(struct au0828_dev *dev)
 {
        struct au0828_dvb *dvb = &dev->dvb;
 
-       if (dvb->frontend && dev->urb_streaming) {
+       if (dvb->frontend && dev->need_urb_start) {
                pr_info("resuming DVB\n");
 
                au0828_set_frontend(dvb->frontend);
index d187129b96b7e421677139af55608d92fedcc7c4..a7cc6e397fdd9f98afeb1cd44cd7853eb64978e8 100644 (file)
@@ -267,8 +267,8 @@ struct au0828_dev {
        char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
                                                   transfer */
 
-       /* USB / URB Related */
-       int             urb_streaming;
+       /* DVB USB / URB Related */
+       bool            urb_streaming, need_urb_start;
        struct urb      *urbs[URB_COUNT];
 
        /* Preallocated transfer digital transfer buffers */