|
@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
|
|
|
+static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
if (mutex_lock_interruptible(&fdtv->avc_mutex))
|
|
|
return -EINTR;
|
|
|
|
|
|
- ret = fdtv->backend->lock(fdtv, addr, data, arg);
|
|
|
+ ret = fdtv->backend->lock(fdtv, addr, data);
|
|
|
if (ret < 0)
|
|
|
dev_err(fdtv->device, "CMP: lock I/O error\n");
|
|
|
|
|
@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
|
|
|
|
|
|
int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
|
|
|
{
|
|
|
- __be32 old_opcr, opcr;
|
|
|
+ __be32 old_opcr, opcr[2];
|
|
|
u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
|
|
|
int attempts = 0;
|
|
|
int ret;
|
|
|
|
|
|
- ret = cmp_read(fdtv, &opcr, opcr_address, 4);
|
|
|
+ ret = cmp_read(fdtv, opcr, opcr_address, 4);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
repeat:
|
|
|
- if (!get_opcr_online(opcr)) {
|
|
|
+ if (!get_opcr_online(*opcr)) {
|
|
|
dev_err(fdtv->device, "CMP: output offline\n");
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
|
|
|
- old_opcr = opcr;
|
|
|
+ old_opcr = *opcr;
|
|
|
|
|
|
- if (get_opcr_p2p_connections(opcr)) {
|
|
|
- if (get_opcr_channel(opcr) != channel) {
|
|
|
+ if (get_opcr_p2p_connections(*opcr)) {
|
|
|
+ if (get_opcr_channel(*opcr) != channel) {
|
|
|
dev_err(fdtv->device, "CMP: cannot change channel\n");
|
|
|
return -EBUSY;
|
|
|
}
|
|
@@ -1314,11 +1314,11 @@ repeat:
|
|
|
|
|
|
/* We don't allocate isochronous resources. */
|
|
|
} else {
|
|
|
- set_opcr_channel(&opcr, channel);
|
|
|
- set_opcr_data_rate(&opcr, 2); /* S400 */
|
|
|
+ set_opcr_channel(opcr, channel);
|
|
|
+ set_opcr_data_rate(opcr, 2); /* S400 */
|
|
|
|
|
|
/* FIXME: this is for the worst case - optimize */
|
|
|
- set_opcr_overhead_id(&opcr, 0);
|
|
|
+ set_opcr_overhead_id(opcr, 0);
|
|
|
|
|
|
/*
|
|
|
* FIXME: allocate isochronous channel and bandwidth at IRM
|
|
@@ -1326,13 +1326,16 @@ repeat:
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
- set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
|
|
|
+ set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
|
|
|
|
|
|
- ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
|
|
|
+ opcr[1] = *opcr;
|
|
|
+ opcr[0] = old_opcr;
|
|
|
+
|
|
|
+ ret = cmp_lock(fdtv, opcr_address, opcr);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
- if (old_opcr != opcr) {
|
|
|
+ if (old_opcr != *opcr) {
|
|
|
/*
|
|
|
* FIXME: if old_opcr.P2P_Connections > 0,
|
|
|
* deallocate isochronous channel and bandwidth at IRM
|
|
@@ -1350,27 +1353,30 @@ repeat:
|
|
|
|
|
|
void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
|
|
|
{
|
|
|
- __be32 old_opcr, opcr;
|
|
|
+ __be32 old_opcr, opcr[2];
|
|
|
u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
|
|
|
int attempts = 0;
|
|
|
|
|
|
- if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
|
|
|
+ if (cmp_read(fdtv, opcr, opcr_address, 4) < 0)
|
|
|
return;
|
|
|
|
|
|
repeat:
|
|
|
- if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
|
|
|
- get_opcr_channel(opcr) != channel) {
|
|
|
+ if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
|
|
|
+ get_opcr_channel(*opcr) != channel) {
|
|
|
dev_err(fdtv->device, "CMP: no connection to break\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- old_opcr = opcr;
|
|
|
- set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
|
|
|
+ old_opcr = *opcr;
|
|
|
+ set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
|
|
|
+
|
|
|
+ opcr[1] = *opcr;
|
|
|
+ opcr[0] = old_opcr;
|
|
|
|
|
|
- if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
|
|
|
+ if (cmp_lock(fdtv, opcr_address, opcr) < 0)
|
|
|
return;
|
|
|
|
|
|
- if (old_opcr != opcr) {
|
|
|
+ if (old_opcr != *opcr) {
|
|
|
/*
|
|
|
* FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
|
|
|
* owner, deallocate isochronous channel and bandwidth at IRM
|