diff options
Diffstat (limited to 'drivers/media/dvb-core/dvb_frontend.c')
-rw-r--r-- | drivers/media/dvb-core/dvb_frontend.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 06ea30a689d7..ad3e42a4eaf7 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -135,7 +135,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv) - dvb_free_device(fepriv->dvbdev); + dvb_device_put(fepriv->dvbdev); dvb_frontend_invoke_release(fe, fe->ops.release); @@ -292,14 +292,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, } if (events->eventw == events->eventr) { - int ret; + struct wait_queue_entry wait; + int ret = 0; if (flags & O_NONBLOCK) return -EWOULDBLOCK; - ret = wait_event_interruptible(events->wait_queue, - dvb_frontend_test_event(fepriv, events)); - + init_waitqueue_entry(&wait, current); + add_wait_queue(&events->wait_queue, &wait); + while (!dvb_frontend_test_event(fepriv, events)) { + wait_woken(&wait, TASK_INTERRUPTIBLE, 0); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + } + remove_wait_queue(&events->wait_queue, &wait); if (ret < 0) return ret; } @@ -2961,6 +2969,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb, .name = fe->ops.info.name, #endif }; + int ret; dev_dbg(dvb->device, "%s:\n", __func__); @@ -2994,8 +3003,13 @@ int dvb_register_frontend(struct dvb_adapter *dvb, "DVB: registering adapter %i frontend %i (%s)...\n", fe->dvb->num, fe->id, fe->ops.info.name); - dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template, + ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND, 0); + if (ret) { + dvb_frontend_put(fe); + mutex_unlock(&frontend_mutex); + return ret; + } /* * Initialize the cache to the proper values according with the |