if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
+       if (dmxdev->exit) {
+               mutex_unlock(&dmxdev->mutex);
+               return -ENODEV;
+       }
+
        if ((file->f_flags & O_ACCMODE) == O_RDWR) {
                if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
                        mutex_unlock(&dmxdev->mutex);
                dmxdev->demux->disconnect_frontend(dmxdev->demux);
                dmxdev->demux->connect_frontend(dmxdev->demux, front);
        }
+       dvbdev->users++;
        mutex_unlock(&dmxdev->mutex);
        return 0;
 }
                        vfree(mem);
                }
        }
-       mutex_unlock(&dmxdev->mutex);
+       /* TODO */
+       dvbdev->users--;
+       if(dvbdev->users==-1 && dmxdev->exit==1) {
+               fops_put(file->f_op);
+               file->f_op = NULL;
+               mutex_unlock(&dmxdev->mutex);
+               wake_up(&dvbdev->wait_queue);
+       } else
+               mutex_unlock(&dmxdev->mutex);
+
        return 0;
 }
 
                return -EINVAL;
        if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
+
+       if (dmxdev->exit) {
+               mutex_unlock(&dmxdev->mutex);
+               return -ENODEV;
+       }
        ret = dmxdev->demux->write(dmxdev->demux, buf, count);
        mutex_unlock(&dmxdev->mutex);
        return ret;
        struct dmxdev *dmxdev = dvbdev->priv;
        int ret;
 
+       if (dmxdev->exit) {
+               mutex_unlock(&dmxdev->mutex);
+               return -ENODEV;
+       }
+
        //mutex_lock(&dmxdev->mutex);
        ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
                                     file->f_flags & O_NONBLOCK,
        dmxdevfilter->feed.ts = NULL;
        init_timer(&dmxdevfilter->timer);
 
+       dvbdev->users++;
+
        mutex_unlock(&dmxdev->mutex);
        return 0;
 }
        struct dmxdev_filter *dmxdevfilter = file->private_data;
        struct dmxdev *dmxdev = dmxdevfilter->dev;
 
-       return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+       int ret;
+
+       ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+
+       mutex_lock(&dmxdev->mutex);
+       dmxdev->dvbdev->users--;
+       if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
+               fops_put(file->f_op);
+               file->f_op = NULL;
+               mutex_unlock(&dmxdev->mutex);
+               wake_up(&dmxdev->dvbdev->wait_queue);
+       } else
+               mutex_unlock(&dmxdev->mutex);
+
+       return ret;
 }
 
 static struct file_operations dvb_demux_fops = {
 static struct dvb_device dvbdev_dvr = {
        .priv = NULL,
        .readers = 1,
+       .users = 1,
        .fops = &dvb_dvr_fops
 };
 
 
 void dvb_dmxdev_release(struct dmxdev *dmxdev)
 {
+       dmxdev->exit=1;
+       if (dmxdev->dvbdev->users > 1) {
+               wait_event(dmxdev->dvbdev->wait_queue,
+                               dmxdev->dvbdev->users==1);
+       }
+       if (dmxdev->dvr_dvbdev->users > 1) {
+               wait_event(dmxdev->dvr_dvbdev->wait_queue,
+                               dmxdev->dvr_dvbdev->users==1);
+       }
+
        dvb_unregister_device(dmxdev->dvbdev);
        dvb_unregister_device(dmxdev->dvr_dvbdev);
 
 
 
        kthread_stop(fepriv->thread);
 
-       if (fepriv->dvbdev->users < -1)
-               wait_event_interruptible(fepriv->dvbdev->wait_queue,
-                               fepriv->dvbdev->users==-1);
-
        init_MUTEX (&fepriv->sem);
        fepriv->state = FESTATE_IDLE;
 
        if (dvbdev->users==-1 && fepriv->exit==1) {
                fops_put(file->f_op);
                file->f_op = NULL;
-               wake_up_interruptible (&dvbdev->wait_queue);
+               wake_up(&dvbdev->wait_queue);
        }
        return ret;
 }
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        dprintk ("%s\n", __FUNCTION__);
 
+       mutex_lock(&frontend_mutex);
        dvb_frontend_stop (fe);
+       mutex_unlock(&frontend_mutex);
+
+       if (fepriv->dvbdev->users < -1)
+               wait_event(fepriv->dvbdev->wait_queue,
+                               fepriv->dvbdev->users==-1);
+
        mutex_lock(&frontend_mutex);
        dvb_unregister_device (fepriv->dvbdev);