1313#include <linux/io.h>
1414#include <linux/module.h>
1515#include <linux/of.h>
16- #include <linux/of_device .h>
16+ #include <linux/of_platform .h>
1717#include <linux/platform_device.h>
1818#include <linux/printk.h>
19+ #include <linux/property.h>
1920#include <linux/types.h>
2021#include <linux/sizes.h>
2122 #include <linux/slab.h>
@@ -67,7 +68,7 @@ static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
6768 return cmd -> smc_id ;
6869}
6970
70- static u32 __meson_sm_call (u32 cmd , u32 arg0 , u32 arg1 , u32 arg2 ,
71+ static s32 __meson_sm_call (u32 cmd , u32 arg0 , u32 arg1 , u32 arg2 ,
7172 u32 arg3 , u32 arg4 )
7273{
7374 struct arm_smccc_res res ;
@@ -102,9 +103,10 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
102103 * Return: 0 on success, a negative value on error
103104 */
104105int meson_sm_call (struct meson_sm_firmware * fw , unsigned int cmd_index ,
105- u32 * ret , u32 arg0 , u32 arg1 , u32 arg2 , u32 arg3 , u32 arg4 )
106+ s32 * ret , u32 arg0 , u32 arg1 , u32 arg2 , u32 arg3 , u32 arg4 )
106107{
107- u32 cmd , lret ;
108+ u32 cmd ;
109+ s32 lret ;
108110
109111 if (!fw -> chip )
110112 return - ENOENT ;
@@ -143,7 +145,7 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
143145 unsigned int bsize , unsigned int cmd_index , u32 arg0 ,
144146 u32 arg1 , u32 arg2 , u32 arg3 , u32 arg4 )
145147{
146- u32 size ;
148+ s32 size ;
147149 int ret ;
148150
149151 if (!fw -> chip )
@@ -158,11 +160,16 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
158160 if (meson_sm_call (fw , cmd_index , & size , arg0 , arg1 , arg2 , arg3 , arg4 ) < 0 )
159161 return - EINVAL ;
160162
161- if (size > bsize )
163+ if (size < 0 || size > bsize )
162164 return - EINVAL ;
163165
164166 ret = size ;
165167
168+ /* In some cases (for example GET_CHIP_ID command),
169+ * SMC doesn't return the number of bytes read, even
170+ * though the bytes were actually read into sm_shmem_out.
171+ * So this check is needed.
172+ */
166173 if (!size )
167174 size = bsize ;
168175
@@ -192,7 +199,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
192199 unsigned int size , unsigned int cmd_index , u32 arg0 ,
193200 u32 arg1 , u32 arg2 , u32 arg3 , u32 arg4 )
194201{
195- u32 written ;
202+ s32 written ;
196203
197204 if (!fw -> chip )
198205 return - ENOENT ;
@@ -208,7 +215,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
208215 if (meson_sm_call (fw , cmd_index , & written , arg0 , arg1 , arg2 , arg3 , arg4 ) < 0 )
209216 return - EINVAL ;
210217
211- if (! written )
218+ if (written <= 0 || written > size )
212219 return - EINVAL ;
213220
214221 return written ;
@@ -291,7 +298,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
291298 if (!fw )
292299 return - ENOMEM ;
293300
294- chip = of_match_device ( meson_sm_ids , dev )-> data ;
301+ chip = device_get_match_data ( dev );
295302 if (!chip )
296303 return - EINVAL ;
297304
0 commit comments