[openwrt/openwrt] mvebu: puzzle-mcu: add mcu write retry function

LEDE Commits lede-commits at lists.infradead.org
Wed Apr 12 17:34:49 PDT 2023


dangole pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/877ec78e2354e39a363bf257b7562a36d4b18e4a

commit 877ec78e2354e39a363bf257b7562a36d4b18e4a
Author: Ian Chang <ianchang at ieiworld.com>
AuthorDate: Tue Apr 11 16:07:24 2023 +0800

    mvebu: puzzle-mcu: add mcu write retry function
    
    Avoid MCU getting "command reply receive timed out" message when LED
    configuration setting trigger function is enabled in heartbeat mode.
    
    Signed-off-by: Ian Chang <ianchang at ieiworld.com>
---
 ...11-drivers-leds-wt61p803-puzzle-mcu-retry.patch | 63 ++++++++++++++++++++++
 ...11-drivers-leds-wt61p803-puzzle-mcu-retry.patch | 63 ++++++++++++++++++++++
 2 files changed, 126 insertions(+)

diff --git a/target/linux/mvebu/patches-5.10/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch b/target/linux/mvebu/patches-5.10/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
new file mode 100644
index 0000000000..2f0b1788ff
--- /dev/null
+++ b/target/linux/mvebu/patches-5.10/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
@@ -0,0 +1,63 @@
+--- a/drivers/mfd/iei-wt61p803-puzzle.c
++++ b/drivers/mfd/iei-wt61p803-puzzle.c
+@@ -241,6 +241,7 @@ int iei_wt61p803_puzzle_write_command(st
+ {
+ 	struct device *dev = &mcu->serdev->dev;
+ 	int ret;
++	int retries;
+ 
+ 	if (size <= 1 || size > IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH)
+ 		return -EINVAL;
+@@ -252,24 +253,36 @@ int iei_wt61p803_puzzle_write_command(st
+ 	print_hex_dump_debug("puzzle-mcu tx: ", DUMP_PREFIX_NONE,
+ 			     16, 1, cmd, size, false);
+ 
++	retries = 3;
+ 	/* Initialize reply struct */
+-	reinit_completion(&mcu->reply->received);
+-	mcu->reply->size = 0;
+-	usleep_range(2000, 10000);
+-	serdev_device_write_flush(mcu->serdev);
+-	ret = serdev_device_write_buf(mcu->serdev, cmd, size);
+-	if (ret < 0)
+-		goto exit;
+-
+-	serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
+-	ret = wait_for_completion_timeout(&mcu->reply->received,
+-					  IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
+-	if (ret == 0) {
+-		dev_err(dev, "Command reply receive timeout\n");
+-		ret = -ETIMEDOUT;
+-		goto exit;
++	while (retries) {
++		reinit_completion(&mcu->reply->received);
++		mcu->reply->size = 0;
++		usleep_range(2000, 10000);
++		serdev_device_write_flush(mcu->serdev);
++		ret = serdev_device_write_buf(mcu->serdev, cmd, size);
++		if (ret < 0)
++			goto exit;
++
++		serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
++		ret = wait_for_completion_timeout(&mcu->reply->received,
++						  IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
++		retries--;
++		if (ret == 0) {
++			if (retries == 0) {
++				dev_err(dev, "Command reply receive timeout\n");
++				ret = -ETIMEDOUT;
++				goto exit;
++			}
++		}
++		else {
++			if (mcu->reply->data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
++				mcu->reply->data[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
++				mcu->reply->data[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK) {
++				break;
++			}
++		}
+ 	}
+-
+ 	*reply_size = mcu->reply->size;
+ 	/* Copy the received data, as it will not be available after a new frame is received */
+ 	memcpy(reply_data, mcu->reply->data, mcu->reply->size);
diff --git a/target/linux/mvebu/patches-5.15/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch b/target/linux/mvebu/patches-5.15/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
new file mode 100644
index 0000000000..2f0b1788ff
--- /dev/null
+++ b/target/linux/mvebu/patches-5.15/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
@@ -0,0 +1,63 @@
+--- a/drivers/mfd/iei-wt61p803-puzzle.c
++++ b/drivers/mfd/iei-wt61p803-puzzle.c
+@@ -241,6 +241,7 @@ int iei_wt61p803_puzzle_write_command(st
+ {
+ 	struct device *dev = &mcu->serdev->dev;
+ 	int ret;
++	int retries;
+ 
+ 	if (size <= 1 || size > IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH)
+ 		return -EINVAL;
+@@ -252,24 +253,36 @@ int iei_wt61p803_puzzle_write_command(st
+ 	print_hex_dump_debug("puzzle-mcu tx: ", DUMP_PREFIX_NONE,
+ 			     16, 1, cmd, size, false);
+ 
++	retries = 3;
+ 	/* Initialize reply struct */
+-	reinit_completion(&mcu->reply->received);
+-	mcu->reply->size = 0;
+-	usleep_range(2000, 10000);
+-	serdev_device_write_flush(mcu->serdev);
+-	ret = serdev_device_write_buf(mcu->serdev, cmd, size);
+-	if (ret < 0)
+-		goto exit;
+-
+-	serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
+-	ret = wait_for_completion_timeout(&mcu->reply->received,
+-					  IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
+-	if (ret == 0) {
+-		dev_err(dev, "Command reply receive timeout\n");
+-		ret = -ETIMEDOUT;
+-		goto exit;
++	while (retries) {
++		reinit_completion(&mcu->reply->received);
++		mcu->reply->size = 0;
++		usleep_range(2000, 10000);
++		serdev_device_write_flush(mcu->serdev);
++		ret = serdev_device_write_buf(mcu->serdev, cmd, size);
++		if (ret < 0)
++			goto exit;
++
++		serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
++		ret = wait_for_completion_timeout(&mcu->reply->received,
++						  IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
++		retries--;
++		if (ret == 0) {
++			if (retries == 0) {
++				dev_err(dev, "Command reply receive timeout\n");
++				ret = -ETIMEDOUT;
++				goto exit;
++			}
++		}
++		else {
++			if (mcu->reply->data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
++				mcu->reply->data[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
++				mcu->reply->data[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK) {
++				break;
++			}
++		}
+ 	}
+-
+ 	*reply_size = mcu->reply->size;
+ 	/* Copy the received data, as it will not be available after a new frame is received */
+ 	memcpy(reply_data, mcu->reply->data, mcu->reply->size);




More information about the lede-commits mailing list