aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firewire/firedtv-avc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
commit3e7468313758913c5e4d372f35b271b96bad1298 (patch)
treeeb612d252a9e2349a1173451cd779beebd18a33e /drivers/media/dvb/firewire/firedtv-avc.c
parent6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff)
parente97f4677961f68e29bd906022ebf60a6df7f530a (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (345 commits) V4L/DVB (13542): ir-keytable: Allow dynamic table change V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage V4L/DVB (13540): ir-common: Cleanup get key evdev code V4L/DVB (13539): ir-common: add __func__ for debug messages V4L/DVB (13538): ir-common: Use a dynamic keycode table V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code V4L/DVB (13534): ir-common: Remove some unused fields/structs V4L/DVB (13533): ir: use dynamic tables, instead of static ones V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it V4L/DVB (13458): go7007: subdev conversion V4L/DVB (13457): s2250: subdev conversion V4L/DVB (13456): s2250: Change module structure V4L/DVB (13528): em28xx: add support for em2800 VC211A card em28xx: don't reduce scale to half size for em2800 em28xx: don't load audio modules when AC97 is mis-detected em28xx: em2800 chips support max width of 640 V4L/DVB (13523): dvb-bt8xx: fix compile warning ... Fix up trivial conflicts due to spelling fixes from the trivial tree in Documentation/video4linux/gspca.txt drivers/media/video/cx18/cx18-mailbox.h
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-avc.c')
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 485d061319ab..50c42a4b972b 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -1236,14 +1236,14 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1236 1236
1237#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL 1237#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
1238 1238
1239static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) 1239static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1240{ 1240{
1241 int ret; 1241 int ret;
1242 1242
1243 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1243 if (mutex_lock_interruptible(&fdtv->avc_mutex))
1244 return -EINTR; 1244 return -EINTR;
1245 1245
1246 ret = fdtv->backend->read(fdtv, addr, buf, len); 1246 ret = fdtv->backend->read(fdtv, addr, data);
1247 if (ret < 0) 1247 if (ret < 0)
1248 dev_err(fdtv->device, "CMP: read I/O error\n"); 1248 dev_err(fdtv->device, "CMP: read I/O error\n");
1249 1249
@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
1251 return ret; 1251 return ret;
1252} 1252}
1253 1253
1254static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) 1254static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1255{ 1255{
1256 int ret; 1256 int ret;
1257 1257
1258 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1258 if (mutex_lock_interruptible(&fdtv->avc_mutex))
1259 return -EINTR; 1259 return -EINTR;
1260 1260
1261 ret = fdtv->backend->lock(fdtv, addr, data, arg); 1261 ret = fdtv->backend->lock(fdtv, addr, data);
1262 if (ret < 0) 1262 if (ret < 0)
1263 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1263 dev_err(fdtv->device, "CMP: lock I/O error\n");
1264 1264
@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
1288 1288
1289int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) 1289int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
1290{ 1290{
1291 __be32 old_opcr, opcr; 1291 __be32 old_opcr, opcr[2];
1292 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); 1292 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1293 int attempts = 0; 1293 int attempts = 0;
1294 int ret; 1294 int ret;
1295 1295
1296 ret = cmp_read(fdtv, &opcr, opcr_address, 4); 1296 ret = cmp_read(fdtv, opcr_address, opcr);
1297 if (ret < 0) 1297 if (ret < 0)
1298 return ret; 1298 return ret;
1299 1299
1300repeat: 1300repeat:
1301 if (!get_opcr_online(opcr)) { 1301 if (!get_opcr_online(*opcr)) {
1302 dev_err(fdtv->device, "CMP: output offline\n"); 1302 dev_err(fdtv->device, "CMP: output offline\n");
1303 return -EBUSY; 1303 return -EBUSY;
1304 } 1304 }
1305 1305
1306 old_opcr = opcr; 1306 old_opcr = *opcr;
1307 1307
1308 if (get_opcr_p2p_connections(opcr)) { 1308 if (get_opcr_p2p_connections(*opcr)) {
1309 if (get_opcr_channel(opcr) != channel) { 1309 if (get_opcr_channel(*opcr) != channel) {
1310 dev_err(fdtv->device, "CMP: cannot change channel\n"); 1310 dev_err(fdtv->device, "CMP: cannot change channel\n");
1311 return -EBUSY; 1311 return -EBUSY;
1312 } 1312 }
@@ -1314,11 +1314,11 @@ repeat:
1314 1314
1315 /* We don't allocate isochronous resources. */ 1315 /* We don't allocate isochronous resources. */
1316 } else { 1316 } else {
1317 set_opcr_channel(&opcr, channel); 1317 set_opcr_channel(opcr, channel);
1318 set_opcr_data_rate(&opcr, 2); /* S400 */ 1318 set_opcr_data_rate(opcr, 2); /* S400 */
1319 1319
1320 /* FIXME: this is for the worst case - optimize */ 1320 /* FIXME: this is for the worst case - optimize */
1321 set_opcr_overhead_id(&opcr, 0); 1321 set_opcr_overhead_id(opcr, 0);
1322 1322
1323 /* 1323 /*
1324 * FIXME: allocate isochronous channel and bandwidth at IRM 1324 * FIXME: allocate isochronous channel and bandwidth at IRM
@@ -1326,13 +1326,16 @@ repeat:
1326 */ 1326 */
1327 } 1327 }
1328 1328
1329 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); 1329 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
1330 1330
1331 ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); 1331 opcr[1] = *opcr;
1332 opcr[0] = old_opcr;
1333
1334 ret = cmp_lock(fdtv, opcr_address, opcr);
1332 if (ret < 0) 1335 if (ret < 0)
1333 return ret; 1336 return ret;
1334 1337
1335 if (old_opcr != opcr) { 1338 if (old_opcr != *opcr) {
1336 /* 1339 /*
1337 * FIXME: if old_opcr.P2P_Connections > 0, 1340 * FIXME: if old_opcr.P2P_Connections > 0,
1338 * deallocate isochronous channel and bandwidth at IRM 1341 * deallocate isochronous channel and bandwidth at IRM
@@ -1350,27 +1353,30 @@ repeat:
1350 1353
1351void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) 1354void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
1352{ 1355{
1353 __be32 old_opcr, opcr; 1356 __be32 old_opcr, opcr[2];
1354 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); 1357 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
1355 int attempts = 0; 1358 int attempts = 0;
1356 1359
1357 if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) 1360 if (cmp_read(fdtv, opcr_address, opcr) < 0)
1358 return; 1361 return;
1359 1362
1360repeat: 1363repeat:
1361 if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || 1364 if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
1362 get_opcr_channel(opcr) != channel) { 1365 get_opcr_channel(*opcr) != channel) {
1363 dev_err(fdtv->device, "CMP: no connection to break\n"); 1366 dev_err(fdtv->device, "CMP: no connection to break\n");
1364 return; 1367 return;
1365 } 1368 }
1366 1369
1367 old_opcr = opcr; 1370 old_opcr = *opcr;
1368 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); 1371 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
1372
1373 opcr[1] = *opcr;
1374 opcr[0] = old_opcr;
1369 1375
1370 if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) 1376 if (cmp_lock(fdtv, opcr_address, opcr) < 0)
1371 return; 1377 return;
1372 1378
1373 if (old_opcr != opcr) { 1379 if (old_opcr != *opcr) {
1374 /* 1380 /*
1375 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last 1381 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
1376 * owner, deallocate isochronous channel and bandwidth at IRM 1382 * owner, deallocate isochronous channel and bandwidth at IRM