]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
a3572c057417b97545d973bb7fb543810b145d93
[thirdparty/kernel/stable-queue.git] /
1 From 83beece5aff75879bdfc6df8ba84ea88fd93050e Mon Sep 17 00:00:00 2001
2 From: Conor Dooley <conor.dooley@microchip.com>
3 Date: Wed, 16 Oct 2024 17:35:06 +0100
4 Subject: firmware: microchip: auto-update: fix poll_complete() to not report spurious timeout errors
5
6 From: Conor Dooley <conor.dooley@microchip.com>
7
8 commit 83beece5aff75879bdfc6df8ba84ea88fd93050e upstream.
9
10 fw_upload's poll_complete() is really intended for use with
11 asynchronous write() implementations - or at least those where the
12 write() loop may terminate without the kernel yet being aware of whether
13 or not the firmware upload has succeeded. For auto-update, write() is
14 only ever called once and will only return when uploading has completed,
15 be that by passing or failing. The core fw_upload code only calls
16 poll_complete() after the final call to write() has returned.
17
18 However, the poll_complete() implementation in the auto-update driver
19 was written to expect poll_complete() to be called from another context,
20 and it waits for a completion signalled from write(). Since
21 poll_complete() is actually called from the same context, after the
22 write() loop has terminated, wait_for_completion() never sees the
23 completion get signalled and always times out, causing programming to
24 always report a failing.
25
26 Since write() is full synchronous, and its return value will indicate
27 whether or not programming passed or failed, poll_complete() serves no
28 purpose and can be cut down to simply return FW_UPLOAD_ERR_NONE.
29
30 Cc: stable@vger.kernel.org
31 Fixes: ec5b0f1193ad4 ("firmware: microchip: add PolarFire SoC Auto Update support")
32 Reported-by: Jamie Gibbons <jamie.gibbons@microchip.com>
33 Tested-by: Jamie Gibbons <jamie.gibbons@microchip.com>
34 Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
35 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
36 ---
37 drivers/firmware/microchip/mpfs-auto-update.c | 42 ++++----------------------
38 1 file changed, 7 insertions(+), 35 deletions(-)
39
40 --- a/drivers/firmware/microchip/mpfs-auto-update.c
41 +++ b/drivers/firmware/microchip/mpfs-auto-update.c
42 @@ -76,14 +76,11 @@
43 #define AUTO_UPDATE_INFO_SIZE SZ_1M
44 #define AUTO_UPDATE_BITSTREAM_BASE (AUTO_UPDATE_DIRECTORY_SIZE + AUTO_UPDATE_INFO_SIZE)
45
46 -#define AUTO_UPDATE_TIMEOUT_MS 60000
47 -
48 struct mpfs_auto_update_priv {
49 struct mpfs_sys_controller *sys_controller;
50 struct device *dev;
51 struct mtd_info *flash;
52 struct fw_upload *fw_uploader;
53 - struct completion programming_complete;
54 size_t size_per_bitstream;
55 bool cancel_request;
56 };
57 @@ -156,19 +153,6 @@ static void mpfs_auto_update_cancel(stru
58
59 static enum fw_upload_err mpfs_auto_update_poll_complete(struct fw_upload *fw_uploader)
60 {
61 - struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
62 - int ret;
63 -
64 - /*
65 - * There is no meaningful way to get the status of the programming while
66 - * it is in progress, so attempting anything other than waiting for it
67 - * to complete would be misplaced.
68 - */
69 - ret = wait_for_completion_timeout(&priv->programming_complete,
70 - msecs_to_jiffies(AUTO_UPDATE_TIMEOUT_MS));
71 - if (!ret)
72 - return FW_UPLOAD_ERR_TIMEOUT;
73 -
74 return FW_UPLOAD_ERR_NONE;
75 }
76
77 @@ -349,33 +333,23 @@ static enum fw_upload_err mpfs_auto_upda
78 u32 offset, u32 size, u32 *written)
79 {
80 struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
81 - enum fw_upload_err err = FW_UPLOAD_ERR_NONE;
82 int ret;
83
84 - reinit_completion(&priv->programming_complete);
85 -
86 ret = mpfs_auto_update_write_bitstream(fw_uploader, data, offset, size, written);
87 - if (ret) {
88 - err = FW_UPLOAD_ERR_RW_ERROR;
89 - goto out;
90 - }
91 + if (ret)
92 + return FW_UPLOAD_ERR_RW_ERROR;
93
94 - if (priv->cancel_request) {
95 - err = FW_UPLOAD_ERR_CANCELED;
96 - goto out;
97 - }
98 + if (priv->cancel_request)
99 + return FW_UPLOAD_ERR_CANCELED;
100
101 if (mpfs_auto_update_is_bitstream_info(data, size))
102 - goto out;
103 + return FW_UPLOAD_ERR_NONE;
104
105 ret = mpfs_auto_update_verify_image(fw_uploader);
106 if (ret)
107 - err = FW_UPLOAD_ERR_FW_INVALID;
108 + return FW_UPLOAD_ERR_FW_INVALID;
109
110 -out:
111 - complete(&priv->programming_complete);
112 -
113 - return err;
114 + return FW_UPLOAD_ERR_NONE;
115 }
116
117 static const struct fw_upload_ops mpfs_auto_update_ops = {
118 @@ -461,8 +435,6 @@ static int mpfs_auto_update_probe(struct
119 return dev_err_probe(dev, ret,
120 "The current bitstream does not support auto-update\n");
121
122 - init_completion(&priv->programming_complete);
123 -
124 fw_uploader = firmware_upload_register(THIS_MODULE, dev, "mpfs-auto-update",
125 &mpfs_auto_update_ops, priv);
126 if (IS_ERR(fw_uploader))