Skip to content

Commit bee7975

Browse files
committed
Merge tag 'mfd-fixes-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD fix from Lee Jones: "A single cros_ec_spi fix correcting the handling for long-running commands" * tag 'mfd-fixes-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: mfd: cros_ec: Retry commands when EC is known to be busy
2 parents 9ce8654 + 1179956 commit bee7975

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

drivers/mfd/cros_ec_spi.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,25 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
419419
/* Verify that EC can process command */
420420
for (i = 0; i < len; i++) {
421421
rx_byte = rx_buf[i];
422+
/*
423+
* Seeing the PAST_END, RX_BAD_DATA, or NOT_READY
424+
* markers are all signs that the EC didn't fully
425+
* receive our command. e.g., if the EC is flashing
426+
* itself, it can't respond to any commands and instead
427+
* clocks out EC_SPI_PAST_END from its SPI hardware
428+
* buffer. Similar occurrences can happen if the AP is
429+
* too slow to clock out data after asserting CS -- the
430+
* EC will abort and fill its buffer with
431+
* EC_SPI_RX_BAD_DATA.
432+
*
433+
* In all cases, these errors should be safe to retry.
434+
* Report -EAGAIN and let the caller decide what to do
435+
* about that.
436+
*/
422437
if (rx_byte == EC_SPI_PAST_END ||
423438
rx_byte == EC_SPI_RX_BAD_DATA ||
424439
rx_byte == EC_SPI_NOT_READY) {
425-
ret = -EREMOTEIO;
440+
ret = -EAGAIN;
426441
break;
427442
}
428443
}
@@ -431,7 +446,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
431446
if (!ret)
432447
ret = cros_ec_spi_receive_packet(ec_dev,
433448
ec_msg->insize + sizeof(*response));
434-
else
449+
else if (ret != -EAGAIN)
435450
dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
436451

437452
final_ret = terminate_request(ec_dev);
@@ -537,10 +552,11 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
537552
/* Verify that EC can process command */
538553
for (i = 0; i < len; i++) {
539554
rx_byte = rx_buf[i];
555+
/* See comments in cros_ec_pkt_xfer_spi() */
540556
if (rx_byte == EC_SPI_PAST_END ||
541557
rx_byte == EC_SPI_RX_BAD_DATA ||
542558
rx_byte == EC_SPI_NOT_READY) {
543-
ret = -EREMOTEIO;
559+
ret = -EAGAIN;
544560
break;
545561
}
546562
}
@@ -549,7 +565,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
549565
if (!ret)
550566
ret = cros_ec_spi_receive_response(ec_dev,
551567
ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
552-
else
568+
else if (ret != -EAGAIN)
553569
dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
554570

555571
final_ret = terminate_request(ec_dev);

drivers/platform/chrome/cros_ec_proto.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ static int send_command(struct cros_ec_device *ec_dev,
9191
usleep_range(10000, 11000);
9292

9393
ret = (*xfer_fxn)(ec_dev, status_msg);
94+
if (ret == -EAGAIN)
95+
continue;
9496
if (ret < 0)
9597
break;
9698

0 commit comments

Comments
 (0)