Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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,
+2 −2
Original line number Original line Diff line number Diff line
@@ -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,
}
}
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 = {
+20 −2
Original line number Original line Diff line number Diff line
@@ -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)
	}
	}


	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;
	}
	}