summaryrefslogtreecommitdiff
path: root/drivers/firmware/meson/meson_sm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 14:46:51 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 14:46:51 -1000
commit385903a7ec75bb400f4bf0f07d8d5ad61390270d (patch)
treef6510ea86effc389da264871b6ecb6af6c77d679 /drivers/firmware/meson/meson_sm.c
parentc035f0268b87fc21f517f638b3bad26c81babc85 (diff)
parentdfae947836d867e127e2b64f981ebb299c28f0dc (diff)
Merge tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull SoC driver updates from Arnd Bergmann: "The highlights for the driver support this time are - Qualcomm platforms gain support for the Qualcomm Secure Execution Environment firmware interface to access EFI variables on certain devices, and new features for multiple platform and firmware drivers. - Arm FF-A firmware support gains support for v1.1 specification features, in particular notification and memory transaction descriptor changes. - SCMI firmware support now support v3.2 features for clock and DVFS configuration and a new transport for Qualcomm platforms. - Minor cleanups and bugfixes are added to pretty much all the active platforms: qualcomm, broadcom, dove, ti-k3, rockchip, sifive, amlogic, atmel, tegra, aspeed, vexpress, mediatek, samsung and more. In particular, this contains portions of the treewide conversion to use __counted_by annotations and the device_get_match_data helper" * tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (156 commits) soc: qcom: pmic_glink_altmode: Print return value on error firmware: qcom: scm: remove unneeded 'extern' specifiers firmware: qcom: scm: add a missing forward declaration for struct device firmware: qcom: move Qualcomm code into its own directory soc: samsung: exynos-chipid: Convert to platform remove callback returning void soc: qcom: apr: Add __counted_by for struct apr_rx_buf and use struct_size() soc: qcom: pmic_glink: fix connector type to be DisplayPort soc: ti: k3-socinfo: Avoid overriding return value soc: ti: k3-socinfo: Fix typo in bitfield documentation soc: ti: knav_qmss_queue: Use device_get_match_data() firmware: ti_sci: Use device_get_match_data() firmware: qcom: qseecom: add missing include guards soc/pxa: ssp: Convert to platform remove callback returning void soc/mediatek: mtk-mmsys: Convert to platform remove callback returning void soc/mediatek: mtk-devapc: Convert to platform remove callback returning void soc/loongson: loongson2_guts: Convert to platform remove callback returning void soc/litex: litex_soc_ctrl: Convert to platform remove callback returning void soc/ixp4xx: ixp4xx-qmgr: Convert to platform remove callback returning void soc/ixp4xx: ixp4xx-npe: Convert to platform remove callback returning void soc/hisilicon: kunpeng_hccs: Convert to platform remove callback returning void ...
Diffstat (limited to 'drivers/firmware/meson/meson_sm.c')
-rw-r--r--drivers/firmware/meson/meson_sm.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 9a2656d73600..ed60f1103053 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -13,9 +13,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/sizes.h>
#include <linux/slab.h>
@@ -67,7 +68,7 @@ static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
return cmd->smc_id;
}
-static u32 __meson_sm_call(u32 cmd, u32 arg0, u32 arg1, u32 arg2,
+static s32 __meson_sm_call(u32 cmd, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 arg4)
{
struct arm_smccc_res res;
@@ -102,9 +103,10 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
* Return: 0 on success, a negative value on error
*/
int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
- u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ s32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 cmd, lret;
+ u32 cmd;
+ s32 lret;
if (!fw->chip)
return -ENOENT;
@@ -143,7 +145,7 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
unsigned int bsize, unsigned int cmd_index, u32 arg0,
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 size;
+ s32 size;
int ret;
if (!fw->chip)
@@ -158,11 +160,16 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
- if (size > bsize)
+ if (size < 0 || size > bsize)
return -EINVAL;
ret = size;
+ /* In some cases (for example GET_CHIP_ID command),
+ * SMC doesn't return the number of bytes read, even
+ * though the bytes were actually read into sm_shmem_out.
+ * So this check is needed.
+ */
if (!size)
size = bsize;
@@ -192,7 +199,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
unsigned int size, unsigned int cmd_index, u32 arg0,
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
- u32 written;
+ s32 written;
if (!fw->chip)
return -ENOENT;
@@ -208,7 +215,7 @@ int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
- if (!written)
+ if (written <= 0 || written > size)
return -EINVAL;
return written;
@@ -291,7 +298,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
if (!fw)
return -ENOMEM;
- chip = of_match_device(meson_sm_ids, dev)->data;
+ chip = device_get_match_data(dev);
if (!chip)
return -EINVAL;