xref: /openbmc/linux/drivers/usb/typec/ucsi/ucsi.c (revision 45fe9262)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * USB Type-C Connector System Software Interface driver
4  *
5  * Copyright (C) 2017, Intel Corporation
6  * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7  */
8 
9 #include <linux/completion.h>
10 #include <linux/property.h>
11 #include <linux/device.h>
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/usb/typec_dp.h>
16 
17 #include "ucsi.h"
18 #include "trace.h"
19 
20 /*
21  * UCSI_TIMEOUT_MS - PPM communication timeout
22  *
23  * Ideally we could use MIN_TIME_TO_RESPOND_WITH_BUSY (which is defined in UCSI
24  * specification) here as reference, but unfortunately we can't. It is very
25  * difficult to estimate the time it takes for the system to process the command
26  * before it is actually passed to the PPM.
27  */
28 #define UCSI_TIMEOUT_MS		5000
29 
30 /*
31  * UCSI_SWAP_TIMEOUT_MS - Timeout for role swap requests
32  *
33  * 5 seconds is close to the time it takes for CapsCounter to reach 0, so even
34  * if the PPM does not generate Connector Change events before that with
35  * partners that do not support USB Power Delivery, this should still work.
36  */
37 #define UCSI_SWAP_TIMEOUT_MS	5000
38 
39 static int ucsi_acknowledge_command(struct ucsi *ucsi)
40 {
41 	u64 ctrl;
42 
43 	ctrl = UCSI_ACK_CC_CI;
44 	ctrl |= UCSI_ACK_COMMAND_COMPLETE;
45 
46 	return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
47 }
48 
49 static int ucsi_acknowledge_connector_change(struct ucsi *ucsi)
50 {
51 	u64 ctrl;
52 
53 	ctrl = UCSI_ACK_CC_CI;
54 	ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
55 
56 	return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
57 }
58 
59 static int ucsi_exec_command(struct ucsi *ucsi, u64 command);
60 
61 static int ucsi_read_error(struct ucsi *ucsi)
62 {
63 	u16 error;
64 	int ret;
65 
66 	/* Acknowlege the command that failed */
67 	ret = ucsi_acknowledge_command(ucsi);
68 	if (ret)
69 		return ret;
70 
71 	ret = ucsi_exec_command(ucsi, UCSI_GET_ERROR_STATUS);
72 	if (ret < 0)
73 		return ret;
74 
75 	ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, &error, sizeof(error));
76 	if (ret)
77 		return ret;
78 
79 	switch (error) {
80 	case UCSI_ERROR_INCOMPATIBLE_PARTNER:
81 		return -EOPNOTSUPP;
82 	case UCSI_ERROR_CC_COMMUNICATION_ERR:
83 		return -ECOMM;
84 	case UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL:
85 		return -EPROTO;
86 	case UCSI_ERROR_DEAD_BATTERY:
87 		dev_warn(ucsi->dev, "Dead battery condition!\n");
88 		return -EPERM;
89 	case UCSI_ERROR_INVALID_CON_NUM:
90 	case UCSI_ERROR_UNREGONIZED_CMD:
91 	case UCSI_ERROR_INVALID_CMD_ARGUMENT:
92 		dev_err(ucsi->dev, "possible UCSI driver bug %u\n", error);
93 		return -EINVAL;
94 	case UCSI_ERROR_OVERCURRENT:
95 		dev_warn(ucsi->dev, "Overcurrent condition\n");
96 		break;
97 	case UCSI_ERROR_PARTNER_REJECTED_SWAP:
98 		dev_warn(ucsi->dev, "Partner rejected swap\n");
99 		break;
100 	case UCSI_ERROR_HARD_RESET:
101 		dev_warn(ucsi->dev, "Hard reset occurred\n");
102 		break;
103 	case UCSI_ERROR_PPM_POLICY_CONFLICT:
104 		dev_warn(ucsi->dev, "PPM Policy conflict\n");
105 		break;
106 	case UCSI_ERROR_SWAP_REJECTED:
107 		dev_warn(ucsi->dev, "Swap rejected\n");
108 		break;
109 	case UCSI_ERROR_UNDEFINED:
110 	default:
111 		dev_err(ucsi->dev, "unknown error %u\n", error);
112 		break;
113 	}
114 
115 	return -EIO;
116 }
117 
118 static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
119 {
120 	u32 cci;
121 	int ret;
122 
123 	ret = ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
124 	if (ret)
125 		return ret;
126 
127 	ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
128 	if (ret)
129 		return ret;
130 
131 	if (cci & UCSI_CCI_BUSY)
132 		return -EBUSY;
133 
134 	if (!(cci & UCSI_CCI_COMMAND_COMPLETE))
135 		return -EIO;
136 
137 	if (cci & UCSI_CCI_NOT_SUPPORTED)
138 		return -EOPNOTSUPP;
139 
140 	if (cci & UCSI_CCI_ERROR) {
141 		if (cmd == UCSI_GET_ERROR_STATUS)
142 			return -EIO;
143 		return ucsi_read_error(ucsi);
144 	}
145 
146 	return UCSI_CCI_LENGTH(cci);
147 }
148 
149 int ucsi_send_command(struct ucsi *ucsi, u64 command,
150 		      void *data, size_t size)
151 {
152 	u8 length;
153 	int ret;
154 
155 	mutex_lock(&ucsi->ppm_lock);
156 
157 	ret = ucsi_exec_command(ucsi, command);
158 	if (ret < 0)
159 		goto out;
160 
161 	length = ret;
162 
163 	if (data) {
164 		ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, data, size);
165 		if (ret)
166 			goto out;
167 	}
168 
169 	ret = ucsi_acknowledge_command(ucsi);
170 	if (ret)
171 		goto out;
172 
173 	ret = length;
174 out:
175 	mutex_unlock(&ucsi->ppm_lock);
176 	return ret;
177 }
178 EXPORT_SYMBOL_GPL(ucsi_send_command);
179 
180 int ucsi_resume(struct ucsi *ucsi)
181 {
182 	u64 command;
183 
184 	/* Restore UCSI notification enable mask after system resume */
185 	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
186 
187 	return ucsi_send_command(ucsi, command, NULL, 0);
188 }
189 EXPORT_SYMBOL_GPL(ucsi_resume);
190 /* -------------------------------------------------------------------------- */
191 
192 void ucsi_altmode_update_active(struct ucsi_connector *con)
193 {
194 	const struct typec_altmode *altmode = NULL;
195 	u64 command;
196 	int ret;
197 	u8 cur;
198 	int i;
199 
200 	command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
201 	ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur));
202 	if (ret < 0) {
203 		if (con->ucsi->version > 0x0100) {
204 			dev_err(con->ucsi->dev,
205 				"GET_CURRENT_CAM command failed\n");
206 			return;
207 		}
208 		cur = 0xff;
209 	}
210 
211 	if (cur < UCSI_MAX_ALTMODES)
212 		altmode = typec_altmode_get_partner(con->port_altmode[cur]);
213 
214 	for (i = 0; con->partner_altmode[i]; i++)
215 		typec_altmode_update_active(con->partner_altmode[i],
216 					    con->partner_altmode[i] == altmode);
217 }
218 
219 static int ucsi_altmode_next_mode(struct typec_altmode **alt, u16 svid)
220 {
221 	u8 mode = 1;
222 	int i;
223 
224 	for (i = 0; alt[i]; i++) {
225 		if (i > MODE_DISCOVERY_MAX)
226 			return -ERANGE;
227 
228 		if (alt[i]->svid == svid)
229 			mode++;
230 	}
231 
232 	return mode;
233 }
234 
235 static int ucsi_next_altmode(struct typec_altmode **alt)
236 {
237 	int i = 0;
238 
239 	for (i = 0; i < UCSI_MAX_ALTMODES; i++)
240 		if (!alt[i])
241 			return i;
242 
243 	return -ENOENT;
244 }
245 
246 static int ucsi_register_altmode(struct ucsi_connector *con,
247 				 struct typec_altmode_desc *desc,
248 				 u8 recipient)
249 {
250 	struct typec_altmode *alt;
251 	bool override;
252 	int ret;
253 	int i;
254 
255 	override = !!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE);
256 
257 	switch (recipient) {
258 	case UCSI_RECIPIENT_CON:
259 		i = ucsi_next_altmode(con->port_altmode);
260 		if (i < 0) {
261 			ret = i;
262 			goto err;
263 		}
264 
265 		ret = ucsi_altmode_next_mode(con->port_altmode, desc->svid);
266 		if (ret < 0)
267 			return ret;
268 
269 		desc->mode = ret;
270 
271 		switch (desc->svid) {
272 		case USB_TYPEC_DP_SID:
273 			alt = ucsi_register_displayport(con, override, i, desc);
274 			break;
275 		case USB_TYPEC_NVIDIA_VLINK_SID:
276 			if (desc->vdo == USB_TYPEC_NVIDIA_VLINK_DBG_VDO)
277 				alt = typec_port_register_altmode(con->port,
278 								  desc);
279 			else
280 				alt = ucsi_register_displayport(con, override,
281 								i, desc);
282 			break;
283 		default:
284 			alt = typec_port_register_altmode(con->port, desc);
285 			break;
286 		}
287 
288 		if (IS_ERR(alt)) {
289 			ret = PTR_ERR(alt);
290 			goto err;
291 		}
292 
293 		con->port_altmode[i] = alt;
294 		break;
295 	case UCSI_RECIPIENT_SOP:
296 		i = ucsi_next_altmode(con->partner_altmode);
297 		if (i < 0) {
298 			ret = i;
299 			goto err;
300 		}
301 
302 		ret = ucsi_altmode_next_mode(con->partner_altmode, desc->svid);
303 		if (ret < 0)
304 			return ret;
305 
306 		desc->mode = ret;
307 
308 		alt = typec_partner_register_altmode(con->partner, desc);
309 		if (IS_ERR(alt)) {
310 			ret = PTR_ERR(alt);
311 			goto err;
312 		}
313 
314 		con->partner_altmode[i] = alt;
315 		break;
316 	default:
317 		return -EINVAL;
318 	}
319 
320 	trace_ucsi_register_altmode(recipient, alt);
321 
322 	return 0;
323 
324 err:
325 	dev_err(con->ucsi->dev, "failed to registers svid 0x%04x mode %d\n",
326 		desc->svid, desc->mode);
327 
328 	return ret;
329 }
330 
331 static int
332 ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
333 {
334 	int max_altmodes = UCSI_MAX_ALTMODES;
335 	struct typec_altmode_desc desc;
336 	struct ucsi_altmode alt;
337 	struct ucsi_altmode orig[UCSI_MAX_ALTMODES];
338 	struct ucsi_altmode updated[UCSI_MAX_ALTMODES];
339 	struct ucsi *ucsi = con->ucsi;
340 	bool multi_dp = false;
341 	u64 command;
342 	int ret;
343 	int len;
344 	int i;
345 	int k = 0;
346 
347 	if (recipient == UCSI_RECIPIENT_CON)
348 		max_altmodes = con->ucsi->cap.num_alt_modes;
349 
350 	memset(orig, 0, sizeof(orig));
351 	memset(updated, 0, sizeof(updated));
352 
353 	/* First get all the alternate modes */
354 	for (i = 0; i < max_altmodes; i++) {
355 		memset(&alt, 0, sizeof(alt));
356 		command = UCSI_GET_ALTERNATE_MODES;
357 		command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
358 		command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
359 		command |= UCSI_GET_ALTMODE_OFFSET(i);
360 		len = ucsi_send_command(con->ucsi, command, &alt, sizeof(alt));
361 		/*
362 		 * We are collecting all altmodes first and then registering.
363 		 * Some type-C device will return zero length data beyond last
364 		 * alternate modes. We should not return if length is zero.
365 		 */
366 		if (len < 0)
367 			return len;
368 
369 		/* We got all altmodes, now break out and register them */
370 		if (!len || !alt.svid)
371 			break;
372 
373 		orig[k].mid = alt.mid;
374 		orig[k].svid = alt.svid;
375 		k++;
376 	}
377 	/*
378 	 * Update the original altmode table as some ppms may report
379 	 * multiple DP altmodes.
380 	 */
381 	if (recipient == UCSI_RECIPIENT_CON)
382 		multi_dp = ucsi->ops->update_altmodes(ucsi, orig, updated);
383 
384 	/* now register altmodes */
385 	for (i = 0; i < max_altmodes; i++) {
386 		memset(&desc, 0, sizeof(desc));
387 		if (multi_dp && recipient == UCSI_RECIPIENT_CON) {
388 			desc.svid = updated[i].svid;
389 			desc.vdo = updated[i].mid;
390 		} else {
391 			desc.svid = orig[i].svid;
392 			desc.vdo = orig[i].mid;
393 		}
394 		desc.roles = TYPEC_PORT_DRD;
395 
396 		if (!desc.svid)
397 			return 0;
398 
399 		ret = ucsi_register_altmode(con, &desc, recipient);
400 		if (ret)
401 			return ret;
402 	}
403 
404 	return 0;
405 }
406 
407 static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
408 {
409 	int max_altmodes = UCSI_MAX_ALTMODES;
410 	struct typec_altmode_desc desc;
411 	struct ucsi_altmode alt[2];
412 	u64 command;
413 	int num;
414 	int ret;
415 	int len;
416 	int j;
417 	int i;
418 
419 	if (!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_DETAILS))
420 		return 0;
421 
422 	if (recipient == UCSI_RECIPIENT_SOP && con->partner_altmode[0])
423 		return 0;
424 
425 	if (con->ucsi->ops->update_altmodes)
426 		return ucsi_register_altmodes_nvidia(con, recipient);
427 
428 	if (recipient == UCSI_RECIPIENT_CON)
429 		max_altmodes = con->ucsi->cap.num_alt_modes;
430 
431 	for (i = 0; i < max_altmodes;) {
432 		memset(alt, 0, sizeof(alt));
433 		command = UCSI_GET_ALTERNATE_MODES;
434 		command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
435 		command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
436 		command |= UCSI_GET_ALTMODE_OFFSET(i);
437 		len = ucsi_send_command(con->ucsi, command, alt, sizeof(alt));
438 		if (len <= 0)
439 			return len;
440 
441 		/*
442 		 * This code is requesting one alt mode at a time, but some PPMs
443 		 * may still return two. If that happens both alt modes need be
444 		 * registered and the offset for the next alt mode has to be
445 		 * incremented.
446 		 */
447 		num = len / sizeof(alt[0]);
448 		i += num;
449 
450 		for (j = 0; j < num; j++) {
451 			if (!alt[j].svid)
452 				return 0;
453 
454 			memset(&desc, 0, sizeof(desc));
455 			desc.vdo = alt[j].mid;
456 			desc.svid = alt[j].svid;
457 			desc.roles = TYPEC_PORT_DRD;
458 
459 			ret = ucsi_register_altmode(con, &desc, recipient);
460 			if (ret)
461 				return ret;
462 		}
463 	}
464 
465 	return 0;
466 }
467 
468 static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient)
469 {
470 	const struct typec_altmode *pdev;
471 	struct typec_altmode **adev;
472 	int i = 0;
473 
474 	switch (recipient) {
475 	case UCSI_RECIPIENT_CON:
476 		adev = con->port_altmode;
477 		break;
478 	case UCSI_RECIPIENT_SOP:
479 		adev = con->partner_altmode;
480 		break;
481 	default:
482 		return;
483 	}
484 
485 	while (adev[i]) {
486 		if (recipient == UCSI_RECIPIENT_SOP &&
487 		    (adev[i]->svid == USB_TYPEC_DP_SID ||
488 			(adev[i]->svid == USB_TYPEC_NVIDIA_VLINK_SID &&
489 			adev[i]->vdo != USB_TYPEC_NVIDIA_VLINK_DBG_VDO))) {
490 			pdev = typec_altmode_get_partner(adev[i]);
491 			ucsi_displayport_remove_partner((void *)pdev);
492 		}
493 		typec_unregister_altmode(adev[i]);
494 		adev[i++] = NULL;
495 	}
496 }
497 
498 static void ucsi_get_pdos(struct ucsi_connector *con, int is_partner)
499 {
500 	struct ucsi *ucsi = con->ucsi;
501 	u64 command;
502 	int ret;
503 
504 	command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num);
505 	command |= UCSI_GET_PDOS_PARTNER_PDO(is_partner);
506 	command |= UCSI_GET_PDOS_NUM_PDOS(UCSI_MAX_PDOS - 1);
507 	command |= UCSI_GET_PDOS_SRC_PDOS;
508 	ret = ucsi_send_command(ucsi, command, con->src_pdos,
509 			       sizeof(con->src_pdos));
510 	if (ret < 0) {
511 		dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret);
512 		return;
513 	}
514 	con->num_pdos = ret / sizeof(u32); /* number of bytes to 32-bit PDOs */
515 	if (ret == 0)
516 		dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n");
517 }
518 
519 static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
520 {
521 	switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
522 	case UCSI_CONSTAT_PWR_OPMODE_PD:
523 		con->rdo = con->status.request_data_obj;
524 		typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD);
525 		ucsi_get_pdos(con, 1);
526 		break;
527 	case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5:
528 		con->rdo = 0;
529 		typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_1_5A);
530 		break;
531 	case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0:
532 		con->rdo = 0;
533 		typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_3_0A);
534 		break;
535 	default:
536 		con->rdo = 0;
537 		typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_USB);
538 		break;
539 	}
540 }
541 
542 static int ucsi_register_partner(struct ucsi_connector *con)
543 {
544 	u8 pwr_opmode = UCSI_CONSTAT_PWR_OPMODE(con->status.flags);
545 	struct typec_partner_desc desc;
546 	struct typec_partner *partner;
547 
548 	if (con->partner)
549 		return 0;
550 
551 	memset(&desc, 0, sizeof(desc));
552 
553 	switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
554 	case UCSI_CONSTAT_PARTNER_TYPE_DEBUG:
555 		desc.accessory = TYPEC_ACCESSORY_DEBUG;
556 		break;
557 	case UCSI_CONSTAT_PARTNER_TYPE_AUDIO:
558 		desc.accessory = TYPEC_ACCESSORY_AUDIO;
559 		break;
560 	default:
561 		break;
562 	}
563 
564 	desc.usb_pd = pwr_opmode == UCSI_CONSTAT_PWR_OPMODE_PD;
565 
566 	partner = typec_register_partner(con->port, &desc);
567 	if (IS_ERR(partner)) {
568 		dev_err(con->ucsi->dev,
569 			"con%d: failed to register partner (%ld)\n", con->num,
570 			PTR_ERR(partner));
571 		return PTR_ERR(partner);
572 	}
573 
574 	con->partner = partner;
575 
576 	return 0;
577 }
578 
579 static void ucsi_unregister_partner(struct ucsi_connector *con)
580 {
581 	if (!con->partner)
582 		return;
583 
584 	ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
585 	typec_unregister_partner(con->partner);
586 	con->partner = NULL;
587 }
588 
589 static void ucsi_partner_change(struct ucsi_connector *con)
590 {
591 	int ret;
592 
593 	if (!con->partner)
594 		return;
595 
596 	switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
597 	case UCSI_CONSTAT_PARTNER_TYPE_UFP:
598 	case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
599 	case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
600 		typec_set_data_role(con->port, TYPEC_HOST);
601 		break;
602 	case UCSI_CONSTAT_PARTNER_TYPE_DFP:
603 		typec_set_data_role(con->port, TYPEC_DEVICE);
604 		break;
605 	default:
606 		break;
607 	}
608 
609 	/* Complete pending data role swap */
610 	if (!completion_done(&con->complete))
611 		complete(&con->complete);
612 
613 	/* Can't rely on Partner Flags field. Always checking the alt modes. */
614 	ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
615 	if (ret)
616 		dev_err(con->ucsi->dev,
617 			"con%d: failed to register partner alternate modes\n",
618 			con->num);
619 	else
620 		ucsi_altmode_update_active(con);
621 }
622 
623 static void ucsi_handle_connector_change(struct work_struct *work)
624 {
625 	struct ucsi_connector *con = container_of(work, struct ucsi_connector,
626 						  work);
627 	struct ucsi *ucsi = con->ucsi;
628 	struct ucsi_connector_status pre_ack_status;
629 	struct ucsi_connector_status post_ack_status;
630 	enum typec_role role;
631 	u16 inferred_changes;
632 	u16 changed_flags;
633 	u64 command;
634 	int ret;
635 
636 	mutex_lock(&con->lock);
637 
638 	/*
639 	 * Some/many PPMs have an issue where all fields in the change bitfield
640 	 * are cleared when an ACK is send. This will causes any change
641 	 * between GET_CONNECTOR_STATUS and ACK to be lost.
642 	 *
643 	 * We work around this by re-fetching the connector status afterwards.
644 	 * We then infer any changes that we see have happened but that may not
645 	 * be represented in the change bitfield.
646 	 *
647 	 * Also, even though we don't need to know the currently supported alt
648 	 * modes, we run the GET_CAM_SUPPORTED command to ensure the PPM does
649 	 * not get stuck in case it assumes we do.
650 	 * Always do this, rather than relying on UCSI_CONSTAT_CAM_CHANGE to be
651 	 * set in the change bitfield.
652 	 *
653 	 * We end up with the following actions:
654 	 *  1. UCSI_GET_CONNECTOR_STATUS, store result, update unprocessed_changes
655 	 *  2. UCSI_GET_CAM_SUPPORTED, discard result
656 	 *  3. ACK connector change
657 	 *  4. UCSI_GET_CONNECTOR_STATUS, store result
658 	 *  5. Infere lost changes by comparing UCSI_GET_CONNECTOR_STATUS results
659 	 *  6. If PPM reported a new change, then restart in order to ACK
660 	 *  7. Process everything as usual.
661 	 *
662 	 * We may end up seeing a change twice, but we can only miss extremely
663 	 * short transitional changes.
664 	 */
665 
666 	/* 1. First UCSI_GET_CONNECTOR_STATUS */
667 	command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
668 	ret = ucsi_send_command(ucsi, command, &pre_ack_status,
669 				sizeof(pre_ack_status));
670 	if (ret < 0) {
671 		dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n",
672 			__func__, ret);
673 		goto out_unlock;
674 	}
675 	con->unprocessed_changes |= pre_ack_status.change;
676 
677 	/* 2. Run UCSI_GET_CAM_SUPPORTED and discard the result. */
678 	command = UCSI_GET_CAM_SUPPORTED;
679 	command |= UCSI_CONNECTOR_NUMBER(con->num);
680 	ucsi_send_command(con->ucsi, command, NULL, 0);
681 
682 	/* 3. ACK connector change */
683 	clear_bit(EVENT_PENDING, &ucsi->flags);
684 	ret = ucsi_acknowledge_connector_change(ucsi);
685 	if (ret) {
686 		dev_err(ucsi->dev, "%s: ACK failed (%d)", __func__, ret);
687 		goto out_unlock;
688 	}
689 
690 	/* 4. Second UCSI_GET_CONNECTOR_STATUS */
691 	command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
692 	ret = ucsi_send_command(ucsi, command, &post_ack_status,
693 				sizeof(post_ack_status));
694 	if (ret < 0) {
695 		dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n",
696 			__func__, ret);
697 		goto out_unlock;
698 	}
699 
700 	/* 5. Inferre any missing changes */
701 	changed_flags = pre_ack_status.flags ^ post_ack_status.flags;
702 	inferred_changes = 0;
703 	if (UCSI_CONSTAT_PWR_OPMODE(changed_flags) != 0)
704 		inferred_changes |= UCSI_CONSTAT_POWER_OPMODE_CHANGE;
705 
706 	if (changed_flags & UCSI_CONSTAT_CONNECTED)
707 		inferred_changes |= UCSI_CONSTAT_CONNECT_CHANGE;
708 
709 	if (changed_flags & UCSI_CONSTAT_PWR_DIR)
710 		inferred_changes |= UCSI_CONSTAT_POWER_DIR_CHANGE;
711 
712 	if (UCSI_CONSTAT_PARTNER_FLAGS(changed_flags) != 0)
713 		inferred_changes |= UCSI_CONSTAT_PARTNER_CHANGE;
714 
715 	if (UCSI_CONSTAT_PARTNER_TYPE(changed_flags) != 0)
716 		inferred_changes |= UCSI_CONSTAT_PARTNER_CHANGE;
717 
718 	/* Mask out anything that was correctly notified in the later call. */
719 	inferred_changes &= ~post_ack_status.change;
720 	if (inferred_changes)
721 		dev_dbg(ucsi->dev, "%s: Inferred changes that would have been lost: 0x%04x\n",
722 			__func__, inferred_changes);
723 
724 	con->unprocessed_changes |= inferred_changes;
725 
726 	/* 6. If PPM reported a new change, then restart in order to ACK */
727 	if (post_ack_status.change)
728 		goto out_unlock;
729 
730 	/* 7. Continue as if nothing happened */
731 	con->status = post_ack_status;
732 	con->status.change = con->unprocessed_changes;
733 	con->unprocessed_changes = 0;
734 
735 	role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
736 
737 	if (con->status.change & UCSI_CONSTAT_POWER_OPMODE_CHANGE ||
738 	    con->status.change & UCSI_CONSTAT_POWER_LEVEL_CHANGE) {
739 		ucsi_pwr_opmode_change(con);
740 		ucsi_port_psy_changed(con);
741 	}
742 
743 	if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) {
744 		typec_set_pwr_role(con->port, role);
745 
746 		/* Complete pending power role swap */
747 		if (!completion_done(&con->complete))
748 			complete(&con->complete);
749 	}
750 
751 	if (con->status.change & UCSI_CONSTAT_CONNECT_CHANGE) {
752 		typec_set_pwr_role(con->port, role);
753 
754 		switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
755 		case UCSI_CONSTAT_PARTNER_TYPE_UFP:
756 		case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
757 		case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
758 			typec_set_data_role(con->port, TYPEC_HOST);
759 			break;
760 		case UCSI_CONSTAT_PARTNER_TYPE_DFP:
761 			typec_set_data_role(con->port, TYPEC_DEVICE);
762 			break;
763 		default:
764 			break;
765 		}
766 
767 		if (con->status.flags & UCSI_CONSTAT_CONNECTED)
768 			ucsi_register_partner(con);
769 		else
770 			ucsi_unregister_partner(con);
771 
772 		ucsi_port_psy_changed(con);
773 	}
774 
775 	if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE)
776 		ucsi_partner_change(con);
777 
778 	trace_ucsi_connector_change(con->num, &con->status);
779 
780 out_unlock:
781 	if (test_and_clear_bit(EVENT_PENDING, &ucsi->flags)) {
782 		schedule_work(&con->work);
783 		mutex_unlock(&con->lock);
784 		return;
785 	}
786 
787 	clear_bit(EVENT_PROCESSING, &ucsi->flags);
788 	mutex_unlock(&con->lock);
789 }
790 
791 /**
792  * ucsi_connector_change - Process Connector Change Event
793  * @ucsi: UCSI Interface
794  * @num: Connector number
795  */
796 void ucsi_connector_change(struct ucsi *ucsi, u8 num)
797 {
798 	struct ucsi_connector *con = &ucsi->connector[num - 1];
799 
800 	if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) {
801 		dev_dbg(ucsi->dev, "Bogus connector change event\n");
802 		return;
803 	}
804 
805 	set_bit(EVENT_PENDING, &ucsi->flags);
806 
807 	if (!test_and_set_bit(EVENT_PROCESSING, &ucsi->flags))
808 		schedule_work(&con->work);
809 }
810 EXPORT_SYMBOL_GPL(ucsi_connector_change);
811 
812 /* -------------------------------------------------------------------------- */
813 
814 static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
815 {
816 	u64 command;
817 
818 	command = UCSI_CONNECTOR_RESET | UCSI_CONNECTOR_NUMBER(con->num);
819 	command |= hard ? UCSI_CONNECTOR_RESET_HARD : 0;
820 
821 	return ucsi_send_command(con->ucsi, command, NULL, 0);
822 }
823 
824 static int ucsi_reset_ppm(struct ucsi *ucsi)
825 {
826 	u64 command = UCSI_PPM_RESET;
827 	unsigned long tmo;
828 	u32 cci;
829 	int ret;
830 
831 	mutex_lock(&ucsi->ppm_lock);
832 
833 	ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,
834 				     sizeof(command));
835 	if (ret < 0)
836 		goto out;
837 
838 	tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS);
839 
840 	do {
841 		if (time_is_before_jiffies(tmo)) {
842 			ret = -ETIMEDOUT;
843 			goto out;
844 		}
845 
846 		ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
847 		if (ret)
848 			goto out;
849 
850 		/* If the PPM is still doing something else, reset it again. */
851 		if (cci & ~UCSI_CCI_RESET_COMPLETE) {
852 			ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL,
853 						     &command,
854 						     sizeof(command));
855 			if (ret < 0)
856 				goto out;
857 		}
858 
859 		msleep(20);
860 	} while (!(cci & UCSI_CCI_RESET_COMPLETE));
861 
862 out:
863 	mutex_unlock(&ucsi->ppm_lock);
864 	return ret;
865 }
866 
867 static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
868 {
869 	int ret;
870 
871 	ret = ucsi_send_command(con->ucsi, command, NULL, 0);
872 	if (ret == -ETIMEDOUT) {
873 		u64 c;
874 
875 		/* PPM most likely stopped responding. Resetting everything. */
876 		ucsi_reset_ppm(con->ucsi);
877 
878 		c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
879 		ucsi_send_command(con->ucsi, c, NULL, 0);
880 
881 		ucsi_reset_connector(con, true);
882 	}
883 
884 	return ret;
885 }
886 
887 static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
888 {
889 	struct ucsi_connector *con = typec_get_drvdata(port);
890 	u8 partner_type;
891 	u64 command;
892 	int ret = 0;
893 
894 	mutex_lock(&con->lock);
895 
896 	if (!con->partner) {
897 		ret = -ENOTCONN;
898 		goto out_unlock;
899 	}
900 
901 	partner_type = UCSI_CONSTAT_PARTNER_TYPE(con->status.flags);
902 	if ((partner_type == UCSI_CONSTAT_PARTNER_TYPE_DFP &&
903 	     role == TYPEC_DEVICE) ||
904 	    (partner_type == UCSI_CONSTAT_PARTNER_TYPE_UFP &&
905 	     role == TYPEC_HOST))
906 		goto out_unlock;
907 
908 	command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num);
909 	command |= UCSI_SET_UOR_ROLE(role);
910 	command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS;
911 	ret = ucsi_role_cmd(con, command);
912 	if (ret < 0)
913 		goto out_unlock;
914 
915 	if (!wait_for_completion_timeout(&con->complete,
916 					msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS)))
917 		ret = -ETIMEDOUT;
918 
919 out_unlock:
920 	mutex_unlock(&con->lock);
921 
922 	return ret < 0 ? ret : 0;
923 }
924 
925 static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
926 {
927 	struct ucsi_connector *con = typec_get_drvdata(port);
928 	enum typec_role cur_role;
929 	u64 command;
930 	int ret = 0;
931 
932 	mutex_lock(&con->lock);
933 
934 	if (!con->partner) {
935 		ret = -ENOTCONN;
936 		goto out_unlock;
937 	}
938 
939 	cur_role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
940 
941 	if (cur_role == role)
942 		goto out_unlock;
943 
944 	command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num);
945 	command |= UCSI_SET_PDR_ROLE(role);
946 	command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS;
947 	ret = ucsi_role_cmd(con, command);
948 	if (ret < 0)
949 		goto out_unlock;
950 
951 	if (!wait_for_completion_timeout(&con->complete,
952 				msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) {
953 		ret = -ETIMEDOUT;
954 		goto out_unlock;
955 	}
956 
957 	/* Something has gone wrong while swapping the role */
958 	if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) !=
959 	    UCSI_CONSTAT_PWR_OPMODE_PD) {
960 		ucsi_reset_connector(con, true);
961 		ret = -EPROTO;
962 	}
963 
964 out_unlock:
965 	mutex_unlock(&con->lock);
966 
967 	return ret;
968 }
969 
970 static const struct typec_operations ucsi_ops = {
971 	.dr_set = ucsi_dr_swap,
972 	.pr_set = ucsi_pr_swap
973 };
974 
975 static struct fwnode_handle *ucsi_find_fwnode(struct ucsi_connector *con)
976 {
977 	struct fwnode_handle *fwnode;
978 	int i = 1;
979 
980 	device_for_each_child_node(con->ucsi->dev, fwnode)
981 		if (i++ == con->num)
982 			return fwnode;
983 	return NULL;
984 }
985 
986 static int ucsi_register_port(struct ucsi *ucsi, int index)
987 {
988 	struct ucsi_connector *con = &ucsi->connector[index];
989 	struct typec_capability *cap = &con->typec_cap;
990 	enum typec_accessory *accessory = cap->accessory;
991 	u64 command;
992 	int ret;
993 
994 	INIT_WORK(&con->work, ucsi_handle_connector_change);
995 	init_completion(&con->complete);
996 	mutex_init(&con->lock);
997 	con->num = index + 1;
998 	con->ucsi = ucsi;
999 
1000 	/* Delay other interactions with the con until registration is complete */
1001 	mutex_lock(&con->lock);
1002 
1003 	/* Get connector capability */
1004 	command = UCSI_GET_CONNECTOR_CAPABILITY;
1005 	command |= UCSI_CONNECTOR_NUMBER(con->num);
1006 	ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap));
1007 	if (ret < 0)
1008 		goto out;
1009 
1010 	if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP)
1011 		cap->data = TYPEC_PORT_DRD;
1012 	else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DFP)
1013 		cap->data = TYPEC_PORT_DFP;
1014 	else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_UFP)
1015 		cap->data = TYPEC_PORT_UFP;
1016 
1017 	if ((con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER) &&
1018 	    (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER))
1019 		cap->type = TYPEC_PORT_DRP;
1020 	else if (con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER)
1021 		cap->type = TYPEC_PORT_SRC;
1022 	else if (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER)
1023 		cap->type = TYPEC_PORT_SNK;
1024 
1025 	cap->revision = ucsi->cap.typec_version;
1026 	cap->pd_revision = ucsi->cap.pd_version;
1027 	cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
1028 
1029 	if (con->cap.op_mode & UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY)
1030 		*accessory++ = TYPEC_ACCESSORY_AUDIO;
1031 	if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY)
1032 		*accessory = TYPEC_ACCESSORY_DEBUG;
1033 
1034 	cap->fwnode = ucsi_find_fwnode(con);
1035 	cap->driver_data = con;
1036 	cap->ops = &ucsi_ops;
1037 
1038 	ret = ucsi_register_port_psy(con);
1039 	if (ret)
1040 		goto out;
1041 
1042 	/* Register the connector */
1043 	con->port = typec_register_port(ucsi->dev, cap);
1044 	if (IS_ERR(con->port)) {
1045 		ret = PTR_ERR(con->port);
1046 		goto out;
1047 	}
1048 
1049 	/* Alternate modes */
1050 	ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_CON);
1051 	if (ret) {
1052 		dev_err(ucsi->dev, "con%d: failed to register alt modes\n",
1053 			con->num);
1054 		goto out;
1055 	}
1056 
1057 	/* Get the status */
1058 	command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
1059 	ret = ucsi_send_command(ucsi, command, &con->status, sizeof(con->status));
1060 	if (ret < 0) {
1061 		dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
1062 		ret = 0;
1063 		goto out;
1064 	}
1065 	ret = 0; /* ucsi_send_command() returns length on success */
1066 
1067 	switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
1068 	case UCSI_CONSTAT_PARTNER_TYPE_UFP:
1069 	case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
1070 	case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
1071 		typec_set_data_role(con->port, TYPEC_HOST);
1072 		break;
1073 	case UCSI_CONSTAT_PARTNER_TYPE_DFP:
1074 		typec_set_data_role(con->port, TYPEC_DEVICE);
1075 		break;
1076 	default:
1077 		break;
1078 	}
1079 
1080 	/* Check if there is already something connected */
1081 	if (con->status.flags & UCSI_CONSTAT_CONNECTED) {
1082 		typec_set_pwr_role(con->port,
1083 				  !!(con->status.flags & UCSI_CONSTAT_PWR_DIR));
1084 		ucsi_pwr_opmode_change(con);
1085 		ucsi_register_partner(con);
1086 		ucsi_port_psy_changed(con);
1087 	}
1088 
1089 	if (con->partner) {
1090 		ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
1091 		if (ret) {
1092 			dev_err(ucsi->dev,
1093 				"con%d: failed to register alternate modes\n",
1094 				con->num);
1095 			ret = 0;
1096 		} else {
1097 			ucsi_altmode_update_active(con);
1098 		}
1099 	}
1100 
1101 	trace_ucsi_register_port(con->num, &con->status);
1102 
1103 out:
1104 	mutex_unlock(&con->lock);
1105 	return ret;
1106 }
1107 
1108 /**
1109  * ucsi_init - Initialize UCSI interface
1110  * @ucsi: UCSI to be initialized
1111  *
1112  * Registers all ports @ucsi has and enables all notification events.
1113  */
1114 static int ucsi_init(struct ucsi *ucsi)
1115 {
1116 	struct ucsi_connector *con;
1117 	u64 command;
1118 	int ret;
1119 	int i;
1120 
1121 	/* Reset the PPM */
1122 	ret = ucsi_reset_ppm(ucsi);
1123 	if (ret) {
1124 		dev_err(ucsi->dev, "failed to reset PPM!\n");
1125 		goto err;
1126 	}
1127 
1128 	/* Enable basic notifications */
1129 	ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
1130 	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
1131 	ret = ucsi_send_command(ucsi, command, NULL, 0);
1132 	if (ret < 0)
1133 		goto err_reset;
1134 
1135 	/* Get PPM capabilities */
1136 	command = UCSI_GET_CAPABILITY;
1137 	ret = ucsi_send_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap));
1138 	if (ret < 0)
1139 		goto err_reset;
1140 
1141 	if (!ucsi->cap.num_connectors) {
1142 		ret = -ENODEV;
1143 		goto err_reset;
1144 	}
1145 
1146 	/* Allocate the connectors. Released in ucsi_unregister_ppm() */
1147 	ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1,
1148 				  sizeof(*ucsi->connector), GFP_KERNEL);
1149 	if (!ucsi->connector) {
1150 		ret = -ENOMEM;
1151 		goto err_reset;
1152 	}
1153 
1154 	/* Register all connectors */
1155 	for (i = 0; i < ucsi->cap.num_connectors; i++) {
1156 		ret = ucsi_register_port(ucsi, i);
1157 		if (ret)
1158 			goto err_unregister;
1159 	}
1160 
1161 	/* Enable all notifications */
1162 	ucsi->ntfy = UCSI_ENABLE_NTFY_ALL;
1163 	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
1164 	ret = ucsi_send_command(ucsi, command, NULL, 0);
1165 	if (ret < 0)
1166 		goto err_unregister;
1167 
1168 	return 0;
1169 
1170 err_unregister:
1171 	for (con = ucsi->connector; con->port; con++) {
1172 		ucsi_unregister_partner(con);
1173 		ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON);
1174 		ucsi_unregister_port_psy(con);
1175 		typec_unregister_port(con->port);
1176 		con->port = NULL;
1177 	}
1178 
1179 err_reset:
1180 	ucsi_reset_ppm(ucsi);
1181 err:
1182 	return ret;
1183 }
1184 
1185 static void ucsi_init_work(struct work_struct *work)
1186 {
1187 	struct ucsi *ucsi = container_of(work, struct ucsi, work);
1188 	int ret;
1189 
1190 	ret = ucsi_init(ucsi);
1191 	if (ret)
1192 		dev_err(ucsi->dev, "PPM init failed (%d)\n", ret);
1193 }
1194 
1195 /**
1196  * ucsi_get_drvdata - Return private driver data pointer
1197  * @ucsi: UCSI interface
1198  */
1199 void *ucsi_get_drvdata(struct ucsi *ucsi)
1200 {
1201 	return ucsi->driver_data;
1202 }
1203 EXPORT_SYMBOL_GPL(ucsi_get_drvdata);
1204 
1205 /**
1206  * ucsi_get_drvdata - Assign private driver data pointer
1207  * @ucsi: UCSI interface
1208  * @data: Private data pointer
1209  */
1210 void ucsi_set_drvdata(struct ucsi *ucsi, void *data)
1211 {
1212 	ucsi->driver_data = data;
1213 }
1214 EXPORT_SYMBOL_GPL(ucsi_set_drvdata);
1215 
1216 /**
1217  * ucsi_create - Allocate UCSI instance
1218  * @dev: Device interface to the PPM (Platform Policy Manager)
1219  * @ops: I/O routines
1220  */
1221 struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
1222 {
1223 	struct ucsi *ucsi;
1224 
1225 	if (!ops || !ops->read || !ops->sync_write || !ops->async_write)
1226 		return ERR_PTR(-EINVAL);
1227 
1228 	ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL);
1229 	if (!ucsi)
1230 		return ERR_PTR(-ENOMEM);
1231 
1232 	INIT_WORK(&ucsi->work, ucsi_init_work);
1233 	mutex_init(&ucsi->ppm_lock);
1234 	ucsi->dev = dev;
1235 	ucsi->ops = ops;
1236 
1237 	return ucsi;
1238 }
1239 EXPORT_SYMBOL_GPL(ucsi_create);
1240 
1241 /**
1242  * ucsi_destroy - Free UCSI instance
1243  * @ucsi: UCSI instance to be freed
1244  */
1245 void ucsi_destroy(struct ucsi *ucsi)
1246 {
1247 	kfree(ucsi);
1248 }
1249 EXPORT_SYMBOL_GPL(ucsi_destroy);
1250 
1251 /**
1252  * ucsi_register - Register UCSI interface
1253  * @ucsi: UCSI instance
1254  */
1255 int ucsi_register(struct ucsi *ucsi)
1256 {
1257 	int ret;
1258 
1259 	ret = ucsi->ops->read(ucsi, UCSI_VERSION, &ucsi->version,
1260 			      sizeof(ucsi->version));
1261 	if (ret)
1262 		return ret;
1263 
1264 	if (!ucsi->version)
1265 		return -ENODEV;
1266 
1267 	queue_work(system_long_wq, &ucsi->work);
1268 
1269 	return 0;
1270 }
1271 EXPORT_SYMBOL_GPL(ucsi_register);
1272 
1273 /**
1274  * ucsi_unregister - Unregister UCSI interface
1275  * @ucsi: UCSI interface to be unregistered
1276  *
1277  * Unregister UCSI interface that was created with ucsi_register().
1278  */
1279 void ucsi_unregister(struct ucsi *ucsi)
1280 {
1281 	u64 cmd = UCSI_SET_NOTIFICATION_ENABLE;
1282 	int i;
1283 
1284 	/* Make sure that we are not in the middle of driver initialization */
1285 	cancel_work_sync(&ucsi->work);
1286 
1287 	/* Disable notifications */
1288 	ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
1289 
1290 	for (i = 0; i < ucsi->cap.num_connectors; i++) {
1291 		cancel_work_sync(&ucsi->connector[i].work);
1292 		ucsi_unregister_partner(&ucsi->connector[i]);
1293 		ucsi_unregister_altmodes(&ucsi->connector[i],
1294 					 UCSI_RECIPIENT_CON);
1295 		ucsi_unregister_port_psy(&ucsi->connector[i]);
1296 		typec_unregister_port(ucsi->connector[i].port);
1297 	}
1298 
1299 	kfree(ucsi->connector);
1300 }
1301 EXPORT_SYMBOL_GPL(ucsi_unregister);
1302 
1303 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
1304 MODULE_LICENSE("GPL v2");
1305 MODULE_DESCRIPTION("USB Type-C Connector System Software Interface driver");
1306