SSI-87: firmware: imx: scu: Support reception of any size message
The implementation was limiting the size of a message which can be received to 4 but soem response can be bigger. For example the response of the 'sc_seco_secvio_config' API is 6 words. This patch removes this limitation relying on the count of word received instead of the index of the chan. It does so by duplicating imx_scu_call_rpc as imx_scu_call_big_rpc in order to cahnge the RX method using imx_scu_big_rx_callback instead of imx_scu_rx_callback. Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>5.4-rM2-2.2.x-imx-squashed
parent
ec19a7176f
commit
ccf07c0822
|
@ -138,6 +138,29 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
|
|||
complete(&sc_ipc->done);
|
||||
}
|
||||
|
||||
static void imx_scu_big_rx_callback(struct mbox_client *c, void *msg)
|
||||
{
|
||||
struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl);
|
||||
struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc;
|
||||
struct imx_sc_rpc_msg *hdr;
|
||||
u32 *data = msg;
|
||||
|
||||
if (sc_ipc->count == 0) {
|
||||
hdr = msg;
|
||||
sc_ipc->rx_size = hdr->size;
|
||||
dev_dbg(sc_ipc->dev, "msg rx size %u\n", sc_ipc->rx_size);
|
||||
}
|
||||
|
||||
sc_ipc->msg[sc_ipc->count] = *data;
|
||||
sc_ipc->count++;
|
||||
|
||||
dev_dbg(sc_ipc->dev, "mu %u msg %u 0x%x\n", sc_chan->idx,
|
||||
sc_ipc->count, *data);
|
||||
|
||||
if (sc_ipc->count == sc_ipc->rx_size)
|
||||
complete(&sc_ipc->done);
|
||||
}
|
||||
|
||||
static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
|
||||
{
|
||||
struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg;
|
||||
|
@ -232,6 +255,71 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(imx_scu_call_rpc);
|
||||
|
||||
int imx_scu_call_big_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
|
||||
{
|
||||
struct imx_sc_rpc_msg *hdr;
|
||||
struct arm_smccc_res res;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (WARN_ON(!sc_ipc || !msg))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&sc_ipc->lock);
|
||||
for (i = 4; i < 8; i++) {
|
||||
struct mbox_client *cl = &sc_ipc->chans[i].cl;
|
||||
|
||||
cl->rx_callback = imx_scu_big_rx_callback;
|
||||
}
|
||||
|
||||
reinit_completion(&sc_ipc->done);
|
||||
|
||||
sc_ipc->msg = msg;
|
||||
sc_ipc->count = 0;
|
||||
sc_ipc->rx_size = 0;
|
||||
if (xen_initial_domain()) {
|
||||
arm_smccc_hvc(FSL_HVC_SC, (uint64_t)msg, !have_resp, 0, 0, 0,
|
||||
0, 0, &res);
|
||||
if (res.a0)
|
||||
printk("Error FSL_HVC_SC %ld\n", res.a0);
|
||||
|
||||
ret = res.a0;
|
||||
|
||||
} else {
|
||||
ret = imx_scu_ipc_write(sc_ipc, msg);
|
||||
if (ret < 0) {
|
||||
dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (have_resp) {
|
||||
if (!wait_for_completion_timeout(&sc_ipc->done,
|
||||
MAX_RX_TIMEOUT)) {
|
||||
dev_err(sc_ipc->dev, "RPC send msg timeout\n");
|
||||
mutex_unlock(&sc_ipc->lock);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* response status is stored in hdr->func field */
|
||||
hdr = msg;
|
||||
ret = hdr->func;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
for (i = 4; i < 8; i++) {
|
||||
struct mbox_client *cl = &sc_ipc->chans[i].cl;
|
||||
|
||||
cl->rx_callback = imx_scu_rx_callback;
|
||||
}
|
||||
mutex_unlock(&sc_ipc->lock);
|
||||
|
||||
dev_dbg(sc_ipc->dev, "RPC SVC done\n");
|
||||
|
||||
return imx_sc_to_linux_errno(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(imx_scu_call_big_rpc);
|
||||
|
||||
static int imx_scu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
|
@ -48,6 +48,8 @@ struct imx_sc_rpc_msg {
|
|||
* and returns the result in msg.
|
||||
*/
|
||||
int imx_scu_call_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp);
|
||||
int imx_scu_call_big_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp);
|
||||
|
||||
|
||||
/*
|
||||
* This function gets the default ipc handle used by SCU
|
||||
|
@ -65,6 +67,13 @@ imx_scu_call_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp)
|
|||
|
||||
}
|
||||
|
||||
static inline int
|
||||
imx_scu_call_big_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp)
|
||||
{
|
||||
return -EIO;
|
||||
|
||||
}
|
||||
|
||||
static inline int imx_scu_get_handle(struct imx_sc_ipc **ipc)
|
||||
{
|
||||
return -EIO;
|
||||
|
|
Loading…
Reference in New Issue