summaryrefslogtreecommitdiff
path: root/target/linux/mvebu/patches-5.10/911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
blob: 2f0b1788ff68f2ff4ed384ad63a297fd1d888f46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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);