MLK-16013-14: usb: typec: tcpci: handle fault event
authorLi Jun <jun.li@nxp.com>
Wed, 9 Jan 2019 05:07:25 +0000 (10:37 +0530)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
We need clear any fault alerts to make tcpci controller to recover
from fault.

Reviewed-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
drivers/usb/typec/tcpci.c
drivers/usb/typec/tcpci.h

index c3e82c1..638ac2a 100644 (file)
@@ -393,6 +393,9 @@ static int tcpci_init(struct tcpc_dev *tcpc)
        if (ret < 0)
                return ret;
 
+       /* Clear fault condition */
+       regmap_write(tcpci->regmap, TCPC_FAULT_STATUS, 0x80);
+
        if (tcpci->controls_vbus)
                reg = TCPC_POWER_STATUS_VBUS_PRES;
        else
@@ -410,7 +413,7 @@ static int tcpci_init(struct tcpc_dev *tcpc)
        reg = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_FAILED |
                TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_RX_STATUS |
                TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS |
-               TCPC_ALERT_RX_BUF_OVF;
+               TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_FAULT;
        if (tcpci->controls_vbus)
                reg |= TCPC_ALERT_POWER_STATUS;
        tcpci->irq_mask = reg;
@@ -421,6 +424,7 @@ static int tcpci_init(struct tcpc_dev *tcpc)
 irqreturn_t tcpci_irq(struct tcpci *tcpci)
 {
        u16 status;
+       unsigned int reg;
 
        tcpci_read16(tcpci, TCPC_ALERT, &status);
 
@@ -436,8 +440,6 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
                tcpm_cc_change(tcpci->port);
 
        if (status & TCPC_ALERT_POWER_STATUS) {
-               unsigned int reg;
-
                regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &reg);
 
                /*
@@ -477,6 +479,13 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
                tcpci_write16(tcpci, TCPC_ALERT,
                              TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_RX_STATUS);
 
+       /* Clear the fault status anyway */
+       if (status & TCPC_ALERT_FAULT) {
+               regmap_read(tcpci->regmap, TCPC_FAULT_STATUS, &reg);
+               regmap_write(tcpci->regmap, TCPC_FAULT_STATUS,
+                               reg | TCPC_FAULT_STATUS_CLEAR);
+       }
+
        if (status & TCPC_ALERT_RX_HARD_RST)
                tcpm_pd_hard_reset(tcpci->port);
 
index 303ebde..8671e91 100644 (file)
@@ -32,6 +32,7 @@
 #define TCPC_ALERT_MASK                        0x12
 #define TCPC_POWER_STATUS_MASK         0x14
 #define TCPC_FAULT_STATUS_MASK         0x15
+#define TCPC_FAULT_STATUS_CLEAR                BIT(7)
 #define TCPC_CONFIG_STD_OUTPUT         0x18
 
 #define TCPC_TCPC_CTRL                 0x19