From 7cf052ec4db4e747449b5be7ac7847ad70da7c41 Mon Sep 17 00:00:00 2001 From: zain wang Date: Thu, 11 May 2017 15:46:25 +0800 Subject: [PATCH] mfd: fusb302: Don't mistake meaningful packets for Good_CRC If a partner port sends a packet at approximately the same time as we send a packet, we may end up with the initial packet followed by the GOOD_CRC reply in our HW FIFO. Don't automatically discard the first packet in the FIFO. Instead, discard the packet only if it's a GOOD_CRC packet. And, modify our get_message function to automatically discard GOOD_CRC in search of a meaningful packet. In addition, due to interrupt latency, we can't rely on receiving one interrupt per incoming packet. If our Rx FIFO is non-empty, assume that it contains at least one packet. Change-Id: Iaad80a4c55eea3e9e2791d81d7c5d28ce97bd2f5 Signed-off-by: zain wang --- drivers/mfd/fusb302.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/mfd/fusb302.c b/drivers/mfd/fusb302.c index aea504bbce32..e0c9468b8d20 100644 --- a/drivers/mfd/fusb302.c +++ b/drivers/mfd/fusb302.c @@ -50,6 +50,10 @@ #define PIN_MAP_E BIT(4) #define PIN_MAP_F BIT(5) +#define PACKET_IS_GOOD_CRC(header) \ + (PD_HEADER_TYPE(header) == CMT_GOODCRC && \ + PD_HEADER_CNT(header) == 0) + static u8 fusb30x_port_used; static struct fusb30x_chip *fusb30x_port_info[256]; @@ -339,11 +343,14 @@ static int tcpm_get_message(struct fusb30x_chip *chip) u8 buf[32]; int len; - regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, 3); - chip->rec_head = (buf[1] & 0xff) | ((buf[2] << 8) & 0xff00); + do { + regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, 3); + chip->rec_head = (buf[1] & 0xff) | ((buf[2] << 8) & 0xff00); - len = PD_HEADER_CNT(chip->rec_head) << 2; - regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, len + 4); + len = PD_HEADER_CNT(chip->rec_head) << 2; + regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, len + 4); + /* ignore good_crc message */ + } while (PACKET_IS_GOOD_CRC(chip->rec_head)); memcpy(chip->rec_load, buf, len); @@ -352,7 +359,7 @@ static int tcpm_get_message(struct fusb30x_chip *chip) static void fusb302_flush_rx_fifo(struct fusb30x_chip *chip) { - tcpm_get_message(chip); + regmap_write(chip->regmap, FUSB_REG_CONTROL1, CONTROL1_RX_FLUSH); } static int tcpm_get_cc(struct fusb30x_chip *chip, int *CC1, int *CC2) @@ -741,7 +748,6 @@ static void tcpc_alert(struct fusb30x_chip *chip, int *evt) if (interrupta & INTERRUPTA_TXSENT) { *evt |= EVENT_TX; - fusb302_flush_rx_fifo(chip); chip->tx_state = tx_success; } -- 2.34.1