diff options
author | Markus Rechberger <markus.rechberger@amd.com> | 2007-04-14 09:18:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-04-27 14:45:30 -0400 |
commit | ca5be9cd0516629cb8ee335b7dad076e66d72a22 (patch) | |
tree | d55baaf4d5c633ef9ce5629375bf4fd1af50ea95 /drivers/media | |
parent | 31a1854706707dc3b67eb0d3bf0f51c67d91c82e (diff) |
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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 17 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.h | 1 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a21a894d3f98..9783d392b7d3 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -606,6 +606,11 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
606 | return; | 606 | return; |
607 | 607 | ||
608 | kthread_stop(fepriv->thread); | 608 | kthread_stop(fepriv->thread); |
609 | |||
610 | if (fepriv->dvbdev->users < -1) | ||
611 | wait_event_interruptible(fepriv->dvbdev->wait_queue, | ||
612 | fepriv->dvbdev->users==-1); | ||
613 | |||
609 | init_MUTEX (&fepriv->sem); | 614 | init_MUTEX (&fepriv->sem); |
610 | fepriv->state = FESTATE_IDLE; | 615 | fepriv->state = FESTATE_IDLE; |
611 | 616 | ||
@@ -1023,6 +1028,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) | |||
1023 | struct dvb_device *dvbdev = file->private_data; | 1028 | struct dvb_device *dvbdev = file->private_data; |
1024 | struct dvb_frontend *fe = dvbdev->priv; | 1029 | struct dvb_frontend *fe = dvbdev->priv; |
1025 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1030 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1031 | int ret; | ||
1026 | 1032 | ||
1027 | dprintk ("%s\n", __FUNCTION__); | 1033 | dprintk ("%s\n", __FUNCTION__); |
1028 | 1034 | ||
@@ -1032,7 +1038,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) | |||
1032 | if (fe->ops.ts_bus_ctrl) | 1038 | if (fe->ops.ts_bus_ctrl) |
1033 | fe->ops.ts_bus_ctrl (fe, 0); | 1039 | fe->ops.ts_bus_ctrl (fe, 0); |
1034 | 1040 | ||
1035 | return dvb_generic_release (inode, file); | 1041 | ret = dvb_generic_release (inode, file); |
1042 | |||
1043 | if (dvbdev->users==-1 && fepriv->exit==1) { | ||
1044 | fops_put(file->f_op); | ||
1045 | file->f_op = NULL; | ||
1046 | wake_up_interruptible (&dvbdev->wait_queue); | ||
1047 | } | ||
1048 | return ret; | ||
1036 | } | 1049 | } |
1037 | 1050 | ||
1038 | static struct file_operations dvb_frontend_fops = { | 1051 | static struct file_operations dvb_frontend_fops = { |
@@ -1091,9 +1104,9 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
1091 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1104 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1092 | dprintk ("%s\n", __FUNCTION__); | 1105 | dprintk ("%s\n", __FUNCTION__); |
1093 | 1106 | ||
1107 | dvb_frontend_stop (fe); | ||
1094 | mutex_lock(&frontend_mutex); | 1108 | mutex_lock(&frontend_mutex); |
1095 | dvb_unregister_device (fepriv->dvbdev); | 1109 | dvb_unregister_device (fepriv->dvbdev); |
1096 | dvb_frontend_stop (fe); | ||
1097 | 1110 | ||
1098 | /* fe is invalid now */ | 1111 | /* fe is invalid now */ |
1099 | kfree(fepriv); | 1112 | kfree(fepriv); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 14a372a0fe8b..e23d8a0ea1d3 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
233 | dvbdev->adapter = adap; | 233 | dvbdev->adapter = adap; |
234 | dvbdev->priv = priv; | 234 | dvbdev->priv = priv; |
235 | dvbdev->fops = dvbdevfops; | 235 | dvbdev->fops = dvbdevfops; |
236 | init_waitqueue_head (&dvbdev->wait_queue); | ||
236 | 237 | ||
237 | memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); | 238 | memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); |
238 | dvbdev->fops->owner = adap->module; | 239 | dvbdev->fops->owner = adap->module; |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 620e7887b3d3..6dff10ebf470 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -69,6 +69,7 @@ struct dvb_device { | |||
69 | int writers; | 69 | int writers; |
70 | int users; | 70 | int users; |
71 | 71 | ||
72 | wait_queue_head_t wait_queue; | ||
72 | /* don't really need those !? -- FIXME: use video_usercopy */ | 73 | /* don't really need those !? -- FIXME: use video_usercopy */ |
73 | int (*kernel_ioctl)(struct inode *inode, struct file *file, | 74 | int (*kernel_ioctl)(struct inode *inode, struct file *file, |
74 | unsigned int cmd, void *arg); | 75 | unsigned int cmd, void *arg); |