Lines Matching refs:c

46 void cmp_error(struct cmp_connection *c, const char *fmt, ...)  in cmp_error()  argument
51 dev_err(&c->resources.unit->device, "%cPCR%u: %pV", in cmp_error()
52 (c->direction == CMP_INPUT) ? 'i' : 'o', in cmp_error()
53 c->pcr_index, &(struct va_format){ fmt, &va }); in cmp_error()
57 static u64 mpr_address(struct cmp_connection *c) in mpr_address() argument
59 if (c->direction == CMP_INPUT) in mpr_address()
65 static u64 pcr_address(struct cmp_connection *c) in pcr_address() argument
67 if (c->direction == CMP_INPUT) in pcr_address()
68 return CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index); in pcr_address()
70 return CSR_REGISTER_BASE + CSR_OPCR(c->pcr_index); in pcr_address()
73 static int pcr_modify(struct cmp_connection *c, in pcr_modify() argument
74 __be32 (*modify)(struct cmp_connection *c, __be32 old), in pcr_modify() argument
75 int (*check)(struct cmp_connection *c, __be32 pcr), in pcr_modify() argument
81 buffer[0] = c->last_pcr_value; in pcr_modify()
84 buffer[1] = modify(c, buffer[0]); in pcr_modify()
87 c->resources.unit, TCODE_LOCK_COMPARE_SWAP, in pcr_modify()
88 pcr_address(c), buffer, 8, in pcr_modify()
89 FW_FIXED_GENERATION | c->resources.generation); in pcr_modify()
102 err = check(c, buffer[0]); in pcr_modify()
107 c->last_pcr_value = buffer[1]; in pcr_modify()
120 int cmp_connection_init(struct cmp_connection *c, in cmp_connection_init() argument
129 c->direction = direction; in cmp_connection_init()
131 mpr_address(c), &mpr_be, 4, 0); in cmp_connection_init()
139 err = fw_iso_resources_init(&c->resources, unit); in cmp_connection_init()
143 c->connected = false; in cmp_connection_init()
144 mutex_init(&c->mutex); in cmp_connection_init()
145 c->last_pcr_value = cpu_to_be32(0x80000000); in cmp_connection_init()
146 c->pcr_index = pcr_index; in cmp_connection_init()
147 c->max_speed = (mpr & MPR_SPEED_MASK) >> MPR_SPEED_SHIFT; in cmp_connection_init()
148 if (c->max_speed == SCODE_BETA) in cmp_connection_init()
149 c->max_speed += (mpr & MPR_XSPEED_MASK) >> MPR_XSPEED_SHIFT; in cmp_connection_init()
160 int cmp_connection_check_used(struct cmp_connection *c, bool *used) in cmp_connection_check_used() argument
166 c->resources.unit, TCODE_READ_QUADLET_REQUEST, in cmp_connection_check_used()
167 pcr_address(c), &pcr, 4, 0); in cmp_connection_check_used()
180 void cmp_connection_destroy(struct cmp_connection *c) in cmp_connection_destroy() argument
182 WARN_ON(c->connected); in cmp_connection_destroy()
183 mutex_destroy(&c->mutex); in cmp_connection_destroy()
184 fw_iso_resources_destroy(&c->resources); in cmp_connection_destroy()
189 static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr) in ipcr_set_modify() argument
195 ipcr |= cpu_to_be32(c->resources.channel << PCR_CHANNEL_SHIFT); in ipcr_set_modify()
200 static int get_overhead_id(struct cmp_connection *c) in get_overhead_id() argument
210 if (c->resources.bandwidth_overhead < (id << 5)) in get_overhead_id()
219 static __be32 opcr_set_modify(struct cmp_connection *c, __be32 opcr) in opcr_set_modify() argument
224 if (c->speed > SCODE_400) { in opcr_set_modify()
226 xspd = c->speed - SCODE_800; in opcr_set_modify()
228 spd = c->speed; in opcr_set_modify()
240 opcr |= cpu_to_be32(c->resources.channel << PCR_CHANNEL_SHIFT); in opcr_set_modify()
242 opcr |= cpu_to_be32(get_overhead_id(c) << OPCR_OVERHEAD_ID_SHIFT); in opcr_set_modify()
247 static int pcr_set_check(struct cmp_connection *c, __be32 pcr) in pcr_set_check() argument
251 cmp_error(c, "plug is already in use\n"); in pcr_set_check()
255 cmp_error(c, "plug is not on-line\n"); in pcr_set_check()
273 int cmp_connection_establish(struct cmp_connection *c, in cmp_connection_establish() argument
278 if (WARN_ON(c->connected)) in cmp_connection_establish()
281 c->speed = min(c->max_speed, in cmp_connection_establish()
282 fw_parent_device(c->resources.unit)->max_speed); in cmp_connection_establish()
284 mutex_lock(&c->mutex); in cmp_connection_establish()
287 err = fw_iso_resources_allocate(&c->resources, in cmp_connection_establish()
288 max_payload_bytes, c->speed); in cmp_connection_establish()
292 if (c->direction == CMP_OUTPUT) in cmp_connection_establish()
293 err = pcr_modify(c, opcr_set_modify, pcr_set_check, in cmp_connection_establish()
296 err = pcr_modify(c, ipcr_set_modify, pcr_set_check, in cmp_connection_establish()
300 fw_iso_resources_free(&c->resources); in cmp_connection_establish()
306 c->connected = true; in cmp_connection_establish()
308 mutex_unlock(&c->mutex); in cmp_connection_establish()
313 fw_iso_resources_free(&c->resources); in cmp_connection_establish()
315 mutex_unlock(&c->mutex); in cmp_connection_establish()
331 int cmp_connection_update(struct cmp_connection *c) in cmp_connection_update() argument
335 mutex_lock(&c->mutex); in cmp_connection_update()
337 if (!c->connected) { in cmp_connection_update()
338 mutex_unlock(&c->mutex); in cmp_connection_update()
342 err = fw_iso_resources_update(&c->resources); in cmp_connection_update()
346 if (c->direction == CMP_OUTPUT) in cmp_connection_update()
347 err = pcr_modify(c, opcr_set_modify, pcr_set_check, in cmp_connection_update()
350 err = pcr_modify(c, ipcr_set_modify, pcr_set_check, in cmp_connection_update()
356 mutex_unlock(&c->mutex); in cmp_connection_update()
361 fw_iso_resources_free(&c->resources); in cmp_connection_update()
363 c->connected = false; in cmp_connection_update()
364 mutex_unlock(&c->mutex); in cmp_connection_update()
370 static __be32 pcr_break_modify(struct cmp_connection *c, __be32 pcr) in pcr_break_modify() argument
383 void cmp_connection_break(struct cmp_connection *c) in cmp_connection_break() argument
387 mutex_lock(&c->mutex); in cmp_connection_break()
389 if (!c->connected) { in cmp_connection_break()
390 mutex_unlock(&c->mutex); in cmp_connection_break()
394 err = pcr_modify(c, pcr_break_modify, NULL, SUCCEED_ON_BUS_RESET); in cmp_connection_break()
396 cmp_error(c, "plug is still connected\n"); in cmp_connection_break()
398 fw_iso_resources_free(&c->resources); in cmp_connection_break()
400 c->connected = false; in cmp_connection_break()
402 mutex_unlock(&c->mutex); in cmp_connection_break()