aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlo Caione <carlo@endlessm.com>2017-03-03 10:17:59 -0500
committerKevin Hilman <khilman@baylibre.com>2017-03-23 15:22:40 -0400
commit7a9bc330df9b8fb3245d50a198b5c6d4d634b06f (patch)
tree2a0eb3dff0c28d6a29acf38baf46f49a9323dabe
parent83e007a0c6a3f4bfdf8f3f8d0fc266cda189b3d6 (diff)
firmware: meson-sm: Allow 0 as valid return value
Some special SMC calls (i.e. the function used to retrieve the serial number of the Amlogic SoCs) returns 0 in the register 0 also when the data was successfully read instead of using the register to hold the number of bytes returned in the bounce buffer as expected. With the current implementation of the driver this is seen as an error and meson_sm_call_read() returns an error even though the data was correctly read. To deal with this when we have no information about the amount of read data (that is 0 is returned by the SMC call) we return to the caller the requested amount of data and 0 as return value. Signed-off-by: Carlo Caione <carlo@endlessm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
-rw-r--r--drivers/firmware/meson/meson_sm.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 5f30a5774e57..ff204421117b 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -136,11 +136,14 @@ EXPORT_SYMBOL(meson_sm_call);
136 * @arg4: SMC32 Argument 4 136 * @arg4: SMC32 Argument 4
137 * 137 *
138 * Return: size of read data on success, a negative value on error 138 * Return: size of read data on success, a negative value on error
139 * When 0 is returned there is no guarantee about the amount of
140 * data read and bsize bytes are copied in buffer.
139 */ 141 */
140int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 142int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
141 u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 143 u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
142{ 144{
143 u32 size; 145 u32 size;
146 int ret;
144 147
145 if (!fw.chip) 148 if (!fw.chip)
146 return -ENOENT; 149 return -ENOENT;
@@ -154,13 +157,18 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
154 if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) 157 if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
155 return -EINVAL; 158 return -EINVAL;
156 159
157 if (!size || size > bsize) 160 if (size > bsize)
158 return -EINVAL; 161 return -EINVAL;
159 162
163 ret = size;
164
165 if (!size)
166 size = bsize;
167
160 if (buffer) 168 if (buffer)
161 memcpy(buffer, fw.sm_shmem_out_base, size); 169 memcpy(buffer, fw.sm_shmem_out_base, size);
162 170
163 return size; 171 return ret;
164} 172}
165EXPORT_SYMBOL(meson_sm_call_read); 173EXPORT_SYMBOL(meson_sm_call_read);
166 174