diff options
author | Chris Rankin <rankincj@yahoo.com> | 2011-08-20 15:01:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-09-03 19:50:22 -0400 |
commit | 0b8bd83cf393832f1d00096b866d888b75b374c3 (patch) | |
tree | 86b8f92a7fa4c6ee0b71b496859e3a7a319a1794 | |
parent | 76424a0a50982e4026c7d1d5a0cddc92eecc5969 (diff) |
[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>
-rw-r--r-- | drivers/media/common/tuners/tda18271-fe.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_core.c | 4 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 22 |
3 files changed, 23 insertions, 5 deletions
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 57022e88e338..63cc4004e211 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -1230,7 +1230,7 @@ static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg) | |||
1230 | return 0; | 1230 | return 0; |
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | static struct dvb_tuner_ops tda18271_tuner_ops = { | 1233 | static const struct dvb_tuner_ops tda18271_tuner_ops = { |
1234 | .info = { | 1234 | .info = { |
1235 | .name = "NXP TDA18271HD", | 1235 | .name = "NXP TDA18271HD", |
1236 | .frequency_min = 45000000, | 1236 | .frequency_min = 45000000, |
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 01512670c6a6..036480f967b7 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c | |||
@@ -742,7 +742,7 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
742 | return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); | 742 | return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); |
743 | } | 743 | } |
744 | 744 | ||
745 | static struct dvb_frontend_ops cxd2820r_ops[2]; | 745 | static const struct dvb_frontend_ops cxd2820r_ops[2]; |
746 | 746 | ||
747 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, | 747 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, |
748 | struct i2c_adapter *i2c, struct dvb_frontend *fe) | 748 | struct i2c_adapter *i2c, struct dvb_frontend *fe) |
@@ -796,7 +796,7 @@ error: | |||
796 | } | 796 | } |
797 | EXPORT_SYMBOL(cxd2820r_attach); | 797 | EXPORT_SYMBOL(cxd2820r_attach); |
798 | 798 | ||
799 | static struct dvb_frontend_ops cxd2820r_ops[2] = { | 799 | static const struct dvb_frontend_ops cxd2820r_ops[2] = { |
800 | { | 800 | { |
801 | /* DVB-T/T2 */ | 801 | /* DVB-T/T2 */ |
802 | .info = { | 802 | .info = { |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index b606fc7f842d..62b558ddc02e 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -842,6 +842,13 @@ out_free: | |||
842 | goto ret; | 842 | goto ret; |
843 | } | 843 | } |
844 | 844 | ||
845 | static inline void prevent_sleep(struct dvb_frontend_ops *ops) | ||
846 | { | ||
847 | ops->set_voltage = NULL; | ||
848 | ops->sleep = NULL; | ||
849 | ops->tuner_ops.sleep = NULL; | ||
850 | } | ||
851 | |||
845 | static int em28xx_dvb_fini(struct em28xx *dev) | 852 | static int em28xx_dvb_fini(struct em28xx *dev) |
846 | { | 853 | { |
847 | if (!dev->board.has_dvb) { | 854 | if (!dev->board.has_dvb) { |
@@ -850,8 +857,19 @@ static int em28xx_dvb_fini(struct em28xx *dev) | |||
850 | } | 857 | } |
851 | 858 | ||
852 | if (dev->dvb) { | 859 | if (dev->dvb) { |
853 | em28xx_unregister_dvb(dev->dvb); | 860 | struct em28xx_dvb *dvb = dev->dvb; |
854 | kfree(dev->dvb); | 861 | |
862 | if (dev->state & DEV_DISCONNECTED) { | ||
863 | /* We cannot tell the device to sleep | ||
864 | * once it has been unplugged. */ | ||
865 | if (dvb->fe[0]) | ||
866 | prevent_sleep(&dvb->fe[0]->ops); | ||
867 | if (dvb->fe[1]) | ||
868 | prevent_sleep(&dvb->fe[1]->ops); | ||
869 | } | ||
870 | |||
871 | em28xx_unregister_dvb(dvb); | ||
872 | kfree(dvb); | ||
855 | dev->dvb = NULL; | 873 | dev->dvb = NULL; |
856 | } | 874 | } |
857 | 875 | ||