Message ID | 20231207090738.15721-14-rdbabiera@google.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: typec: add SOP' support to the tcpm and alt mode drivers | expand |
Hi RD, kernel test robot noticed the following build errors: [auto build test ERROR on 5e4c8814a431d21bfaf20b464134f40f2f81e152] url: https://github.com/intel-lab-lkp/linux/commits/RD-Babiera/usb-typec-bus-provide-transmit-type-for-alternate-mode-drivers/20231207-171114 base: 5e4c8814a431d21bfaf20b464134f40f2f81e152 patch link: https://lore.kernel.org/r/20231207090738.15721-14-rdbabiera%40google.com patch subject: [PATCH v1 02/10] usb: typec: tcpci: enable reception of SOP' messages config: x86_64-allmodconfig (https://download.01.org/0day-ci/archive/20231208/202312080751.GDJHcwNz-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231208/202312080751.GDJHcwNz-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202312080751.GDJHcwNz-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/usb/typec/tcpm/fusb302.c:1470:39: error: too few arguments to function call, expected 3, have 2 tcpm_pd_receive(chip->tcpm_port, msg); ~~~~~~~~~~~~~~~ ^ include/linux/usb/tcpm.h:172:6: note: 'tcpm_pd_receive' declared here void tcpm_pd_receive(struct tcpm_port *port, ^ 1 error generated. -- >> drivers/usb/typec/tcpm/wcove.c:538:37: error: too few arguments to function call, expected 3, have 2 tcpm_pd_receive(wcove->tcpm, &msg); ~~~~~~~~~~~~~~~ ^ include/linux/usb/tcpm.h:172:6: note: 'tcpm_pd_receive' declared here void tcpm_pd_receive(struct tcpm_port *port, ^ 1 error generated. -- >> drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c:302:52: error: too few arguments to function call, expected 3, have 2 tcpm_pd_receive(pmic_typec_pdphy->tcpm_port, &msg); ~~~~~~~~~~~~~~~ ^ include/linux/usb/tcpm.h:172:6: note: 'tcpm_pd_receive' declared here void tcpm_pd_receive(struct tcpm_port *port, ^ 1 error generated. vim +1470 drivers/usb/typec/tcpm/fusb302.c c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1421 c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1422 static int fusb302_pd_read_message(struct fusb302_chip *chip, c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1423 struct pd_message *msg) c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1424 { c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1425 int ret = 0; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1426 u8 token; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1427 u8 crc[4]; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1428 int len; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1429 c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1430 /* first SOP token */ c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1431 ret = fusb302_i2c_read(chip, FUSB_REG_FIFOS, &token); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1432 if (ret < 0) c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1433 return ret; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1434 ret = fusb302_i2c_block_read(chip, FUSB_REG_FIFOS, 2, c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1435 (u8 *)&msg->header); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1436 if (ret < 0) c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1437 return ret; f03d95f59026d1 drivers/staging/typec/fusb302/fusb302.c Guru Das Srinagesh 2017-05-10 1438 len = pd_header_cnt_le(msg->header) * 4; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1439 /* add 4 to length to include the CRC */ c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1440 if (len > PD_MAX_PAYLOAD * 4) { c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1441 fusb302_log(chip, "PD message too long %d", len); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1442 return -EINVAL; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1443 } c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1444 if (len > 0) { c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1445 ret = fusb302_i2c_block_read(chip, FUSB_REG_FIFOS, len, c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1446 (u8 *)msg->payload); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1447 if (ret < 0) c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1448 return ret; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1449 } c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1450 /* another 4 bytes to read CRC out */ c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1451 ret = fusb302_i2c_block_read(chip, FUSB_REG_FIFOS, 4, crc); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1452 if (ret < 0) c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1453 return ret; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1454 fusb302_log(chip, "PD message header: %x", msg->header); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1455 fusb302_log(chip, "PD message len: %d", len); c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1456 ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1457 /* ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1458 * Check if we've read off a GoodCRC message. If so then indicate to ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1459 * TCPM that the previous transmission has completed. Otherwise we pass ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1460 * the received message over to TCPM for processing. ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1461 * ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1462 * We make this check here instead of basing the reporting decision on ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1463 * the IRQ event type, as it's possible for the chip to report the ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1464 * TX_SUCCESS and GCRCSENT events out of order on occasion, so we need ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1465 * to check the message type to ensure correct reporting to TCPM. ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1466 */ ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1467 if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC)) ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1468 tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS); ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1469 else ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 @1470 tcpm_pd_receive(chip->tcpm_port, msg); ab69f61321140f drivers/usb/typec/fusb302/fusb302.c Adam Thomson 2017-11-21 1471 c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1472 return ret; c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1473 } c034a43e72dda5 drivers/staging/typec/fusb302/fusb302.c Yueyao Zhu 2017-04-27 1474
diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index 0ee3e6e29bb1..8ea4ed159a13 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -445,8 +445,11 @@ static int tcpci_set_pd_rx(struct tcpc_dev *tcpc, bool enable) unsigned int reg = 0; int ret; - if (enable) + if (enable) { reg = TCPC_RX_DETECT_SOP | TCPC_RX_DETECT_HARD_RESET; + if (tcpci->data->cable_comm_capable) + reg |= TCPC_RX_DETECT_SOP1; + } ret = regmap_write(tcpci->regmap, TCPC_RX_DETECT, reg); if (ret < 0) return ret; @@ -584,6 +587,13 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc, enum tcpm_transmit_type type return 0; } +static bool tcpci_cable_comm_capable(struct tcpc_dev *tcpc) +{ + struct tcpci *tcpci = tcpc_to_tcpci(tcpc); + + return tcpci->data->cable_comm_capable; +} + static int tcpci_init(struct tcpc_dev *tcpc) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); @@ -712,7 +722,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) /* Read complete, clear RX status alert bit */ tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS); - tcpm_pd_receive(tcpci->port, &msg); + tcpm_pd_receive(tcpci->port, &msg, TCPC_TX_SOP); } if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) { @@ -793,6 +803,7 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data) tcpci->tcpc.enable_frs = tcpci_enable_frs; tcpci->tcpc.frs_sourcing_vbus = tcpci_frs_sourcing_vbus; tcpci->tcpc.set_partner_usb_comm_capable = tcpci_set_partner_usb_comm_capable; + tcpci->tcpc.cable_comm_capable = tcpci_cable_comm_capable; if (tcpci->data->check_contaminant) tcpci->tcpc.check_contaminant = tcpci_check_contaminant; diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c index 7fb966fd639b..548c583ab1a1 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c @@ -128,6 +128,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) u8 count, frame_type, rx_buf[TCPC_RECEIVE_BUFFER_LEN]; int ret, payload_index; u8 *rx_buf_ptr; + enum tcpm_transmit_type rx_type; /* * READABLE_BYTE_COUNT: Indicates the number of bytes in the RX_BUF_BYTE_x registers @@ -142,11 +143,23 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) count = rx_buf[TCPC_RECEIVE_BUFFER_COUNT_OFFSET]; frame_type = rx_buf[TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET]; + switch (frame_type) { + case TCPC_RX_BUF_FRAME_TYPE_SOP1: + rx_type = TCPC_TX_SOP_PRIME; + break; + case TCPC_RX_BUF_FRAME_TYPE_SOP: + rx_type = TCPC_TX_SOP; + break; + default: + rx_type = TCPC_TX_SOP; + break; + } - if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) { + if (count == 0 || (frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP && + frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP1)) { max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS); dev_err(chip->dev, "%s\n", count == 0 ? "error: count is 0" : - "error frame_type is not SOP"); + "error frame_type is not SOP/SOP'"); return; } @@ -183,7 +196,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) if (ret < 0) return; - tcpm_pd_receive(chip->port, &msg); + tcpm_pd_receive(chip->port, &msg, rx_type); } static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink) @@ -478,6 +491,7 @@ static int max_tcpci_probe(struct i2c_client *client) chip->data.vbus_vsafe0v = true; chip->data.set_partner_usb_comm_capable = max_tcpci_set_partner_usb_comm_capable; chip->data.check_contaminant = max_tcpci_check_contaminant; + chip->data.cable_comm_capable = true; max_tcpci_init_regs(chip); chip->tcpci = tcpci_register_port(chip->dev, &chip->data); diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 795e3145b0c2..5f9a4691f626 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -506,6 +506,7 @@ struct pd_rx_event { struct kthread_work work; struct tcpm_port *port; struct pd_message msg; + enum tcpm_transmit_type rx_sop_type; }; static const char * const pd_rev[] = { @@ -2972,6 +2973,7 @@ static void tcpm_pd_rx_handler(struct kthread_work *work) const struct pd_message *msg = &event->msg; unsigned int cnt = pd_header_cnt_le(msg->header); struct tcpm_port *port = event->port; + enum tcpm_transmit_type rx_sop_type = event->rx_sop_type; mutex_lock(&port->lock); @@ -2982,6 +2984,10 @@ static void tcpm_pd_rx_handler(struct kthread_work *work) enum pd_ctrl_msg_type type = pd_header_type_le(msg->header); unsigned int msgid = pd_header_msgid_le(msg->header); + /* Ignore SOP' for now */ + if (rx_sop_type == TCPC_TX_SOP_PRIME) + goto done; + /* * USB PD standard, 6.6.1.2: * "... if MessageID value in a received Message is the @@ -3019,7 +3025,8 @@ static void tcpm_pd_rx_handler(struct kthread_work *work) kfree(event); } -void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg) +void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg, + enum tcpm_transmit_type rx_sop_type) { struct pd_rx_event *event; @@ -3029,6 +3036,7 @@ void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg) kthread_init_work(&event->work, tcpm_pd_rx_handler); event->port = port; + event->rx_sop_type = rx_sop_type; memcpy(&event->msg, msg, sizeof(*msg)); kthread_queue_work(port->wq, &event->work); } diff --git a/include/linux/usb/tcpci.h b/include/linux/usb/tcpci.h index 467e8045e9f8..62c518cca934 100644 --- a/include/linux/usb/tcpci.h +++ b/include/linux/usb/tcpci.h @@ -145,6 +145,7 @@ #define TCPC_RX_BYTE_CNT 0x30 #define TCPC_RX_BUF_FRAME_TYPE 0x31 #define TCPC_RX_BUF_FRAME_TYPE_SOP 0 +#define TCPC_RX_BUF_FRAME_TYPE_SOP1 1 #define TCPC_RX_HDR 0x32 #define TCPC_RX_DATA 0x34 /* through 0x4f */ @@ -188,6 +189,8 @@ struct tcpci; * Optional; Enables TCPC to autonously discharge vbus on disconnect. * @vbus_vsafe0v: * optional; Set when TCPC can detect whether vbus is at VSAFE0V. + * @cable_comm_capable + * optional; Set when TCPC can communicate with cable plugs over SOP' * @set_partner_usb_comm_capable: * Optional; The USB Communications Capable bit indicates if port * partner is capable of communication over the USB data lines @@ -204,6 +207,7 @@ struct tcpci_data { unsigned char TX_BUF_BYTE_x_hidden:1; unsigned char auto_discharge_disconnect:1; unsigned char vbus_vsafe0v:1; + unsigned char cable_comm_capable:1; int (*init)(struct tcpci *tcpci, struct tcpci_data *data); int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data, diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index 65fac5e1f317..41d1ac9c8bbf 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -119,6 +119,9 @@ enum tcpm_transmit_type { * at the end of the deboumce period or when the port is still * toggling. Chip level drivers are expected to check for contaminant * and call tcpm_clean_port when the port is clean. + * @cable_comm_capable + * Optional; Returns whether cable communication over SOP' is supported + * by the tcpc */ struct tcpc_dev { struct fwnode_handle *fwnode; @@ -154,6 +157,7 @@ struct tcpc_dev { bool (*is_vbus_vsafe0v)(struct tcpc_dev *dev); void (*set_partner_usb_comm_capable)(struct tcpc_dev *dev, bool enable); void (*check_contaminant)(struct tcpc_dev *dev); + bool (*cable_comm_capable)(struct tcpc_dev *dev); }; struct tcpm_port; @@ -166,7 +170,8 @@ void tcpm_cc_change(struct tcpm_port *port); void tcpm_sink_frs(struct tcpm_port *port); void tcpm_sourcing_vbus(struct tcpm_port *port); void tcpm_pd_receive(struct tcpm_port *port, - const struct pd_message *msg); + const struct pd_message *msg, + enum tcpm_transmit_type rx_sop_type); void tcpm_pd_transmit_complete(struct tcpm_port *port, enum tcpm_transmit_status status); void tcpm_pd_hard_reset(struct tcpm_port *port);
Add cable_comm_capable to tcpci_data for tcpci drivers to indicate that the port tcpc is capable of communicating to cables over SOP. A corresponding tcpci callback tcpci_cable_comm_capable returns this value. The tcpm will primarily use this in later patches to determine if the port can transmit and receive SOP' messages. tcpci_set_pd_rx now utilizes the cable_comm_capable flag to determine if TCPC_RX_DETECT_SOP1 should be added to the bitfield when enabling PD message reception. In the tcpci, add a definition for TCPC_RX_BUF_FRAME_TYPE_SOP1 as described in the Type C Port Controller Interface Specification Section 4.4.14. Maxim based tcpci drivers are capable of SOP' communication, so the cable_comm_capable flag is set to true. process_rx now takes the SOP' into account and passes the value to tcpm_pd_receive. tcpm_pd_receive adds the SOP type as a parameter, and passes it within the pd_rx_event struct for tcpm_pd_rx_handler to use. For now, the handler drops all SOP' messages. Signed-off-by: RD Babiera <rdbabiera@google.com> --- drivers/usb/typec/tcpm/tcpci.c | 15 +++++++++++++-- drivers/usb/typec/tcpm/tcpci_maxim_core.c | 20 +++++++++++++++++--- drivers/usb/typec/tcpm/tcpm.c | 10 +++++++++- include/linux/usb/tcpci.h | 4 ++++ include/linux/usb/tcpm.h | 7 ++++++- 5 files changed, 49 insertions(+), 7 deletions(-)