diff options
| -rw-r--r-- | drivers/mfd/cros_ec_spi.c | 24 | ||||
| -rw-r--r-- | drivers/platform/chrome/cros_ec_proto.c | 2 |
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 | ||
