aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-09-04 17:35:59 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-09-21 18:50:11 -0400
commitd4d6a34d36b1e72d0c5cf470a41fc7bc79acd73f (patch)
tree7daf155e5d1a0d10ee31161702f706dfb7b0b563
parent1066d77f682e84efb56fbd4e5c8bb236532eccc7 (diff)
[media] af9035: remove I2C client differently
It crash kernel when device was removed while it was streaming. That is because we removed driver and frontend thread was still running. Use new callback which allows I2C driver removal just after frontend is unregistered. V2: fixed by reported by Daniel Reported-by: Daniel Glöckner <daniel-gl@gmx.net> Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c93
1 files changed, 67 insertions, 26 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 94563b2f1d48..440ecb459b9c 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -1074,15 +1074,13 @@ static int af9035_get_adapter_count(struct dvb_usb_device *d)
1074 return state->dual_mode + 1; 1074 return state->dual_mode + 1;
1075} 1075}
1076 1076
1077static void af9035_exit(struct dvb_usb_device *d);
1078
1079static int af9035_frontend_attach(struct dvb_usb_adapter *adap) 1077static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
1080{ 1078{
1081 struct state *state = adap_to_priv(adap); 1079 struct state *state = adap_to_priv(adap);
1082 struct dvb_usb_device *d = adap_to_d(adap); 1080 struct dvb_usb_device *d = adap_to_d(adap);
1083 int ret; 1081 int ret;
1084 1082
1085 dev_dbg(&d->udev->dev, "%s:\n", __func__); 1083 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
1086 1084
1087 if (!state->af9033_config[adap->id].tuner) { 1085 if (!state->af9033_config[adap->id].tuner) {
1088 /* unsupported tuner */ 1086 /* unsupported tuner */
@@ -1109,12 +1107,48 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
1109 return 0; 1107 return 0;
1110 1108
1111err: 1109err:
1112 af9035_exit(d); /* remove I2C clients */
1113 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1110 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1114 1111
1115 return ret; 1112 return ret;
1116} 1113}
1117 1114
1115static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
1116{
1117 struct state *state = adap_to_priv(adap);
1118 struct dvb_usb_device *d = adap_to_d(adap);
1119 int demod2;
1120
1121 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
1122
1123 /*
1124 * For dual tuner devices we have to resolve 2nd demod client, as there
1125 * is two different kind of tuner drivers; one is using I2C binding
1126 * and the other is using DVB attach/detach binding.
1127 */
1128 switch (state->af9033_config[adap->id].tuner) {
1129 case AF9033_TUNER_IT9135_38:
1130 case AF9033_TUNER_IT9135_51:
1131 case AF9033_TUNER_IT9135_52:
1132 case AF9033_TUNER_IT9135_60:
1133 case AF9033_TUNER_IT9135_61:
1134 case AF9033_TUNER_IT9135_62:
1135 demod2 = 2;
1136 break;
1137 default:
1138 demod2 = 1;
1139 }
1140
1141 if (adap->id == 1) {
1142 if (state->i2c_client[demod2])
1143 af9035_del_i2c_dev(d);
1144 } else if (adap->id == 0) {
1145 if (state->i2c_client[0])
1146 af9035_del_i2c_dev(d);
1147 }
1148
1149 return 0;
1150}
1151
1118static struct tua9001_config af9035_tua9001_config = { 1152static struct tua9001_config af9035_tua9001_config = {
1119 .i2c_addr = 0x60, 1153 .i2c_addr = 0x60,
1120}; 1154};
@@ -1174,7 +1208,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
1174 struct i2c_msg msg[1]; 1208 struct i2c_msg msg[1];
1175 u8 tuner_addr; 1209 u8 tuner_addr;
1176 1210
1177 dev_dbg(&d->udev->dev, "%s:\n", __func__); 1211 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
1178 1212
1179 /* 1213 /*
1180 * XXX: Hack used in that function: we abuse unused I2C address bit [7] 1214 * XXX: Hack used in that function: we abuse unused I2C address bit [7]
@@ -1392,12 +1426,37 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
1392 return 0; 1426 return 0;
1393 1427
1394err: 1428err:
1395 af9035_exit(d); /* remove I2C clients */
1396 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1429 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1397 1430
1398 return ret; 1431 return ret;
1399} 1432}
1400 1433
1434static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
1435{
1436 struct state *state = adap_to_priv(adap);
1437 struct dvb_usb_device *d = adap_to_d(adap);
1438
1439 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
1440
1441 switch (state->af9033_config[adap->id].tuner) {
1442 case AF9033_TUNER_IT9135_38:
1443 case AF9033_TUNER_IT9135_51:
1444 case AF9033_TUNER_IT9135_52:
1445 case AF9033_TUNER_IT9135_60:
1446 case AF9033_TUNER_IT9135_61:
1447 case AF9033_TUNER_IT9135_62:
1448 if (adap->id == 1) {
1449 if (state->i2c_client[3])
1450 af9035_del_i2c_dev(d);
1451 } else if (adap->id == 0) {
1452 if (state->i2c_client[1])
1453 af9035_del_i2c_dev(d);
1454 }
1455 }
1456
1457 return 0;
1458}
1459
1401static int af9035_init(struct dvb_usb_device *d) 1460static int af9035_init(struct dvb_usb_device *d)
1402{ 1461{
1403 struct state *state = d_to_priv(d); 1462 struct state *state = d_to_priv(d);
@@ -1445,25 +1504,6 @@ err:
1445 return ret; 1504 return ret;
1446} 1505}
1447 1506
1448static void af9035_exit(struct dvb_usb_device *d)
1449{
1450 struct state *state = d_to_priv(d);
1451
1452 dev_dbg(&d->udev->dev, "%s:\n", __func__);
1453
1454 if (state->i2c_client[3])
1455 af9035_del_i2c_dev(d);
1456
1457 if (state->i2c_client[2])
1458 af9035_del_i2c_dev(d);
1459
1460 if (state->i2c_client[1])
1461 af9035_del_i2c_dev(d);
1462
1463 if (state->i2c_client[0])
1464 af9035_del_i2c_dev(d);
1465}
1466
1467#if IS_ENABLED(CONFIG_RC_CORE) 1507#if IS_ENABLED(CONFIG_RC_CORE)
1468static int af9035_rc_query(struct dvb_usb_device *d) 1508static int af9035_rc_query(struct dvb_usb_device *d)
1469{ 1509{
@@ -1636,11 +1676,12 @@ static const struct dvb_usb_device_properties af9035_props = {
1636 .i2c_algo = &af9035_i2c_algo, 1676 .i2c_algo = &af9035_i2c_algo,
1637 .read_config = af9035_read_config, 1677 .read_config = af9035_read_config,
1638 .frontend_attach = af9035_frontend_attach, 1678 .frontend_attach = af9035_frontend_attach,
1679 .frontend_detach = af9035_frontend_detach,
1639 .tuner_attach = af9035_tuner_attach, 1680 .tuner_attach = af9035_tuner_attach,
1681 .tuner_detach = af9035_tuner_detach,
1640 .init = af9035_init, 1682 .init = af9035_init,
1641 .get_rc_config = af9035_get_rc_config, 1683 .get_rc_config = af9035_get_rc_config,
1642 .get_stream_config = af9035_get_stream_config, 1684 .get_stream_config = af9035_get_stream_config,
1643 .exit = af9035_exit,
1644 1685
1645 .get_adapter_count = af9035_get_adapter_count, 1686 .get_adapter_count = af9035_get_adapter_count,
1646 .adapter = { 1687 .adapter = {