aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Chang <ianchang@ieiworld.com>2023-04-11 16:07:24 +0800
committerDaniel Golle <daniel@makrotopia.org>2023-04-13 01:07:54 +0100
commit877ec78e2354e39a363bf257b7562a36d4b18e4a (patch)
tree7bcaefa076d493444b56539338056e07d950c17e
parent50f7c5af4a07a8a898a0a60068c6fd4cc40a3273 (diff)
downloadupstream-877ec78e2354e39a363bf257b7562a36d4b18e4a.tar.gz
upstream-877ec78e2354e39a363bf257b7562a36d4b18e4a.tar.bz2
upstream-877ec78e2354e39a363bf257b7562a36d4b18e4a.zip
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@ieiworld.com>
-rw-r--r--target/linux/mvebu/patches-5.10/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch63
-rw-r--r--target/linux/mvebu/patches-5.15/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch63
2 files changed, 126 insertions, 0 deletions
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);