Commit 425f53aa authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] em28xx-dvb: fix PCTV 461e tuner I2C binding

Add missing m88ts2022 module reference counts as removing that module
is not allowed when it is used by em28xx-dvb module. That same module
was not unregistered correctly, fix it too.

Error cases validated by returning errors from m88ds3103, m88ts2022
and a8293 probe().
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 37e59f87
...@@ -1374,6 +1374,7 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -1374,6 +1374,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
{ {
/* demod I2C adapter */ /* demod I2C adapter */
struct i2c_adapter *i2c_adapter; struct i2c_adapter *i2c_adapter;
struct i2c_client *client;
struct i2c_board_info info; struct i2c_board_info info;
struct m88ts2022_config m88ts2022_config = { struct m88ts2022_config m88ts2022_config = {
.clock = 27000000, .clock = 27000000,
...@@ -1396,7 +1397,19 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -1396,7 +1397,19 @@ static int em28xx_dvb_init(struct em28xx *dev)
info.addr = 0x60; info.addr = 0x60;
info.platform_data = &m88ts2022_config; info.platform_data = &m88ts2022_config;
request_module("m88ts2022"); request_module("m88ts2022");
dvb->i2c_client_tuner = i2c_new_device(i2c_adapter, &info); client = i2c_new_device(i2c_adapter, &info);
if (client == NULL || client->dev.driver == NULL) {
dvb_frontend_detach(dvb->fe[0]);
result = -ENODEV;
goto out_free;
}
if (!try_module_get(client->dev.driver->owner)) {
i2c_unregister_device(client);
dvb_frontend_detach(dvb->fe[0]);
result = -ENODEV;
goto out_free;
}
/* delegate signal strength measurement to tuner */ /* delegate signal strength measurement to tuner */
dvb->fe[0]->ops.read_signal_strength = dvb->fe[0]->ops.read_signal_strength =
...@@ -1406,10 +1419,14 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -1406,10 +1419,14 @@ static int em28xx_dvb_init(struct em28xx *dev)
if (!dvb_attach(a8293_attach, dvb->fe[0], if (!dvb_attach(a8293_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus], &dev->i2c_adap[dev->def_i2c_bus],
&em28xx_a8293_config)) { &em28xx_a8293_config)) {
module_put(client->dev.driver->owner);
i2c_unregister_device(client);
dvb_frontend_detach(dvb->fe[0]); dvb_frontend_detach(dvb->fe[0]);
result = -ENODEV; result = -ENODEV;
goto out_free; goto out_free;
} }
dvb->i2c_client_tuner = client;
} }
break; break;
default: default:
...@@ -1471,6 +1488,7 @@ static int em28xx_dvb_fini(struct em28xx *dev) ...@@ -1471,6 +1488,7 @@ static int em28xx_dvb_fini(struct em28xx *dev)
if (dev->dvb) { if (dev->dvb) {
struct em28xx_dvb *dvb = dev->dvb; struct em28xx_dvb *dvb = dev->dvb;
struct i2c_client *client = dvb->i2c_client_tuner;
em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
...@@ -1483,7 +1501,12 @@ static int em28xx_dvb_fini(struct em28xx *dev) ...@@ -1483,7 +1501,12 @@ static int em28xx_dvb_fini(struct em28xx *dev)
prevent_sleep(&dvb->fe[1]->ops); prevent_sleep(&dvb->fe[1]->ops);
} }
i2c_release_client(dvb->i2c_client_tuner); /* remove I2C tuner */
if (client) {
module_put(client->dev.driver->owner);
i2c_unregister_device(client);
}
em28xx_unregister_dvb(dvb); em28xx_unregister_dvb(dvb);
kfree(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