Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bee79752 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 9ce86543 11799564
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -419,10 +419,25 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
		/* Verify that EC can process command */
		for (i = 0; i < len; i++) {
			rx_byte = rx_buf[i];
			/*
			 * Seeing the PAST_END, RX_BAD_DATA, or NOT_READY
			 * markers are all signs that the EC didn't fully
			 * receive our command. e.g., if the EC is flashing
			 * itself, it can't respond to any commands and instead
			 * clocks out EC_SPI_PAST_END from its SPI hardware
			 * buffer. Similar occurrences can happen if the AP is
			 * too slow to clock out data after asserting CS -- the
			 * EC will abort and fill its buffer with
			 * EC_SPI_RX_BAD_DATA.
			 *
			 * In all cases, these errors should be safe to retry.
			 * Report -EAGAIN and let the caller decide what to do
			 * about that.
			 */
			if (rx_byte == EC_SPI_PAST_END  ||
			    rx_byte == EC_SPI_RX_BAD_DATA ||
			    rx_byte == EC_SPI_NOT_READY) {
				ret = -EREMOTEIO;
				ret = -EAGAIN;
				break;
			}
		}
@@ -431,7 +446,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
	if (!ret)
		ret = cros_ec_spi_receive_packet(ec_dev,
				ec_msg->insize + sizeof(*response));
	else
	else if (ret != -EAGAIN)
		dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);

	final_ret = terminate_request(ec_dev);
@@ -537,10 +552,11 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
		/* Verify that EC can process command */
		for (i = 0; i < len; i++) {
			rx_byte = rx_buf[i];
			/* See comments in cros_ec_pkt_xfer_spi() */
			if (rx_byte == EC_SPI_PAST_END  ||
			    rx_byte == EC_SPI_RX_BAD_DATA ||
			    rx_byte == EC_SPI_NOT_READY) {
				ret = -EREMOTEIO;
				ret = -EAGAIN;
				break;
			}
		}
@@ -549,7 +565,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
	if (!ret)
		ret = cros_ec_spi_receive_response(ec_dev,
				ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
	else
	else if (ret != -EAGAIN)
		dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);

	final_ret = terminate_request(ec_dev);
+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ static int send_command(struct cros_ec_device *ec_dev,
			usleep_range(10000, 11000);

			ret = (*xfer_fxn)(ec_dev, status_msg);
			if (ret == -EAGAIN)
				continue;
			if (ret < 0)
				break;