diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:50:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:50:49 -0500 |
commit | 3e7468313758913c5e4d372f35b271b96bad1298 (patch) | |
tree | eb612d252a9e2349a1173451cd779beebd18a33e /drivers/media/dvb/firewire/firedtv-avc.c | |
parent | 6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff) | |
parent | e97f4677961f68e29bd906022ebf60a6df7f530a (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.c | 54 |
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 | ||
1239 | static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) | 1239 | static 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 | ||
1254 | static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) | 1254 | static 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 | ||
1289 | int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) | 1289 | int 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 | ||
1300 | repeat: | 1300 | repeat: |
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 | ||
1351 | void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) | 1354 | void 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 | ||
1360 | repeat: | 1363 | repeat: |
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 |