فهرست منبع

V4L/DVB (5510): Fix 1/3 for bug 7819: fixed frontend hotplug issue

fixed frontend hotplug issue

Signed-off-by: Michal CIJOML Semler <cijoml@volny.cz>
Signed-off-by: Markus Rechberger <markus.rechberger@amd.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Markus Rechberger 18 سال پیش
والد
کامیت
ca5be9cd05
3فایلهای تغییر یافته به همراه17 افزوده شده و 2 حذف شده
  1. 15 2
      drivers/media/dvb/dvb-core/dvb_frontend.c
  2. 1 0
      drivers/media/dvb/dvb-core/dvbdev.c
  3. 1 0
      drivers/media/dvb/dvb-core/dvbdev.h

+ 15 - 2
drivers/media/dvb/dvb-core/dvb_frontend.c

@@ -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);

+ 1 - 0
drivers/media/dvb/dvb-core/dvbdev.c

@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 	dvbdev->adapter = adap;
 	dvbdev->priv = priv;
 	dvbdev->fops = dvbdevfops;
+	init_waitqueue_head (&dvbdev->wait_queue);
 
 	memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
 	dvbdev->fops->owner = adap->module;

+ 1 - 0
drivers/media/dvb/dvb-core/dvbdev.h

@@ -69,6 +69,7 @@ struct dvb_device {
 	int writers;
 	int users;
 
+	wait_queue_head_t	  wait_queue;
 	/* don't really need those !? -- FIXME: use video_usercopy  */
 	int (*kernel_ioctl)(struct inode *inode, struct file *file,
 			    unsigned int cmd, void *arg);