}
EXPORT_SYMBOL(dvb_frontend_reinitialise);
-void dvb_frontend_retune(struct dvb_frontend *fe)
-{
- struct dvb_frontend_private *fepriv = fe->frontend_priv;
-
- fepriv->state = FESTATE_RETUNE;
- dvb_frontend_wakeup(fe);
-}
-EXPORT_SYMBOL(dvb_frontend_retune);
-
static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
{
int q2;
.llseek = noop_llseek,
};
+int dvb_frontend_suspend(struct dvb_frontend *fe)
+{
+ int ret = 0;
+
+ dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
+ fe->id);
+
+ if (fe->ops.tuner_ops.sleep)
+ ret = fe->ops.tuner_ops.sleep(fe);
+
+ if (fe->ops.sleep)
+ ret = fe->ops.sleep(fe);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_frontend_suspend);
+
+int dvb_frontend_resume(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int ret = 0;
+
+ dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
+ fe->id);
+
+ if (fe->ops.init)
+ ret = fe->ops.init(fe);
+
+ if (fe->ops.tuner_ops.init)
+ ret = fe->ops.tuner_ops.init(fe);
+
+ fepriv->state = FESTATE_RETUNE;
+ dvb_frontend_wakeup(fe);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_frontend_resume);
+
int dvb_register_frontend(struct dvb_adapter* dvb,
struct dvb_frontend* fe)
{
* @stream: adapter the usb data stream
* @id: index of this adapter (starting with 0)
* @ts_type: transport stream, input stream, type
+ * @suspend_resume_active: set when there is ongoing suspend / resume
* @pid_filtering: is hardware pid_filtering used or not
* @feed_count: current feed count
* @max_feed_count: maimum feed count device can handle
struct usb_data_stream stream;
u8 id;
u8 ts_type;
+ bool suspend_resume_active;
bool pid_filtering;
u8 feed_count;
u8 max_feed_count;
extern void dvb_usbv2_disconnect(struct usb_interface *);
extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
extern int dvb_usbv2_resume(struct usb_interface *);
+#define dvb_usbv2_reset_resume dvb_usbv2_resume
/* the generic read/write method for device control */
extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
fe->id);
+ if (!adap->suspend_resume_active) {
+ adap->active_fe = fe->id;
+ mutex_lock(&adap->sync_mutex);
+ }
+
ret = dvb_usbv2_device_power_ctrl(d, 1);
if (ret < 0)
goto err;
if (ret < 0)
goto err;
}
-
- return 0;
err:
- dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
- return ret;
-}
-
-static int dvb_usb_fe_init_lock(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- mutex_lock(&adap->sync_mutex);
-
- ret = dvb_usb_fe_init(fe);
- adap->active_fe = fe->id;
+ if (!adap->suspend_resume_active)
+ mutex_unlock(&adap->sync_mutex);
- mutex_unlock(&adap->sync_mutex);
+ dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);
return ret;
}
dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
fe->id);
+ if (!adap->suspend_resume_active)
+ mutex_lock(&adap->sync_mutex);
+
if (adap->fe_sleep[fe->id]) {
ret = adap->fe_sleep[fe->id](fe);
if (ret < 0)
ret = dvb_usbv2_device_power_ctrl(d, 0);
if (ret < 0)
goto err;
-
- return 0;
err:
- dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
- return ret;
-}
-
-static int dvb_usb_fe_sleep_lock(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- mutex_lock(&adap->sync_mutex);
-
- ret = dvb_usb_fe_sleep(fe);
- adap->active_fe = -1;
+ if (!adap->suspend_resume_active) {
+ adap->active_fe = -1;
+ mutex_unlock(&adap->sync_mutex);
+ }
- mutex_unlock(&adap->sync_mutex);
+ dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);
return ret;
}
adap->fe[i]->id = i;
/* re-assign sleep and wakeup functions */
adap->fe_init[i] = adap->fe[i]->ops.init;
- adap->fe[i]->ops.init = dvb_usb_fe_init_lock;
+ adap->fe[i]->ops.init = dvb_usb_fe_init;
adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
- adap->fe[i]->ops.sleep = dvb_usb_fe_sleep_lock;
+ adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
if (ret < 0) {
active_fe = d->adapter[i].active_fe;
if (d->adapter[i].dvb_adap.priv && active_fe != -1) {
fe = d->adapter[i].fe[active_fe];
+ d->adapter[i].suspend_resume_active = true;
if (d->props->streaming_ctrl)
d->props->streaming_ctrl(fe, 0);
/* stop usb streaming */
usb_urb_killv2(&d->adapter[i].stream);
- if (fe->ops.tuner_ops.sleep)
- fe->ops.tuner_ops.sleep(fe);
-
- dvb_usb_fe_sleep(fe);
+ dvb_frontend_suspend(fe);
}
}
if (d->adapter[i].dvb_adap.priv && active_fe != -1) {
fe = d->adapter[i].fe[active_fe];
- dvb_usb_fe_init(fe);
-
- if (fe->ops.tuner_ops.init)
- fe->ops.tuner_ops.init(fe);
-
- /* acquire dvb-core perform retune */
- dvb_frontend_retune(fe);
+ dvb_frontend_resume(fe);
/* resume usb streaming */
usb_urb_submitv2(&d->adapter[i].stream, NULL);
if (d->props->streaming_ctrl)
d->props->streaming_ctrl(fe, 1);
+
+ d->adapter[i].suspend_resume_active = false;
}
}