Skip to content

Commit 7ac45bc

Browse files
ahunter6alexandrebelloni
authored andcommitted
i3c: mipi-i3c-hci: Consolidate common xfer processing logic
Several parts of the MIPI I3C HCI driver duplicate the same sequence for queuing a transfer, waiting for completion, and handling timeouts. This logic appears in five separate locations and will be affected by an upcoming fix. Refactor the repeated code into a new helper, i3c_hci_process_xfer(), and store the timeout value in the hci_xfer structure so that callers do not need to pass it as a separate parameter. Fixes: 9ad9a52 ("i3c/master: introduce the mipi-i3c-hci driver") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260306072451.11131-12-adrian.hunter@intel.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent b6d5864 commit 7ac45bc

4 files changed

Lines changed: 33 additions & 28 deletions

File tree

drivers/i3c/master/mipi-i3c-hci/cmd_v1.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,10 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci)
331331
CMD_A0_ROC | CMD_A0_TOC;
332332
xfer->cmd_desc[1] = 0;
333333
xfer->completion = &done;
334-
hci->io->queue_xfer(hci, xfer, 1);
335-
if (!wait_for_completion_timeout(&done, HZ) &&
336-
hci->io->dequeue_xfer(hci, xfer, 1)) {
337-
ret = -ETIMEDOUT;
334+
xfer->timeout = HZ;
335+
ret = i3c_hci_process_xfer(hci, xfer, 1);
336+
if (ret)
338337
break;
339-
}
340338
if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER ||
341339
RESP_STATUS(xfer->response) == RESP_ERR_NACK) &&
342340
RESP_DATA_LENGTH(xfer->response) == 1) {

drivers/i3c/master/mipi-i3c-hci/cmd_v2.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci)
253253
xfer[0].rnw = true;
254254
xfer[0].cmd_desc[1] = CMD_A1_DATA_LENGTH(8);
255255
xfer[1].completion = &done;
256+
xfer[1].timeout = HZ;
256257

257258
for (;;) {
258259
ret = i3c_master_get_free_addr(&hci->master, next_addr);
@@ -272,12 +273,9 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci)
272273
CMD_A0_ASSIGN_ADDRESS(next_addr) |
273274
CMD_A0_ROC |
274275
CMD_A0_TOC;
275-
hci->io->queue_xfer(hci, xfer, 2);
276-
if (!wait_for_completion_timeout(&done, HZ) &&
277-
hci->io->dequeue_xfer(hci, xfer, 2)) {
278-
ret = -ETIMEDOUT;
276+
ret = i3c_hci_process_xfer(hci, xfer, 2);
277+
if (ret)
279278
break;
280-
}
281279
if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) {
282280
ret = 0; /* no more devices to be assigned */
283281
break;

drivers/i3c/master/mipi-i3c-hci/core.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,25 @@ void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci)
213213
reg_write(DCT_SECTION, FIELD_PREP(DCT_TABLE_INDEX, 0));
214214
}
215215

216+
int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n)
217+
{
218+
struct completion *done = xfer[n - 1].completion;
219+
unsigned long timeout = xfer[n - 1].timeout;
220+
int ret;
221+
222+
ret = hci->io->queue_xfer(hci, xfer, n);
223+
if (ret)
224+
return ret;
225+
226+
if (!wait_for_completion_timeout(done, timeout) &&
227+
hci->io->dequeue_xfer(hci, xfer, n)) {
228+
dev_err(&hci->master.dev, "%s: timeout error\n", __func__);
229+
return -ETIMEDOUT;
230+
}
231+
232+
return 0;
233+
}
234+
216235
static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
217236
struct i3c_ccc_cmd *ccc)
218237
{
@@ -253,18 +272,14 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
253272
last = i - 1;
254273
xfer[last].cmd_desc[0] |= CMD_0_TOC;
255274
xfer[last].completion = &done;
275+
xfer[last].timeout = HZ;
256276

257277
if (prefixed)
258278
xfer--;
259279

260-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
280+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
261281
if (ret)
262282
goto out;
263-
if (!wait_for_completion_timeout(&done, HZ) &&
264-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
265-
ret = -ETIMEDOUT;
266-
goto out;
267-
}
268283
for (i = prefixed; i < nxfers; i++) {
269284
if (ccc->rnw)
270285
ccc->dests[i - prefixed].payload.len =
@@ -335,15 +350,11 @@ static int i3c_hci_i3c_xfers(struct i3c_dev_desc *dev,
335350
last = i - 1;
336351
xfer[last].cmd_desc[0] |= CMD_0_TOC;
337352
xfer[last].completion = &done;
353+
xfer[last].timeout = HZ;
338354

339-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
355+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
340356
if (ret)
341357
goto out;
342-
if (!wait_for_completion_timeout(&done, HZ) &&
343-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
344-
ret = -ETIMEDOUT;
345-
goto out;
346-
}
347358
for (i = 0; i < nxfers; i++) {
348359
if (i3c_xfers[i].rnw)
349360
i3c_xfers[i].len = RESP_DATA_LENGTH(xfer[i].response);
@@ -383,15 +394,11 @@ static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev,
383394
last = i - 1;
384395
xfer[last].cmd_desc[0] |= CMD_0_TOC;
385396
xfer[last].completion = &done;
397+
xfer[last].timeout = m->i2c.timeout;
386398

387-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
399+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
388400
if (ret)
389401
goto out;
390-
if (!wait_for_completion_timeout(&done, m->i2c.timeout) &&
391-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
392-
ret = -ETIMEDOUT;
393-
goto out;
394-
}
395402
for (i = 0; i < nxfers; i++) {
396403
if (RESP_STATUS(xfer[i].response) != RESP_SUCCESS) {
397404
ret = -EIO;

drivers/i3c/master/mipi-i3c-hci/hci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct hci_xfer {
8989
unsigned int data_len;
9090
unsigned int cmd_tid;
9191
struct completion *completion;
92+
unsigned long timeout;
9293
union {
9394
struct {
9495
/* PIO specific */
@@ -156,5 +157,6 @@ void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci);
156157
void amd_set_od_pp_timing(struct i3c_hci *hci);
157158
void amd_set_resp_buf_thld(struct i3c_hci *hci);
158159
void i3c_hci_sync_irq_inactive(struct i3c_hci *hci);
160+
int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n);
159161

160162
#endif

0 commit comments

Comments
 (0)