aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/xc4000.c
diff options
context:
space:
mode:
authorIstvan Varga <istvan_v@mailbox.hu>2011-06-03 11:23:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:34 -0400
commit5614942bb06f5620d0d6eb67bc0268c76c5dd921 (patch)
tree044e35ce245775eeac12e25d4c04cab828010355 /drivers/media/common/tuners/xc4000.c
parentf0ef7c88ca919912011593d2392a59c2fde04748 (diff)
[media] xc4000: added mutex
This patch adds a mutex to xc4000_priv, to protect the driver from being accessed by multiple processes at the same time. Signed-off-by: Istvan Varga <istvan_v@mailbox.hu> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common/tuners/xc4000.c')
-rw-r--r--drivers/media/common/tuners/xc4000.c80
1 files changed, 50 insertions, 30 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 307a8745e06e..be43a6dfac6c 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -28,6 +28,7 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/dvb/frontend.h> 29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/mutex.h>
31#include <asm/unaligned.h> 32#include <asm/unaligned.h>
32 33
33#include "dvb_frontend.h" 34#include "dvb_frontend.h"
@@ -90,6 +91,7 @@ struct xc4000_priv {
90 struct firmware_properties cur_fw; 91 struct firmware_properties cur_fw;
91 __u16 hwmodel; 92 __u16 hwmodel;
92 __u16 hwvers; 93 __u16 hwvers;
94 struct mutex lock;
93}; 95};
94 96
95/* Misc Defines */ 97/* Misc Defines */
@@ -1145,10 +1147,12 @@ static int xc4000_set_params(struct dvb_frontend *fe,
1145{ 1147{
1146 struct xc4000_priv *priv = fe->tuner_priv; 1148 struct xc4000_priv *priv = fe->tuner_priv;
1147 unsigned int type; 1149 unsigned int type;
1148 int ret; 1150 int ret = -EREMOTEIO;
1149 1151
1150 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 1152 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1151 1153
1154 mutex_lock(&priv->lock);
1155
1152 if (fe->ops.info.type == FE_ATSC) { 1156 if (fe->ops.info.type == FE_ATSC) {
1153 dprintk(1, "%s() ATSC\n", __func__); 1157 dprintk(1, "%s() ATSC\n", __func__);
1154 switch (params->u.vsb.modulation) { 1158 switch (params->u.vsb.modulation) {
@@ -1172,7 +1176,8 @@ static int xc4000_set_params(struct dvb_frontend *fe,
1172 type = DTV6; 1176 type = DTV6;
1173 break; 1177 break;
1174 default: 1178 default:
1175 return -EINVAL; 1179 ret = -EINVAL;
1180 goto fail;
1176 } 1181 }
1177 } else if (fe->ops.info.type == FE_OFDM) { 1182 } else if (fe->ops.info.type == FE_OFDM) {
1178 dprintk(1, "%s() OFDM\n", __func__); 1183 dprintk(1, "%s() OFDM\n", __func__);
@@ -1208,28 +1213,29 @@ static int xc4000_set_params(struct dvb_frontend *fe,
1208 break; 1213 break;
1209 default: 1214 default:
1210 printk(KERN_ERR "xc4000 bandwidth not set!\n"); 1215 printk(KERN_ERR "xc4000 bandwidth not set!\n");
1211 return -EINVAL; 1216 ret = -EINVAL;
1217 goto fail;
1212 } 1218 }
1213 priv->rf_mode = XC_RF_MODE_AIR; 1219 priv->rf_mode = XC_RF_MODE_AIR;
1214 } else { 1220 } else {
1215 printk(KERN_ERR "xc4000 modulation type not supported!\n"); 1221 printk(KERN_ERR "xc4000 modulation type not supported!\n");
1216 return -EINVAL; 1222 ret = -EINVAL;
1223 goto fail;
1217 } 1224 }
1218 1225
1219 dprintk(1, "%s() frequency=%d (compensated)\n", 1226 dprintk(1, "%s() frequency=%d (compensated)\n",
1220 __func__, priv->freq_hz); 1227 __func__, priv->freq_hz);
1221 1228
1222 /* Make sure the correct firmware type is loaded */ 1229 /* Make sure the correct firmware type is loaded */
1223 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS) { 1230 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1224 return -EREMOTEIO; 1231 goto fail;
1225 }
1226 1232
1227 ret = xc_SetSignalSource(priv, priv->rf_mode); 1233 ret = xc_SetSignalSource(priv, priv->rf_mode);
1228 if (ret != XC_RESULT_SUCCESS) { 1234 if (ret != XC_RESULT_SUCCESS) {
1229 printk(KERN_ERR 1235 printk(KERN_ERR
1230 "xc4000: xc_SetSignalSource(%d) failed\n", 1236 "xc4000: xc_SetSignalSource(%d) failed\n",
1231 priv->rf_mode); 1237 priv->rf_mode);
1232 return -EREMOTEIO; 1238 goto fail;
1233 } 1239 }
1234 1240
1235 ret = xc_SetTVStandard(priv, 1241 ret = xc_SetTVStandard(priv,
@@ -1237,33 +1243,32 @@ static int xc4000_set_params(struct dvb_frontend *fe,
1237 XC4000_Standard[priv->video_standard].AudioMode); 1243 XC4000_Standard[priv->video_standard].AudioMode);
1238 if (ret != XC_RESULT_SUCCESS) { 1244 if (ret != XC_RESULT_SUCCESS) {
1239 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n"); 1245 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1240 return -EREMOTEIO; 1246 goto fail;
1241 }
1242#ifdef DJH_DEBUG
1243 ret = xc_set_IF_frequency(priv, priv->if_khz);
1244 if (ret != XC_RESULT_SUCCESS) {
1245 printk(KERN_ERR "xc4000: xc_Set_IF_frequency(%d) failed\n",
1246 priv->if_khz);
1247 return -EIO;
1248 } 1247 }
1249#endif
1250 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); 1248 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1251 1249
1252 if (debug) 1250 if (debug)
1253 xc_debug_dump(priv); 1251 xc_debug_dump(priv);
1254 1252
1255 return 0; 1253 ret = 0;
1254
1255fail:
1256 mutex_unlock(&priv->lock);
1257
1258 return ret;
1256} 1259}
1257 1260
1258static int xc4000_set_analog_params(struct dvb_frontend *fe, 1261static int xc4000_set_analog_params(struct dvb_frontend *fe,
1259 struct analog_parameters *params) 1262 struct analog_parameters *params)
1260{ 1263{
1261 struct xc4000_priv *priv = fe->tuner_priv; 1264 struct xc4000_priv *priv = fe->tuner_priv;
1262 int ret; 1265 int ret = -EREMOTEIO;
1263 1266
1264 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", 1267 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1265 __func__, params->frequency); 1268 __func__, params->frequency);
1266 1269
1270 mutex_lock(&priv->lock);
1271
1267 /* Fix me: it could be air. */ 1272 /* Fix me: it could be air. */
1268 priv->rf_mode = params->mode; 1273 priv->rf_mode = params->mode;
1269 if (params->mode > XC_RF_MODE_CABLE) 1274 if (params->mode > XC_RF_MODE_CABLE)
@@ -1318,16 +1323,15 @@ static int xc4000_set_analog_params(struct dvb_frontend *fe,
1318tune_channel: 1323tune_channel:
1319 1324
1320 /* FIXME - firmware type not being set properly */ 1325 /* FIXME - firmware type not being set properly */
1321 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) { 1326 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1322 return -EREMOTEIO; 1327 goto fail;
1323 }
1324 1328
1325 ret = xc_SetSignalSource(priv, priv->rf_mode); 1329 ret = xc_SetSignalSource(priv, priv->rf_mode);
1326 if (ret != XC_RESULT_SUCCESS) { 1330 if (ret != XC_RESULT_SUCCESS) {
1327 printk(KERN_ERR 1331 printk(KERN_ERR
1328 "xc4000: xc_SetSignalSource(%d) failed\n", 1332 "xc4000: xc_SetSignalSource(%d) failed\n",
1329 priv->rf_mode); 1333 priv->rf_mode);
1330 return -EREMOTEIO; 1334 goto fail;
1331 } 1335 }
1332 1336
1333 ret = xc_SetTVStandard(priv, 1337 ret = xc_SetTVStandard(priv,
@@ -1335,7 +1339,7 @@ tune_channel:
1335 XC4000_Standard[priv->video_standard].AudioMode); 1339 XC4000_Standard[priv->video_standard].AudioMode);
1336 if (ret != XC_RESULT_SUCCESS) { 1340 if (ret != XC_RESULT_SUCCESS) {
1337 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n"); 1341 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1338 return -EREMOTEIO; 1342 goto fail;
1339 } 1343 }
1340 1344
1341 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); 1345 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
@@ -1343,7 +1347,12 @@ tune_channel:
1343 if (debug) 1347 if (debug)
1344 xc_debug_dump(priv); 1348 xc_debug_dump(priv);
1345 1349
1346 return 0; 1350 ret = 0;
1351
1352fail:
1353 mutex_unlock(&priv->lock);
1354
1355 return ret;
1347} 1356}
1348 1357
1349static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) 1358static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
@@ -1368,8 +1377,12 @@ static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1368 struct xc4000_priv *priv = fe->tuner_priv; 1377 struct xc4000_priv *priv = fe->tuner_priv;
1369 u16 lock_status = 0; 1378 u16 lock_status = 0;
1370 1379
1380 mutex_lock(&priv->lock);
1381
1371 xc_get_lock_status(priv, &lock_status); 1382 xc_get_lock_status(priv, &lock_status);
1372 1383
1384 mutex_unlock(&priv->lock);
1385
1373 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status); 1386 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
1374 1387
1375 *status = lock_status; 1388 *status = lock_status;
@@ -1386,9 +1399,13 @@ static int xc4000_sleep(struct dvb_frontend *fe)
1386static int xc4000_init(struct dvb_frontend *fe) 1399static int xc4000_init(struct dvb_frontend *fe)
1387{ 1400{
1388 struct xc4000_priv *priv = fe->tuner_priv; 1401 struct xc4000_priv *priv = fe->tuner_priv;
1402 int ret;
1389 dprintk(1, "%s()\n", __func__); 1403 dprintk(1, "%s()\n", __func__);
1390 1404
1391 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) { 1405 mutex_lock(&priv->lock);
1406 ret = check_firmware(fe, DTV8, 0, priv->if_khz);
1407 mutex_unlock(&priv->lock);
1408 if (ret != XC_RESULT_SUCCESS) {
1392 printk(KERN_ERR "xc4000: Unable to initialise tuner\n"); 1409 printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
1393 return -EREMOTEIO; 1410 return -EREMOTEIO;
1394 } 1411 }
@@ -1460,6 +1477,7 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1460 case 1: 1477 case 1:
1461 /* new tuner instance */ 1478 /* new tuner instance */
1462 priv->bandwidth = BANDWIDTH_6_MHZ; 1479 priv->bandwidth = BANDWIDTH_6_MHZ;
1480 mutex_init(&priv->lock);
1463 fe->tuner_priv = priv; 1481 fe->tuner_priv = priv;
1464 break; 1482 break;
1465 default: 1483 default:
@@ -1511,7 +1529,9 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1511 1529
1512 /* FIXME: For now, load the firmware at startup. We will remove this 1530 /* FIXME: For now, load the firmware at startup. We will remove this
1513 before the code goes to production... */ 1531 before the code goes to production... */
1532 mutex_lock(&priv->lock);
1514 check_firmware(fe, DTV8, 0, priv->if_khz); 1533 check_firmware(fe, DTV8, 0, priv->if_khz);
1534 mutex_unlock(&priv->lock);
1515 1535
1516 return fe; 1536 return fe;
1517fail: 1537fail: