[media] em28xx: don't sleep on disconnect

The DVB framework will try to power-down an adapter that no-one is using
any more, but this assumes that the adapter is still connected to the
machine. That's not always true for a USB adapter, so disable the sleep
operations when the adapter has been physically unplugged.

This prevents I2C write failures with error -19 from appearing
occasionally in the dmesg log.

Signed-off-by: Chris Rankin <rankincj@yahoo.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Chris Rankin 2011-08-20 16:01:26 -03:00 committed by Mauro Carvalho Chehab
parent 76424a0a50
commit 0b8bd83cf3
3 changed files with 23 additions and 5 deletions

View File

@ -1230,7 +1230,7 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
return 0;
}
static struct dvb_tuner_ops tda18271_tuner_ops = {
static const struct dvb_tuner_ops tda18271_tuner_ops = {
.info = {
.name = "NXP TDA18271HD",
.frequency_min = 45000000,

View File

@ -742,7 +742,7 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
}
static struct dvb_frontend_ops cxd2820r_ops[2];
static const struct dvb_frontend_ops cxd2820r_ops[2];
struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
struct i2c_adapter *i2c, struct dvb_frontend *fe)
@ -796,7 +796,7 @@ error:
}
EXPORT_SYMBOL(cxd2820r_attach);
static struct dvb_frontend_ops cxd2820r_ops[2] = {
static const struct dvb_frontend_ops cxd2820r_ops[2] = {
{
/* DVB-T/T2 */
.info = {

View File

@ -842,6 +842,13 @@ out_free:
goto ret;
}
static inline void prevent_sleep(struct dvb_frontend_ops *ops)
{
ops->set_voltage = NULL;
ops->sleep = NULL;
ops->tuner_ops.sleep = NULL;
}
static int em28xx_dvb_fini(struct em28xx *dev)
{
if (!dev->board.has_dvb) {
@ -850,8 +857,19 @@ static int em28xx_dvb_fini(struct em28xx *dev)
}
if (dev->dvb) {
em28xx_unregister_dvb(dev->dvb);
kfree(dev->dvb);
struct em28xx_dvb *dvb = dev->dvb;
if (dev->state & DEV_DISCONNECTED) {
/* We cannot tell the device to sleep
* once it has been unplugged. */
if (dvb->fe[0])
prevent_sleep(&dvb->fe[0]->ops);
if (dvb->fe[1])
prevent_sleep(&dvb->fe[1]->ops);
}
em28xx_unregister_dvb(dvb);
kfree(dvb);
dev->dvb = NULL;
}