hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/soundwire/cadence_master.c
....@@ -511,6 +511,29 @@
511511 return SDW_CMD_OK;
512512 }
513513
514
+static void cdns_read_response(struct sdw_cdns *cdns)
515
+{
516
+ u32 num_resp, cmd_base;
517
+ int i;
518
+
519
+ /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */
520
+ BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2);
521
+
522
+ num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
523
+ num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
524
+ if (num_resp > ARRAY_SIZE(cdns->response_buf)) {
525
+ dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp);
526
+ num_resp = ARRAY_SIZE(cdns->response_buf);
527
+ }
528
+
529
+ cmd_base = CDNS_MCP_CMD_BASE;
530
+
531
+ for (i = 0; i < num_resp; i++) {
532
+ cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
533
+ cmd_base += CDNS_MCP_CMD_WORD_LEN;
534
+ }
535
+}
536
+
514537 static enum sdw_command_response
515538 _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
516539 int offset, int count, bool defer)
....@@ -552,6 +575,10 @@
552575 dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
553576 cmd, msg->dev_num, msg->addr, msg->len);
554577 msg->len = 0;
578
+
579
+ /* Drain anything in the RX_FIFO */
580
+ cdns_read_response(cdns);
581
+
555582 return SDW_CMD_TIMEOUT;
556583 }
557584
....@@ -719,22 +746,6 @@
719746 /*
720747 * IRQ handling
721748 */
722
-
723
-static void cdns_read_response(struct sdw_cdns *cdns)
724
-{
725
- u32 num_resp, cmd_base;
726
- int i;
727
-
728
- num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
729
- num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
730
-
731
- cmd_base = CDNS_MCP_CMD_BASE;
732
-
733
- for (i = 0; i < num_resp; i++) {
734
- cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
735
- cmd_base += CDNS_MCP_CMD_WORD_LEN;
736
- }
737
-}
738749
739750 static int cdns_update_slave_status(struct sdw_cdns *cdns,
740751 u32 slave0, u32 slave1)