Commit 0b8bd83c authored by Chris Rankin's avatar Chris Rankin Committed by Mauro Carvalho Chehab

[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: default avatarChris Rankin <rankincj@yahoo.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 76424a0a
...@@ -1230,7 +1230,7 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) ...@@ -1230,7 +1230,7 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
return 0; return 0;
} }
static struct dvb_tuner_ops tda18271_tuner_ops = { static const struct dvb_tuner_ops tda18271_tuner_ops = {
.info = { .info = {
.name = "NXP TDA18271HD", .name = "NXP TDA18271HD",
.frequency_min = 45000000, .frequency_min = 45000000,
......
...@@ -742,7 +742,7 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) ...@@ -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); 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 dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
struct i2c_adapter *i2c, struct dvb_frontend *fe) struct i2c_adapter *i2c, struct dvb_frontend *fe)
...@@ -796,7 +796,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, ...@@ -796,7 +796,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
} }
EXPORT_SYMBOL(cxd2820r_attach); EXPORT_SYMBOL(cxd2820r_attach);
static struct dvb_frontend_ops cxd2820r_ops[2] = { static const struct dvb_frontend_ops cxd2820r_ops[2] = {
{ {
/* DVB-T/T2 */ /* DVB-T/T2 */
.info = { .info = {
......
...@@ -842,6 +842,13 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -842,6 +842,13 @@ static int em28xx_dvb_init(struct em28xx *dev)
goto ret; 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) static int em28xx_dvb_fini(struct em28xx *dev)
{ {
if (!dev->board.has_dvb) { if (!dev->board.has_dvb) {
...@@ -850,8 +857,19 @@ static int em28xx_dvb_fini(struct em28xx *dev) ...@@ -850,8 +857,19 @@ static int em28xx_dvb_fini(struct em28xx *dev)
} }
if (dev->dvb) { if (dev->dvb) {
em28xx_unregister_dvb(dev->dvb); struct em28xx_dvb *dvb = dev->dvb;
kfree(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; dev->dvb = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment