forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/usb/typec/tcpm/tcpci.c
....@@ -15,10 +15,24 @@
1515 #include <linux/usb/pd.h>
1616 #include <linux/usb/tcpm.h>
1717 #include <linux/usb/typec.h>
18
+#include <trace/hooks/typec.h>
1819
1920 #include "tcpci.h"
2021
21
-#define PD_RETRY_COUNT 3
22
+#define PD_RETRY_COUNT_DEFAULT 3
23
+#define PD_RETRY_COUNT_3_0_OR_HIGHER 2
24
+#define AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV 3500
25
+#define VSINKPD_MIN_IR_DROP_MV 750
26
+#define VSRC_NEW_MIN_PERCENT 95
27
+#define VSRC_VALID_MIN_MV 500
28
+#define VPPS_NEW_MIN_PERCENT 95
29
+#define VPPS_VALID_MIN_MV 100
30
+#define VSINKDISCONNECT_PD_MIN_PERCENT 90
31
+
32
+#define tcpc_presenting_rd(reg, cc) \
33
+ (!(TCPC_ROLE_CTRL_DRP & (reg)) && \
34
+ (((reg) & (TCPC_ROLE_CTRL_## cc ##_MASK << TCPC_ROLE_CTRL_## cc ##_SHIFT)) == \
35
+ (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_## cc ##_SHIFT)))
2236
2337 #define tcpc_presenting_cc1_rd(reg) \
2438 (!(TCPC_ROLE_CTRL_DRP & (reg)) && \
....@@ -47,6 +61,12 @@
4761 struct tcpci_data data;
4862 };
4963
64
+struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci)
65
+{
66
+ return tcpci->port;
67
+}
68
+EXPORT_SYMBOL_GPL(tcpci_get_tcpm_port);
69
+
5070 static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc)
5171 {
5272 return container_of(tcpc, struct tcpci, tcpc);
....@@ -65,8 +85,24 @@
6585 static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
6686 {
6787 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
88
+ bool vconn_pres;
89
+ enum typec_cc_polarity polarity = TYPEC_POLARITY_CC1;
6890 unsigned int reg;
6991 int ret;
92
+
93
+ ret = regmap_read(tcpci->regmap, TCPC_POWER_STATUS, &reg);
94
+ if (ret < 0)
95
+ return ret;
96
+
97
+ vconn_pres = !!(reg & TCPC_POWER_STATUS_VCONN_PRES);
98
+ if (vconn_pres) {
99
+ ret = regmap_read(tcpci->regmap, TCPC_TCPC_CTRL, &reg);
100
+ if (ret < 0)
101
+ return ret;
102
+
103
+ if (reg & TCPC_TCPC_CTRL_ORIENTATION)
104
+ polarity = TYPEC_POLARITY_CC2;
105
+ }
70106
71107 switch (cc) {
72108 case TYPEC_CC_RA:
....@@ -102,11 +138,48 @@
102138 break;
103139 }
104140
141
+ if (vconn_pres) {
142
+ if (polarity == TYPEC_POLARITY_CC2) {
143
+ reg &= ~(TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT);
144
+ reg |= (TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT);
145
+ } else {
146
+ reg &= ~(TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT);
147
+ reg |= (TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC2_SHIFT);
148
+ }
149
+ }
150
+
105151 ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
106152 if (ret < 0)
107153 return ret;
108154
109155 return 0;
156
+}
157
+
158
+static int tcpci_apply_rc(struct tcpc_dev *tcpc, enum typec_cc_status cc,
159
+ enum typec_cc_polarity polarity)
160
+{
161
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
162
+ unsigned int reg;
163
+ int ret;
164
+
165
+ ret = regmap_read(tcpci->regmap, TCPC_ROLE_CTRL, &reg);
166
+ if (ret < 0)
167
+ return ret;
168
+
169
+ /*
170
+ * APPLY_RC state is when ROLE_CONTROL.CC1 != ROLE_CONTROL.CC2 and vbus autodischarge on
171
+ * disconnect is disabled. Bail out when ROLE_CONTROL.CC1 != ROLE_CONTROL.CC2.
172
+ */
173
+ if (((reg & (TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT)) >>
174
+ TCPC_ROLE_CTRL_CC2_SHIFT) !=
175
+ ((reg & (TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT)) >>
176
+ TCPC_ROLE_CTRL_CC1_SHIFT))
177
+ return 0;
178
+
179
+ return regmap_update_bits(tcpci->regmap, TCPC_ROLE_CTRL, polarity == TYPEC_POLARITY_CC1 ?
180
+ TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT :
181
+ TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT,
182
+ TCPC_ROLE_CTRL_CC_OPEN);
110183 }
111184
112185 static int tcpci_start_toggling(struct tcpc_dev *tcpc,
....@@ -116,14 +189,17 @@
116189 int ret;
117190 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
118191 unsigned int reg = TCPC_ROLE_CTRL_DRP;
192
+ int override_toggling = 0;
119193
120194 if (port_type != TYPEC_PORT_DRP)
121195 return -EOPNOTSUPP;
122196
123197 /* Handle vendor drp toggling */
124198 if (tcpci->data->start_drp_toggling) {
199
+ trace_android_vh_typec_tcpci_override_toggling(tcpci, tcpci->data,
200
+ &override_toggling);
125201 ret = tcpci->data->start_drp_toggling(tcpci, tcpci->data, cc);
126
- if (ret < 0)
202
+ if (ret < 0 || override_toggling)
127203 return ret;
128204 }
129205
....@@ -166,7 +242,7 @@
166242 case 0x3:
167243 if (sink)
168244 return TYPEC_CC_RP_3_0;
169
- /* fall through */
245
+ fallthrough;
170246 case 0x0:
171247 default:
172248 return TYPEC_CC_OPEN;
....@@ -191,11 +267,11 @@
191267 *cc1 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC1_SHIFT) &
192268 TCPC_CC_STATUS_CC1_MASK,
193269 reg & TCPC_CC_STATUS_TERM ||
194
- tcpc_presenting_cc1_rd(role_control));
270
+ tcpc_presenting_rd(role_control, CC1));
195271 *cc2 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC2_SHIFT) &
196272 TCPC_CC_STATUS_CC2_MASK,
197273 reg & TCPC_CC_STATUS_TERM ||
198
- tcpc_presenting_cc2_rd(role_control));
274
+ tcpc_presenting_rd(role_control, CC2));
199275
200276 return 0;
201277 }
....@@ -260,6 +336,14 @@
260336 TCPC_TCPC_CTRL_ORIENTATION : 0);
261337 }
262338
339
+static void tcpci_set_partner_usb_comm_capable(struct tcpc_dev *tcpc, bool capable)
340
+{
341
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
342
+
343
+ if (tcpci->data->set_partner_usb_comm_capable)
344
+ tcpci->data->set_partner_usb_comm_capable(tcpci, tcpci->data, capable);
345
+}
346
+
263347 static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
264348 {
265349 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
....@@ -275,6 +359,92 @@
275359 return regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL,
276360 TCPC_POWER_CTRL_VCONN_ENABLE,
277361 enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
362
+}
363
+
364
+static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable)
365
+{
366
+ struct tcpci *tcpci = tcpc_to_tcpci(dev);
367
+ int ret;
368
+
369
+ ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_POWER_CTRL_AUTO_DISCHARGE,
370
+ enable ? TCPC_POWER_CTRL_AUTO_DISCHARGE : 0);
371
+ return ret;
372
+}
373
+
374
+static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_pwr_opmode mode,
375
+ bool pps_active, u32 requested_vbus_voltage_mv)
376
+{
377
+ struct tcpci *tcpci = tcpc_to_tcpci(dev);
378
+ unsigned int pwr_ctrl, threshold = 0;
379
+ int ret;
380
+
381
+ /*
382
+ * Indicates that vbus is going to go away due PR_SWAP, hard reset etc.
383
+ * Do not discharge vbus here.
384
+ */
385
+ if (requested_vbus_voltage_mv == 0)
386
+ goto write_thresh;
387
+
388
+ ret = regmap_read(tcpci->regmap, TCPC_POWER_CTRL, &pwr_ctrl);
389
+ if (ret < 0)
390
+ return ret;
391
+
392
+ if (pwr_ctrl & TCPC_FAST_ROLE_SWAP_EN) {
393
+ /* To prevent disconnect when the source is fast role swap is capable. */
394
+ threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV;
395
+ } else if (mode == TYPEC_PWR_MODE_PD) {
396
+ if (pps_active)
397
+ threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
398
+ VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) *
399
+ VSINKDISCONNECT_PD_MIN_PERCENT / 100;
400
+ else
401
+ threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
402
+ VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) *
403
+ VSINKDISCONNECT_PD_MIN_PERCENT / 100;
404
+ } else {
405
+ /* 3.5V for non-pd sink */
406
+ threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV;
407
+ }
408
+
409
+ threshold = threshold / TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB_MV;
410
+
411
+ if (threshold > TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX)
412
+ return -EINVAL;
413
+
414
+write_thresh:
415
+ return tcpci_write16(tcpci, TCPC_VBUS_SINK_DISCONNECT_THRESH, threshold);
416
+}
417
+
418
+static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable)
419
+{
420
+ struct tcpci *tcpci = tcpc_to_tcpci(dev);
421
+ int ret;
422
+
423
+ /* To prevent disconnect during FRS, set disconnect threshold to 3.5V */
424
+ ret = tcpci_write16(tcpci, TCPC_VBUS_SINK_DISCONNECT_THRESH, enable ? 0 : 0x8c);
425
+ if (ret < 0)
426
+ return ret;
427
+
428
+ ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_FAST_ROLE_SWAP_EN, enable ?
429
+ TCPC_FAST_ROLE_SWAP_EN : 0);
430
+
431
+ return ret;
432
+}
433
+
434
+static void tcpci_frs_sourcing_vbus(struct tcpc_dev *dev)
435
+{
436
+ struct tcpci *tcpci = tcpc_to_tcpci(dev);
437
+
438
+ if (tcpci->data->frs_sourcing_vbus)
439
+ tcpci->data->frs_sourcing_vbus(tcpci, tcpci->data);
440
+}
441
+
442
+static int tcpci_set_bist_data(struct tcpc_dev *tcpc, bool enable)
443
+{
444
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
445
+
446
+ return regmap_update_bits(tcpci->regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_BIST_TM,
447
+ enable ? TCPC_TCPC_CTRL_BIST_TM : 0);
278448 }
279449
280450 static int tcpci_set_roles(struct tcpc_dev *tcpc, bool attached,
....@@ -315,7 +485,11 @@
315485 {
316486 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
317487 unsigned int reg;
318
- int ret;
488
+ int ret, vbus, bypass = 0;
489
+
490
+ trace_android_rvh_typec_tcpci_get_vbus(tcpci, tcpci->data, &vbus, &bypass);
491
+ if (bypass)
492
+ return vbus;
319493
320494 ret = regmap_read(tcpci->regmap, TCPC_POWER_STATUS, &reg);
321495 if (ret < 0)
....@@ -324,10 +498,39 @@
324498 return !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
325499 }
326500
501
+static int tcpci_check_contaminant(struct tcpc_dev *tcpc)
502
+{
503
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
504
+ int ret = 0;
505
+
506
+ trace_android_rvh_typec_tcpci_chk_contaminant(tcpci, tcpci->data, &ret);
507
+ return ret;
508
+}
509
+
510
+static bool tcpci_is_vbus_vsafe0v(struct tcpc_dev *tcpc)
511
+{
512
+ struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
513
+ unsigned int reg;
514
+ int ret;
515
+
516
+ ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &reg);
517
+ if (ret < 0)
518
+ return false;
519
+
520
+ return !!(reg & TCPC_EXTENDED_STATUS_VSAFE0V);
521
+}
522
+
327523 static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
328524 {
329525 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
330526 int ret;
527
+
528
+ if (tcpci->data->set_vbus) {
529
+ ret = tcpci->data->set_vbus(tcpci, tcpci->data, source, sink);
530
+ /* Bypass when ret > 0 */
531
+ if (ret != 0)
532
+ return ret < 0 ? ret : 0;
533
+ }
331534
332535 /* Disable both source and sink first before enabling anything */
333536
....@@ -362,9 +565,8 @@
362565 return 0;
363566 }
364567
365
-static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
366
- enum tcpm_transmit_type type,
367
- const struct pd_message *msg)
568
+static int tcpci_pd_transmit(struct tcpc_dev *tcpc, enum tcpm_transmit_type type,
569
+ const struct pd_message *msg, unsigned int negotiated_rev)
368570 {
369571 struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
370572 u16 header = msg ? le16_to_cpu(msg->header) : 0;
....@@ -372,23 +574,49 @@
372574 int ret;
373575
374576 cnt = msg ? pd_header_cnt(header) * 4 : 0;
375
- ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
376
- if (ret < 0)
377
- return ret;
577
+ /**
578
+ * TCPCI spec forbids direct access of TCPC_TX_DATA.
579
+ * But, since some of the chipsets offer this capability,
580
+ * it's fair to support both.
581
+ */
582
+ if (tcpci->data->TX_BUF_BYTE_x_hidden) {
583
+ u8 buf[TCPC_TRANSMIT_BUFFER_MAX_LEN] = {0,};
584
+ u8 pos = 0;
378585
379
- ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
380
- if (ret < 0)
381
- return ret;
586
+ /* Payload + header + TCPC_TX_BYTE_CNT */
587
+ buf[pos++] = cnt + 2;
382588
383
- if (cnt > 0) {
384
- ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA,
385
- &msg->payload, cnt);
589
+ if (msg)
590
+ memcpy(&buf[pos], &msg->header, sizeof(msg->header));
591
+
592
+ pos += sizeof(header);
593
+
594
+ if (cnt > 0)
595
+ memcpy(&buf[pos], msg->payload, cnt);
596
+
597
+ pos += cnt;
598
+ ret = regmap_raw_write(tcpci->regmap, TCPC_TX_BYTE_CNT, buf, pos);
386599 if (ret < 0)
387600 return ret;
601
+ } else {
602
+ ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
603
+ if (ret < 0)
604
+ return ret;
605
+
606
+ ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
607
+ if (ret < 0)
608
+ return ret;
609
+
610
+ if (cnt > 0) {
611
+ ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA, &msg->payload, cnt);
612
+ if (ret < 0)
613
+ return ret;
614
+ }
388615 }
389616
390
- reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) |
391
- (type << TCPC_TRANSMIT_TYPE_SHIFT);
617
+ /* nRetryCount is 3 in PD2.0 spec where 2 in PD3.0 spec */
618
+ reg = ((negotiated_rev > PD_REV20 ? PD_RETRY_COUNT_3_0_OR_HIGHER : PD_RETRY_COUNT_DEFAULT)
619
+ << TCPC_TRANSMIT_RETRY_SHIFT) | (type << TCPC_TRANSMIT_TYPE_SHIFT);
392620 ret = regmap_write(tcpci->regmap, TCPC_TRANSMIT, reg);
393621 if (ret < 0)
394622 return ret;
....@@ -413,6 +641,10 @@
413641 }
414642 if (time_after(jiffies, timeout))
415643 return -ETIMEDOUT;
644
+
645
+ ret = tcpci_write16(tcpci, TCPC_FAULT_STATUS, TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT);
646
+ if (ret < 0)
647
+ return ret;
416648
417649 /* Handle vendor init */
418650 if (tcpci->data->init) {
....@@ -445,12 +677,22 @@
445677 TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS;
446678 if (tcpci->controls_vbus)
447679 reg |= TCPC_ALERT_POWER_STATUS;
680
+ /* Enable VSAFE0V status interrupt when detecting VSAFE0V is supported */
681
+ if (tcpci->data->vbus_vsafe0v) {
682
+ reg |= TCPC_ALERT_EXTENDED_STATUS;
683
+ ret = regmap_write(tcpci->regmap, TCPC_EXTENDED_STATUS_MASK,
684
+ TCPC_EXTENDED_STATUS_VSAFE0V);
685
+ if (ret < 0)
686
+ return ret;
687
+ }
448688 return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg);
449689 }
450690
451691 irqreturn_t tcpci_irq(struct tcpci *tcpci)
452692 {
453693 u16 status;
694
+ int ret;
695
+ unsigned int raw;
454696
455697 tcpci_read16(tcpci, TCPC_ALERT, &status);
456698
....@@ -466,15 +708,12 @@
466708 tcpm_cc_change(tcpci->port);
467709
468710 if (status & TCPC_ALERT_POWER_STATUS) {
469
- unsigned int reg;
470
-
471
- regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &reg);
472
-
711
+ regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &raw);
473712 /*
474713 * If power status mask has been reset, then the TCPC
475714 * has reset.
476715 */
477
- if (reg == 0xff)
716
+ if (raw == 0xff)
478717 tcpm_tcpc_reset(tcpci->port);
479718 else
480719 tcpm_vbus_change(tcpci->port);
....@@ -511,6 +750,12 @@
511750 tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
512751
513752 tcpm_pd_receive(tcpci->port, &msg);
753
+ }
754
+
755
+ if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) {
756
+ ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw);
757
+ if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V))
758
+ tcpm_vbus_change(tcpci->port);
514759 }
515760
516761 if (status & TCPC_ALERT_RX_HARD_RST)
....@@ -572,6 +817,7 @@
572817 tcpci->tcpc.get_vbus = tcpci_get_vbus;
573818 tcpci->tcpc.set_vbus = tcpci_set_vbus;
574819 tcpci->tcpc.set_cc = tcpci_set_cc;
820
+ tcpci->tcpc.apply_rc = tcpci_apply_rc;
575821 tcpci->tcpc.get_cc = tcpci_get_cc;
576822 tcpci->tcpc.set_polarity = tcpci_set_polarity;
577823 tcpci->tcpc.set_vconn = tcpci_set_vconn;
....@@ -580,14 +826,32 @@
580826 tcpci->tcpc.set_pd_rx = tcpci_set_pd_rx;
581827 tcpci->tcpc.set_roles = tcpci_set_roles;
582828 tcpci->tcpc.pd_transmit = tcpci_pd_transmit;
829
+ tcpci->tcpc.set_bist_data = tcpci_set_bist_data;
830
+ tcpci->tcpc.enable_frs = tcpci_enable_frs;
831
+ tcpci->tcpc.frs_sourcing_vbus = tcpci_frs_sourcing_vbus;
832
+ tcpci->tcpc.set_partner_usb_comm_capable = tcpci_set_partner_usb_comm_capable;
833
+ tcpci->tcpc.check_contaminant = tcpci_check_contaminant;
834
+
835
+ if (tcpci->data->auto_discharge_disconnect) {
836
+ tcpci->tcpc.enable_auto_vbus_discharge = tcpci_enable_auto_vbus_discharge;
837
+ tcpci->tcpc.set_auto_vbus_discharge_threshold =
838
+ tcpci_set_auto_vbus_discharge_threshold;
839
+ regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_POWER_CTRL_BLEED_DISCHARGE,
840
+ TCPC_POWER_CTRL_BLEED_DISCHARGE);
841
+ }
842
+
843
+ if (tcpci->data->vbus_vsafe0v)
844
+ tcpci->tcpc.is_vbus_vsafe0v = tcpci_is_vbus_vsafe0v;
583845
584846 err = tcpci_parse_config(tcpci);
585847 if (err < 0)
586848 return ERR_PTR(err);
587849
588850 tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
589
- if (IS_ERR(tcpci->port))
851
+ if (IS_ERR(tcpci->port)) {
852
+ fwnode_handle_put(tcpci->tcpc.fwnode);
590853 return ERR_CAST(tcpci->port);
854
+ }
591855
592856 return tcpci;
593857 }
....@@ -596,6 +860,7 @@
596860 void tcpci_unregister_port(struct tcpci *tcpci)
597861 {
598862 tcpm_unregister_port(tcpci->port);
863
+ fwnode_handle_put(tcpci->tcpc.fwnode);
599864 }
600865 EXPORT_SYMBOL_GPL(tcpci_unregister_port);
601866
....@@ -646,7 +911,7 @@
646911 /* Disable chip interrupts before unregistering port */
647912 err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
648913 if (err < 0)
649
- return err;
914
+ dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err));
650915
651916 tcpci_unregister_port(chip->tcpci);
652917