Re: [PATCH] soundwire: qcom: wait for fifo space to be available before read/write

From: Pierre-Louis Bossart
Date: Wed Mar 31 2021 - 14:39:34 EST



+static int swrm_wait_for_rd_fifo_avail(struct qcom_swrm_ctrl *swrm)
+{
+ u32 fifo_outstanding_cmd, value;
+ u8 fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
+
+ /* Check for fifo underflow during read */
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmd = FIELD_GET(SWRM_RD_CMD_FIFO_CNT_MASK, value);
+
+ /* Check number of outstanding commands in fifo before read */
+ if (fifo_outstanding_cmd)
+ return 0;
+
+ do {
+ usleep_range(500, 510);
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmd = FIELD_GET(SWRM_RD_CMD_FIFO_CNT_MASK, value);
+ if (fifo_outstanding_cmd > 0)
+ break;
+ } while (fifo_retry_count--);
+
+ if (fifo_outstanding_cmd == 0) {
+ dev_err_ratelimited(swrm->dev, "%s err read underflow\n", __func__);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int swrm_wait_for_wr_fifo_avail(struct qcom_swrm_ctrl *swrm)
+{
+ u32 fifo_outstanding_cmd, value;
+ u8 fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
+
+ /* Check for fifo overflow during write */
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmd = FIELD_GET(SWRM_WR_CMD_FIFO_CNT_MASK, value);
+
+ /* Check number of outstanding commands in fifo before write */
+ if (fifo_outstanding_cmd != swrm->wr_fifo_depth)
+ return 0;
+
+ do {
+ usleep_range(500, 510);
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmd = FIELD_GET(SWRM_WR_CMD_FIFO_CNT_MASK, value);
+ if (fifo_outstanding_cmd < swrm->wr_fifo_depth)
+ break;
+ } while (fifo_retry_count--);
+
+ if (fifo_outstanding_cmd == swrm->wr_fifo_depth) {
+ dev_err_ratelimited(swrm->dev, "%s err write overflow\n", __func__);
+ return -ENOMEM;
+ }
+
+ return 0;
+}

nit-pick: you could merge the prologue and loop body with a while(fifo_retry_count--) and put the usleep_range() at the end of the loop.