]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.7
authorSasha Levin <sashal@kernel.org>
Tue, 16 Jun 2020 01:55:37 +0000 (21:55 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 16 Jun 2020 01:55:37 +0000 (21:55 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.7/firmware-imx-scu-fix-corruption-of-header.patch [new file with mode: 0644]
queue-5.7/firmware-imx-scu-support-one-tx-and-one-rx.patch [new file with mode: 0644]
queue-5.7/series

diff --git a/queue-5.7/firmware-imx-scu-fix-corruption-of-header.patch b/queue-5.7/firmware-imx-scu-fix-corruption-of-header.patch
new file mode 100644 (file)
index 0000000..b3945e6
--- /dev/null
@@ -0,0 +1,72 @@
+From a44ad90221a4368d06e0f717ac44a12423df8542 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 00:00:05 +0200
+Subject: firmware: imx: scu: Fix corruption of header
+
+From: Franck LENORMAND <franck.lenormand@nxp.com>
+
+[ Upstream commit f5f27b79eab80de0287c243a22169e4876b08d5e ]
+
+The header of the message to send can be changed if the
+response is longer than the request:
+ - 1st word, the header is sent
+ - the remaining words of the message are sent
+ - the response is received asynchronously during the
+   execution of the loop, changing the size field in
+   the header
+ - the for loop test the termination condition using
+   the corrupted header
+
+It is the case for the API build_info which has just a
+header as request but 3 words in response.
+
+This issue is fixed storing the header locally instead of
+using a pointer on it.
+
+Fixes: edbee095fafb (firmware: imx: add SCU firmware driver support)
+
+Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
+Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
+Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/imx/imx-scu.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
+index e94a5585b698..b3da2e193ad2 100644
+--- a/drivers/firmware/imx/imx-scu.c
++++ b/drivers/firmware/imx/imx-scu.c
+@@ -158,7 +158,7 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
+ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+ {
+-      struct imx_sc_rpc_msg *hdr = msg;
++      struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg;
+       struct imx_sc_chan *sc_chan;
+       u32 *data = msg;
+       int ret;
+@@ -166,13 +166,13 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+       int i;
+       /* Check size */
+-      if (hdr->size > IMX_SC_RPC_MAX_MSG)
++      if (hdr.size > IMX_SC_RPC_MAX_MSG)
+               return -EINVAL;
+-      dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc,
+-              hdr->func, hdr->size);
++      dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc,
++              hdr.func, hdr.size);
+-      size = sc_ipc->fast_ipc ? 1 : hdr->size;
++      size = sc_ipc->fast_ipc ? 1 : hdr.size;
+       for (i = 0; i < size; i++) {
+               sc_chan = &sc_ipc->chans[i % 4];
+-- 
+2.25.1
+
diff --git a/queue-5.7/firmware-imx-scu-support-one-tx-and-one-rx.patch b/queue-5.7/firmware-imx-scu-support-one-tx-and-one-rx.patch
new file mode 100644 (file)
index 0000000..c6e775b
--- /dev/null
@@ -0,0 +1,151 @@
+From 3eadacdc54b15378177fe5060162b690023c20e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Mar 2020 15:49:53 +0800
+Subject: firmware: imx-scu: Support one TX and one RX
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f25a066d1a07affb7bea4e5d9c179c3338338e23 ]
+
+Current imx-scu requires four TX and four RX to communicate with
+SCU. This is low efficient and causes lots of mailbox interrupts.
+
+With imx-mailbox driver could support one TX to use all four transmit
+registers and one RX to use all four receive registers, imx-scu
+could use one TX and one RX.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/imx/imx-scu.c | 54 +++++++++++++++++++++++++++-------
+ 1 file changed, 43 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
+index f71eaa5bf52d..e94a5585b698 100644
+--- a/drivers/firmware/imx/imx-scu.c
++++ b/drivers/firmware/imx/imx-scu.c
+@@ -38,6 +38,7 @@ struct imx_sc_ipc {
+       struct device *dev;
+       struct mutex lock;
+       struct completion done;
++      bool fast_ipc;
+       /* temporarily store the SCU msg */
+       u32 *msg;
+@@ -115,6 +116,7 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
+       struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc;
+       struct imx_sc_rpc_msg *hdr;
+       u32 *data = msg;
++      int i;
+       if (!sc_ipc->msg) {
+               dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n",
+@@ -122,6 +124,19 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
+               return;
+       }
++      if (sc_ipc->fast_ipc) {
++              hdr = msg;
++              sc_ipc->rx_size = hdr->size;
++              sc_ipc->msg[0] = *data++;
++
++              for (i = 1; i < sc_ipc->rx_size; i++)
++                      sc_ipc->msg[i] = *data++;
++
++              complete(&sc_ipc->done);
++
++              return;
++      }
++
+       if (sc_chan->idx == 0) {
+               hdr = msg;
+               sc_ipc->rx_size = hdr->size;
+@@ -147,6 +162,7 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+       struct imx_sc_chan *sc_chan;
+       u32 *data = msg;
+       int ret;
++      int size;
+       int i;
+       /* Check size */
+@@ -156,7 +172,8 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+       dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc,
+               hdr->func, hdr->size);
+-      for (i = 0; i < hdr->size; i++) {
++      size = sc_ipc->fast_ipc ? 1 : hdr->size;
++      for (i = 0; i < size; i++) {
+               sc_chan = &sc_ipc->chans[i % 4];
+               /*
+@@ -168,8 +185,10 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+                * Wait for tx_done before every send to ensure that no
+                * queueing happens at the mailbox channel level.
+                */
+-              wait_for_completion(&sc_chan->tx_done);
+-              reinit_completion(&sc_chan->tx_done);
++              if (!sc_ipc->fast_ipc) {
++                      wait_for_completion(&sc_chan->tx_done);
++                      reinit_completion(&sc_chan->tx_done);
++              }
+               ret = mbox_send_message(sc_chan->ch, &data[i]);
+               if (ret < 0)
+@@ -246,6 +265,8 @@ static int imx_scu_probe(struct platform_device *pdev)
+       struct imx_sc_chan *sc_chan;
+       struct mbox_client *cl;
+       char *chan_name;
++      struct of_phandle_args args;
++      int num_channel;
+       int ret;
+       int i;
+@@ -253,11 +274,20 @@ static int imx_scu_probe(struct platform_device *pdev)
+       if (!sc_ipc)
+               return -ENOMEM;
+-      for (i = 0; i < SCU_MU_CHAN_NUM; i++) {
+-              if (i < 4)
++      ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes",
++                                       "#mbox-cells", 0, &args);
++      if (ret)
++              return ret;
++
++      sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu");
++
++      num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM;
++      for (i = 0; i < num_channel; i++) {
++              if (i < num_channel / 2)
+                       chan_name = kasprintf(GFP_KERNEL, "tx%d", i);
+               else
+-                      chan_name = kasprintf(GFP_KERNEL, "rx%d", i - 4);
++                      chan_name = kasprintf(GFP_KERNEL, "rx%d",
++                                            i - num_channel / 2);
+               if (!chan_name)
+                       return -ENOMEM;
+@@ -269,13 +299,15 @@ static int imx_scu_probe(struct platform_device *pdev)
+               cl->knows_txdone = true;
+               cl->rx_callback = imx_scu_rx_callback;
+-              /* Initial tx_done completion as "done" */
+-              cl->tx_done = imx_scu_tx_done;
+-              init_completion(&sc_chan->tx_done);
+-              complete(&sc_chan->tx_done);
++              if (!sc_ipc->fast_ipc) {
++                      /* Initial tx_done completion as "done" */
++                      cl->tx_done = imx_scu_tx_done;
++                      init_completion(&sc_chan->tx_done);
++                      complete(&sc_chan->tx_done);
++              }
+               sc_chan->sc_ipc = sc_ipc;
+-              sc_chan->idx = i % 4;
++              sc_chan->idx = i % (num_channel / 2);
+               sc_chan->ch = mbox_request_channel_byname(cl, chan_name);
+               if (IS_ERR(sc_chan->ch)) {
+                       ret = PTR_ERR(sc_chan->ch);
+-- 
+2.25.1
+
index ed8b82057b34ec5be3b145d1015cee8c3d184260..299a3cd27b785ad0b5dab06d1fd2df2cbd580b5a 100644 (file)
@@ -94,3 +94,5 @@ crypto-virtio-fix-dest-length-calculation-in-__virtio_crypto_skcipher_do_req.pat
 crypto-virtio-fix-use-after-free-in-virtio_crypto_skcipher_finalize_req.patch
 crypto-virtio-fix-src-dst-scatterlist-calculation-in-__virtio_crypto_skcipher_do_req.patch
 x86-mce-mm-unmap-the-entire-page-if-the-whole-page-is-affected-and-poisoned.patch
+firmware-imx-scu-support-one-tx-and-one-rx.patch
+firmware-imx-scu-fix-corruption-of-header.patch