aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-23 11:20:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-23 11:20:49 -0400
commitbee797529d7c1ea4e2803fda067d20edbc00bc3d (patch)
tree9a19b34411360d1299e0f9a270b779e746a959bd
parent9ce8654323d69273b4977f76f11c9e2d345ab130 (diff)
parent11799564fc7eedff50801950090773928f867996 (diff)
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
-rw-r--r--drivers/mfd/cros_ec_spi.c24
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c2
2 files changed, 22 insertions, 4 deletions
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index 1b52b8557034..2060d1483043 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -419,10 +419,25 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
419 /* Verify that EC can process command */ 419 /* Verify that EC can process command */
420 for (i = 0; i < len; i++) { 420 for (i = 0; i < len; i++) {
421 rx_byte = rx_buf[i]; 421 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 */
422 if (rx_byte == EC_SPI_PAST_END || 437 if (rx_byte == EC_SPI_PAST_END ||
423 rx_byte == EC_SPI_RX_BAD_DATA || 438 rx_byte == EC_SPI_RX_BAD_DATA ||
424 rx_byte == EC_SPI_NOT_READY) { 439 rx_byte == EC_SPI_NOT_READY) {
425 ret = -EREMOTEIO; 440 ret = -EAGAIN;
426 break; 441 break;
427 } 442 }
428 } 443 }
@@ -431,7 +446,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
431 if (!ret) 446 if (!ret)
432 ret = cros_ec_spi_receive_packet(ec_dev, 447 ret = cros_ec_spi_receive_packet(ec_dev,
433 ec_msg->insize + sizeof(*response)); 448 ec_msg->insize + sizeof(*response));
434 else 449 else if (ret != -EAGAIN)
435 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); 450 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
436 451
437 final_ret = terminate_request(ec_dev); 452 final_ret = terminate_request(ec_dev);
@@ -537,10 +552,11 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
537 /* Verify that EC can process command */ 552 /* Verify that EC can process command */
538 for (i = 0; i < len; i++) { 553 for (i = 0; i < len; i++) {
539 rx_byte = rx_buf[i]; 554 rx_byte = rx_buf[i];
555 /* See comments in cros_ec_pkt_xfer_spi() */
540 if (rx_byte == EC_SPI_PAST_END || 556 if (rx_byte == EC_SPI_PAST_END ||
541 rx_byte == EC_SPI_RX_BAD_DATA || 557 rx_byte == EC_SPI_RX_BAD_DATA ||
542 rx_byte == EC_SPI_NOT_READY) { 558 rx_byte == EC_SPI_NOT_READY) {
543 ret = -EREMOTEIO; 559 ret = -EAGAIN;
544 break; 560 break;
545 } 561 }
546 } 562 }
@@ -549,7 +565,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
549 if (!ret) 565 if (!ret)
550 ret = cros_ec_spi_receive_response(ec_dev, 566 ret = cros_ec_spi_receive_response(ec_dev,
551 ec_msg->insize + EC_MSG_TX_PROTO_BYTES); 567 ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
552 else 568 else if (ret != -EAGAIN)
553 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); 569 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
554 570
555 final_ret = terminate_request(ec_dev); 571 final_ret = terminate_request(ec_dev);
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index e7bbdf947bbc..8350ca2311c7 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -91,6 +91,8 @@ static int send_command(struct cros_ec_device *ec_dev,
91 usleep_range(10000, 11000); 91 usleep_range(10000, 11000);
92 92
93 ret = (*xfer_fxn)(ec_dev, status_msg); 93 ret = (*xfer_fxn)(ec_dev, status_msg);
94 if (ret == -EAGAIN)
95 continue;
94 if (ret < 0) 96 if (ret < 0)
95 break; 97 break;
96 98