|
@@ -606,6 +606,11 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
|
|
|
return;
|
|
|
|
|
|
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;
|
|
|
|
|
@@ -1023,6 +1028,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
|
|
struct dvb_device *dvbdev = file->private_data;
|
|
|
struct dvb_frontend *fe = dvbdev->priv;
|
|
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
|
|
+ int ret;
|
|
|
|
|
|
dprintk ("%s\n", __FUNCTION__);
|
|
|
|
|
@@ -1032,7 +1038,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
|
|
if (fe->ops.ts_bus_ctrl)
|
|
|
fe->ops.ts_bus_ctrl (fe, 0);
|
|
|
|
|
|
- return dvb_generic_release (inode, file);
|
|
|
+ ret = dvb_generic_release (inode, file);
|
|
|
+
|
|
|
+ if (dvbdev->users==-1 && fepriv->exit==1) {
|
|
|
+ fops_put(file->f_op);
|
|
|
+ file->f_op = NULL;
|
|
|
+ wake_up_interruptible (&dvbdev->wait_queue);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static struct file_operations dvb_frontend_fops = {
|
|
@@ -1091,9 +1104,9 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
|
|
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
|
|
dprintk ("%s\n", __FUNCTION__);
|
|
|
|
|
|
+ dvb_frontend_stop (fe);
|
|
|
mutex_lock(&frontend_mutex);
|
|
|
dvb_unregister_device (fepriv->dvbdev);
|
|
|
- dvb_frontend_stop (fe);
|
|
|
|
|
|
/* fe is invalid now */
|
|
|
kfree(fepriv);
|