aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-core')
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c12
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c18
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h2
3 files changed, 28 insertions, 4 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 09e96e9ddbd..04578df3f24 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -141,12 +141,18 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
- void *mem = vmalloc(DVR_BUFFER_SIZE);
+ void *mem;
+ if (!dvbdev->readers) {
+ mutex_unlock(&dmxdev->mutex);
+ return -EBUSY;
+ }
+ mem = vmalloc(DVR_BUFFER_SIZE);
if (!mem) {
mutex_unlock(&dmxdev->mutex);
return -ENOMEM;
}
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+ dvbdev->readers--;
}
if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
@@ -184,6 +190,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
dmxdev->dvr_orig_fe);
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
if (dmxdev->dvr_buffer.data) {
void *mem = dmxdev->dvr_buffer.data;
mb();
@@ -1029,8 +1036,7 @@ static struct file_operations dvb_dvr_fops = {
static struct dvb_device dvbdev_dvr = {
.priv = NULL,
- .users = 1,
- .writers = 1,
+ .readers = 1,
.fops = &dvb_dvr_fops
};
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 2c3ea8f95dc..4f8f257e679 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -105,6 +105,7 @@ struct dvb_frontend_private {
fe_status_t status;
unsigned long tune_mode_flags;
unsigned int delay;
+ unsigned int reinitialise;
/* swzigzag values */
unsigned int state;
@@ -121,6 +122,7 @@ struct dvb_frontend_private {
unsigned int check_wrapped;
};
+static void dvb_frontend_wakeup(struct dvb_frontend *fe);
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
{
@@ -213,6 +215,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
fe->ops->init(fe);
}
+void dvb_frontend_reinitialise(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
+ fepriv->reinitialise = 1;
+ dvb_frontend_wakeup(fe);
+}
+EXPORT_SYMBOL(dvb_frontend_reinitialise);
+
static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
{
int q2;
@@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data)
fepriv->quality = 0;
fepriv->delay = 3*HZ;
fepriv->status = 0;
- dvb_frontend_init(fe);
fepriv->wakeup = 0;
+ fepriv->reinitialise = 1;
while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */
@@ -524,6 +535,11 @@ static int dvb_frontend_thread(void *data)
if (down_interruptible(&fepriv->sem))
break;
+ if (fepriv->reinitialise) {
+ dvb_frontend_init(fe);
+ fepriv->reinitialise = 0;
+ }
+
/* do an iteration of the tuning loop */
if (fe->ops->tune) {
/* have we been asked to retune? */
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index d5aee5ad67a..5926a3b745c 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -112,6 +112,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe);
+extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
+
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);