mvebu: puzzle-mcu: add mcu write retry function
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.15 / 911-drivers-leds-wt61p803-puzzle-mcu-retry.patch
1 --- a/drivers/mfd/iei-wt61p803-puzzle.c
2 +++ b/drivers/mfd/iei-wt61p803-puzzle.c
3 @@ -241,6 +241,7 @@ int iei_wt61p803_puzzle_write_command(st
4 {
5 struct device *dev = &mcu->serdev->dev;
6 int ret;
7 + int retries;
8
9 if (size <= 1 || size > IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH)
10 return -EINVAL;
11 @@ -252,24 +253,36 @@ int iei_wt61p803_puzzle_write_command(st
12 print_hex_dump_debug("puzzle-mcu tx: ", DUMP_PREFIX_NONE,
13 16, 1, cmd, size, false);
14
15 + retries = 3;
16 /* Initialize reply struct */
17 - reinit_completion(&mcu->reply->received);
18 - mcu->reply->size = 0;
19 - usleep_range(2000, 10000);
20 - serdev_device_write_flush(mcu->serdev);
21 - ret = serdev_device_write_buf(mcu->serdev, cmd, size);
22 - if (ret < 0)
23 - goto exit;
24 -
25 - serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
26 - ret = wait_for_completion_timeout(&mcu->reply->received,
27 - IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
28 - if (ret == 0) {
29 - dev_err(dev, "Command reply receive timeout\n");
30 - ret = -ETIMEDOUT;
31 - goto exit;
32 + while (retries) {
33 + reinit_completion(&mcu->reply->received);
34 + mcu->reply->size = 0;
35 + usleep_range(2000, 10000);
36 + serdev_device_write_flush(mcu->serdev);
37 + ret = serdev_device_write_buf(mcu->serdev, cmd, size);
38 + if (ret < 0)
39 + goto exit;
40 +
41 + serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
42 + ret = wait_for_completion_timeout(&mcu->reply->received,
43 + IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
44 + retries--;
45 + if (ret == 0) {
46 + if (retries == 0) {
47 + dev_err(dev, "Command reply receive timeout\n");
48 + ret = -ETIMEDOUT;
49 + goto exit;
50 + }
51 + }
52 + else {
53 + if (mcu->reply->data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
54 + mcu->reply->data[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
55 + mcu->reply->data[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK) {
56 + break;
57 + }
58 + }
59 }
60 -
61 *reply_size = mcu->reply->size;
62 /* Copy the received data, as it will not be available after a new frame is received */
63 memcpy(reply_data, mcu->reply->data, mcu->reply->size);