Here's the updated patch that checks whether the frontend exists before disabling the sleep operations.

Cheers,
Chris

--- linux-3.0/drivers/media/common/tuners/tda18271-fe.c.orig    2011-08-20 
18:53:48.000000000 +0100
+++ linux-3.0/drivers/media/common/tuners/tda18271-fe.c 2011-08-20 
19:21:34.000000000 +0100
@@ -1230,7 +1230,7 @@
        return 0;
 }
 
-static struct dvb_tuner_ops tda18271_tuner_ops = {
+static const struct dvb_tuner_ops tda18271_tuner_ops = {
        .info = {
                .name = "NXP TDA18271HD",
                .frequency_min  =  45000000,
--- linux-3.0/drivers/media/dvb/frontends/cxd2820r_core.c.orig  2011-08-20 
18:54:09.000000000 +0100
+++ linux-3.0/drivers/media/dvb/frontends/cxd2820r_core.c       2011-08-20 
19:22:21.000000000 +0100
@@ -778,7 +778,7 @@
 }
 EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
 
-static struct dvb_frontend_ops cxd2820r_ops[2];
+static const struct dvb_frontend_ops cxd2820r_ops[2];
 
 struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
        struct i2c_adapter *i2c, struct dvb_frontend *fe)
@@ -844,7 +844,7 @@
 }
 EXPORT_SYMBOL(cxd2820r_attach);
 
-static struct dvb_frontend_ops cxd2820r_ops[2] = {
+static const struct dvb_frontend_ops cxd2820r_ops[2] = {
        {
                /* DVB-T/T2 */
                .info = {
--- linux-3.0/drivers/media/video/em28xx/em28xx-dvb.c.orig      2011-08-20 
18:53:25.000000000 +0100
+++ linux-3.0/drivers/media/video/em28xx/em28xx-dvb.c   2011-08-20 
19:26:51.000000000 +0100
@@ -720,6 +720,13 @@
        goto ret;
 }
 
+static inline void prevent_sleep(struct dvb_frontend_ops *ops)
+{
+       ops->set_voltage = NULL;
+       ops->sleep = NULL;
+       ops->tuner_ops.sleep = NULL;
+}
+
 static int dvb_fini(struct em28xx *dev)
 {
        if (!dev->board.has_dvb) {
@@ -728,8 +735,19 @@
        }
 
        if (dev->dvb) {
-               unregister_dvb(dev->dvb);
-               kfree(dev->dvb);
+               struct em28xx_dvb *dvb = dev->dvb;
+
+               if (dev->state & DEV_DISCONNECTED) {
+                       /* We cannot tell the device to sleep
+                        * once it has been unplugged. */
+                       if (dvb->fe[0])
+                               prevent_sleep(&dvb->fe[0]->ops);
+                       if (dvb->fe[1])
+                               prevent_sleep(&dvb->fe[1]->ops);
+               }
+
+               unregister_dvb(dvb);
+               kfree(dvb);
                dev->dvb = NULL;
        }
 

Reply via email to