|
@@ -1374,6 +1374,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|
|
{
|
|
|
/* demod I2C adapter */
|
|
|
struct i2c_adapter *i2c_adapter;
|
|
|
+ struct i2c_client *client;
|
|
|
struct i2c_board_info info;
|
|
|
struct m88ts2022_config m88ts2022_config = {
|
|
|
.clock = 27000000,
|
|
@@ -1396,7 +1397,19 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|
|
info.addr = 0x60;
|
|
|
info.platform_data = &m88ts2022_config;
|
|
|
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 */
|
|
|
dvb->fe[0]->ops.read_signal_strength =
|
|
@@ -1406,10 +1419,14 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|
|
if (!dvb_attach(a8293_attach, dvb->fe[0],
|
|
|
&dev->i2c_adap[dev->def_i2c_bus],
|
|
|
&em28xx_a8293_config)) {
|
|
|
+ module_put(client->dev.driver->owner);
|
|
|
+ i2c_unregister_device(client);
|
|
|
dvb_frontend_detach(dvb->fe[0]);
|
|
|
result = -ENODEV;
|
|
|
goto out_free;
|
|
|
}
|
|
|
+
|
|
|
+ dvb->i2c_client_tuner = client;
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
@@ -1471,6 +1488,7 @@ static int em28xx_dvb_fini(struct em28xx *dev)
|
|
|
|
|
|
if (dev->dvb) {
|
|
|
struct em28xx_dvb *dvb = dev->dvb;
|
|
|
+ struct i2c_client *client = dvb->i2c_client_tuner;
|
|
|
|
|
|
em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
|
|
|
|
|
@@ -1483,7 +1501,12 @@ static int em28xx_dvb_fini(struct em28xx *dev)
|
|
|
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);
|
|
|
kfree(dvb);
|
|
|
dev->dvb = NULL;
|