Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / media / dvb / ttpci / av7110.c
index 4506165..29ed532 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/firmware.h>
 #include <linux/crc32.h>
 #include <linux/i2c.h>
+#include <linux/kthread.h>
 
 #include <asm/system.h>
 
@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110)
 
 static void av7110_arm_sync(struct av7110 *av7110)
 {
-       av7110->arm_rmmod = 1;
-       wake_up_interruptible(&av7110->arm_wait);
+       if (av7110->arm_thread)
+               kthread_stop(av7110->arm_thread);
 
-       while (av7110->arm_thread)
-               msleep(1);
+       av7110->arm_thread = NULL;
 }
 
 static int arm_thread(void *data)
@@ -238,17 +238,11 @@ static int arm_thread(void *data)
 
        dprintk(4, "%p\n",av7110);
 
-       lock_kernel();
-       daemonize("arm_mon");
-       sigfillset(&current->blocked);
-       unlock_kernel();
-
-       av7110->arm_thread = current;
-
        for (;;) {
                timeout = wait_event_interruptible_timeout(av7110->arm_wait,
-                                                          av7110->arm_rmmod, 5 * HZ);
-               if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
+                       kthread_should_stop(), 5 * HZ);
+
+               if (-ERESTARTSYS == timeout || kthread_should_stop()) {
                        /* got signal or told to quit*/
                        break;
                }
@@ -276,7 +270,6 @@ static int arm_thread(void *data)
                av7110->arm_errors = 0;
        }
 
-       av7110->arm_thread = NULL;
        return 0;
 }
 
@@ -695,8 +688,8 @@ static void gpioirq(unsigned long data)
 static int dvb_osd_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, void *parg)
 {
-       struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-       struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
 
        dprintk(4, "%p\n", av7110);
 
@@ -786,7 +779,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
 static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
 {
        struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
-       struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
+       struct av7110 *av7110 = dvbdmxfeed->demux->priv;
        u16 buf[20];
        int ret, i;
        u16 handle;
@@ -835,7 +828,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
 
 static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
 {
-       struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
+       struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv;
        u16 buf[3];
        u16 answ[2];
        int ret;
@@ -871,7 +864,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
 static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
 {
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
+       struct av7110 *av7110 = dvbdmx->priv;
        u16 *pid = dvbdmx->pids, npids[5];
        int i;
        int ret = 0;
@@ -914,7 +907,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
 static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
 {
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
+       struct av7110 *av7110 = dvbdmx->priv;
        u16 *pid = dvbdmx->pids, npids[5];
        int i;
 
@@ -1103,9 +1096,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
 
        /* pointer casting paranoia... */
        BUG_ON(!demux);
-       dvbdemux = (struct dvb_demux *) demux->priv;
+       dvbdemux = demux->priv;
        BUG_ON(!dvbdemux);
-       av7110 = (struct av7110 *) dvbdemux->priv;
+       av7110 = dvbdemux->priv;
 
        dprintk(4, "%p\n", av7110);
 
@@ -1137,7 +1130,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
 
 static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+       struct av7110* av7110 = fe->dvb->priv;
 
        switch (tone) {
        case SEC_TONE_ON:
@@ -1197,7 +1190,7 @@ static int start_ts_capture(struct av7110 *budget)
 static int budget_start_feed(struct dvb_demux_feed *feed)
 {
        struct dvb_demux *demux = feed->demux;
-       struct av7110 *budget = (struct av7110 *) demux->priv;
+       struct av7110 *budget = demux->priv;
        int status;
 
        dprintk(2, "av7110: %p\n", budget);
@@ -1212,7 +1205,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
 static int budget_stop_feed(struct dvb_demux_feed *feed)
 {
        struct dvb_demux *demux = feed->demux;
-       struct av7110 *budget = (struct av7110 *) demux->priv;
+       struct av7110 *budget = demux->priv;
        int status;
 
        dprintk(2, "budget: %p\n", budget);
@@ -1383,8 +1376,10 @@ static void dvb_unregister(struct av7110 *av7110)
        dvb_dmxdev_release(&av7110->dmxdev);
        dvb_dmx_release(&av7110->demux);
 
-       if (av7110->fe != NULL)
+       if (av7110->fe != NULL) {
                dvb_unregister_frontend(av7110->fe);
+               dvb_frontend_detach(av7110->fe);
+       }
        dvb_unregister_device(av7110->osd_dev);
        av7110_av_unregister(av7110);
        av7110_ca_unregister(av7110);
@@ -1549,7 +1544,7 @@ static int get_firmware(struct av7110* av7110)
 
 static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
 {
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+       struct av7110* av7110 = fe->dvb->priv;
        u8 pwr = 0;
        u8 buf[4];
        struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
@@ -1699,9 +1694,13 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front
 
 static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
 {
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
+       struct av7110* av7110 = fe->dvb->priv;
 
        return request_firmware(fw, name, &av7110->dev->pci->dev);
+#else
+       return -EINVAL;
+#endif
 }
 
 static struct sp8870_config alps_tdlb7_config = {
@@ -1861,7 +1860,7 @@ static struct stv0297_config nexusca_stv0297_config = {
 
 static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
 {
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+       struct av7110* av7110 = fe->dvb->priv;
        u32 div;
        u8 cfg, cpump, band_select;
        u8 data[4];
@@ -2077,7 +2076,7 @@ static int frontend_init(struct av7110 *av7110)
        if (av7110->dev->pci->subsystem_vendor == 0x110a) {
                switch(av7110->dev->pci->subsystem_device) {
                case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
-                       av7110->fe = ves1820_attach(&philips_cd1516_config,
+                       av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config,
                                                    &av7110->i2c_adap, read_pwm(av7110));
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
@@ -2092,7 +2091,7 @@ static int frontend_init(struct av7110 *av7110)
                case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
 
                        // try the ALPS BSRV2 first of all
-                       av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
                                av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2103,7 +2102,7 @@ static int frontend_init(struct av7110 *av7110)
                        }
 
                        // try the ALPS BSRU6 now
-                       av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
                                av7110->fe->tuner_priv = &av7110->i2c_adap;
@@ -2116,7 +2115,7 @@ static int frontend_init(struct av7110 *av7110)
                        }
 
                        // Try the grundig 29504-451
-                       av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
                                av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2130,7 +2129,7 @@ static int frontend_init(struct av7110 *av7110)
                        switch(av7110->dev->pci->subsystem_device) {
                        case 0x0000:
                                /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
-                               av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
+                               av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap,
                                                        read_pwm(av7110));
                                if (av7110->fe) {
                                        av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
@@ -2138,7 +2137,7 @@ static int frontend_init(struct av7110 *av7110)
                                break;
                        case 0x0003:
                                /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
-                               av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
+                               av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap,
                                                        read_pwm(av7110));
                                if (av7110->fe) {
                                        av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
@@ -2148,17 +2147,24 @@ static int frontend_init(struct av7110 *av7110)
                        break;
 
                case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
-
-                       // ALPS TDLB7
-                       av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
+                       // try ALPS TDLB7 first, then Grundig 29504-401
+                       av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params;
+                               break;
                        }
+                       /* fall-thru */
+
+               case 0x0008: // Hauppauge/TT DVB-T
+                       // Grundig 29504-401
+                       av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap);
+                       if (av7110->fe)
+                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
                        break;
 
                case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
 
-                       av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
+                       av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
                        }
@@ -2166,7 +2172,7 @@ static int frontend_init(struct av7110 *av7110)
 
                case 0x0004: // Galaxis DVB-S rev1.3
                        /* ALPS BSRV2 */
-                       av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
                                av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2178,7 +2184,7 @@ static int frontend_init(struct av7110 *av7110)
 
                case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
                        /* Grundig 29504-451 */
-                       av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
                                av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
@@ -2188,17 +2194,9 @@ static int frontend_init(struct av7110 *av7110)
                        }
                        break;
 
-               case 0x0008: // Hauppauge/TT DVB-T
-
-                       av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
-                       }
-                       break;
-
                case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
 
-                       av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params;
 
@@ -2214,12 +2212,12 @@ static int frontend_init(struct av7110 *av7110)
 
                case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
                        /* ALPS BSBE1 */
-                       av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
+                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap);
                        if (av7110->fe) {
                                av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
                                av7110->fe->tuner_priv = &av7110->i2c_adap;
 
-                               if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) {
+                               if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) {
                                        printk("dvb-ttpci: LNBP21 not found!\n");
                                        if (av7110->fe->ops.release)
                                                av7110->fe->ops.release(av7110->fe);
@@ -2255,8 +2253,7 @@ static int frontend_init(struct av7110 *av7110)
                ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
                if (ret < 0) {
                        printk("av7110: Frontend registration failed!\n");
-                       if (av7110->fe->ops.release)
-                               av7110->fe->ops.release(av7110->fe);
+                       dvb_frontend_detach(av7110->fe);
                        av7110->fe = NULL;
                }
        }
@@ -2334,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
        const int length = TS_WIDTH * TS_HEIGHT;
        struct pci_dev *pdev = dev->pci;
        struct av7110 *av7110;
+       struct task_struct *thread;
        int ret, count = 0;
 
        dprintk(4, "dev: %p\n", dev);
@@ -2618,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
                printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
                        "System might be unstable!\n", FW_VERSION(av7110->arm_app));
 
-       ret = kernel_thread(arm_thread, (void *) av7110, 0);
-       if (ret < 0)
+       thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
+       if (IS_ERR(thread)) {
+               ret = PTR_ERR(thread);
                goto err_stop_arm_9;
+       }
+       av7110->arm_thread = thread;
 
        /* set initial volume in mixer struct */
        av7110->mixer.volume_left  = volume;
@@ -2823,8 +2824,8 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
 
 
 static struct saa7146_extension av7110_extension = {
-       .name           = "dvb\0",
-       .flags          = SAA7146_I2C_SHORT_DELAY,
+       .name           = "dvb",
+       .flags          = SAA7146_USE_I2C_IRQ,
 
        .module         = THIS_MODULE,
        .pci_tbl        = &pci_tbl[0],