summaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2019-11-06 16:46:02 +0100
committerOlof Johansson <olof@lixom.net>2019-11-06 16:46:03 +0100
commit8cbbff3a6423cc95fbd00c49da54952a87088d4f (patch)
tree30afb60484a8e795eb29714d68825fca9aaeae85 /drivers/firmware
parentMerge tag 'samsung-drivers-5.5' of https://git.kernel.org/pub/scm/linux/kerne... (diff)
parentsoc: imx8mq: Read SOC revision from TF-A (diff)
downloadlinux-8cbbff3a6423cc95fbd00c49da54952a87088d4f.tar.xz
linux-8cbbff3a6423cc95fbd00c49da54952a87088d4f.zip
Merge tag 'imx-drivers-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers
i.MX drivers update for 5.5: - Skip return check for those SCU firmware APIs that are defined as void function in firmware. - Use established serial_number attribute instead of custom one to show SoC's unique ID for i.MX8 SoC drivers. - Read i.MX8MQ SOC revision from TF-A which parses ROM and exposes the value through a SMC call. This improves the situation that SOC revision reports 'unknown' on some older revisions. - Add a check and warn on unexpected SCU RX to avoid potential stack corruption in imx-scu driver. - Fix a sparse warning in imx-scu-irq driver by adding missing header. - Remove an unneeded call to devm_of_platform_populate() from imx-dsp driver. * tag 'imx-drivers-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: soc: imx8mq: Read SOC revision from TF-A soc: imx-scu: Using existing serial_number instead of UID soc: imx8: Using existing serial_number instead of UID firmware: imx: add missing include of <linux/firmware/imx/sci.h> firmware: imx: Remove call to devm_of_platform_populate firmware: imx: Skip return value check for some special SCU firmware APIs firmware: imx: warn on unexpected RX Link: https://lore.kernel.org/r/20191105150315.15477-1-shawnguo@kernel.org Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/imx/imx-dsp.c2
-rw-r--r--drivers/firmware/imx/imx-scu-irq.c1
-rw-r--r--drivers/firmware/imx/imx-scu.c24
3 files changed, 25 insertions, 2 deletions
diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c
index a43d2db5cbdb..4265e9dbed84 100644
--- a/drivers/firmware/imx/imx-dsp.c
+++ b/drivers/firmware/imx/imx-dsp.c
@@ -114,7 +114,7 @@ static int imx_dsp_probe(struct platform_device *pdev)
dev_info(dev, "NXP i.MX DSP IPC initialized\n");
- return devm_of_platform_populate(dev);
+ return 0;
out:
kfree(chan_name);
for (j = 0; j < i; j++) {
diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c
index 687121f8c4d5..db655e87cdc8 100644
--- a/drivers/firmware/imx/imx-scu-irq.c
+++ b/drivers/firmware/imx/imx-scu-irq.c
@@ -8,6 +8,7 @@
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/sci.h>
#include <linux/mailbox_client.h>
#define IMX_SC_IRQ_FUNC_ENABLE 1
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index 04a24a863d6e..03b43b7a6d1d 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -107,6 +107,12 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
struct imx_sc_rpc_msg *hdr;
u32 *data = msg;
+ if (!sc_ipc->msg) {
+ dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n",
+ sc_chan->idx, *data);
+ return;
+ }
+
if (sc_chan->idx == 0) {
hdr = msg;
sc_ipc->rx_size = hdr->size;
@@ -156,6 +162,7 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
*/
int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
{
+ uint8_t saved_svc, saved_func;
struct imx_sc_rpc_msg *hdr;
int ret;
@@ -165,7 +172,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
mutex_lock(&sc_ipc->lock);
reinit_completion(&sc_ipc->done);
- sc_ipc->msg = msg;
+ if (have_resp) {
+ sc_ipc->msg = msg;
+ saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc;
+ saved_func = ((struct imx_sc_rpc_msg *)msg)->func;
+ }
sc_ipc->count = 0;
ret = imx_scu_ipc_write(sc_ipc, msg);
if (ret < 0) {
@@ -184,9 +195,20 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
/* response status is stored in hdr->func field */
hdr = msg;
ret = hdr->func;
+ /*
+ * Some special SCU firmware APIs do NOT have return value
+ * in hdr->func, but they do have response data, those special
+ * APIs are defined as void function in SCU firmware, so they
+ * should be treated as return success always.
+ */
+ if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
+ (saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
+ saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
+ ret = 0;
}
out:
+ sc_ipc->msg = NULL;
mutex_unlock(&sc_ipc->lock);
dev_dbg(sc_ipc->dev, "RPC SVC done\n");