Lines Matching +full:ch +full:- +full:func

1 // SPDX-License-Identifier: GPL-2.0+
29 struct mbox_chan *ch; member
69 -EINVAL, /* IMX_SC_ERR_VERSION */
70 -EINVAL, /* IMX_SC_ERR_CONFIG */
71 -EINVAL, /* IMX_SC_ERR_PARM */
72 -EACCES, /* IMX_SC_ERR_NOACCESS */
73 -EACCES, /* IMX_SC_ERR_LOCKED */
74 -ERANGE, /* IMX_SC_ERR_UNAVAILABLE */
75 -EEXIST, /* IMX_SC_ERR_NOTFOUND */
76 -EPERM, /* IMX_SC_ERR_NOPOWER */
77 -EPIPE, /* IMX_SC_ERR_IPC */
78 -EBUSY, /* IMX_SC_ERR_BUSY */
79 -EIO, /* IMX_SC_ERR_FAIL */
88 return -EIO; in imx_sc_to_linux_errno()
97 return -EPROBE_DEFER; in imx_scu_get_handle()
104 /* Callback called when the word of a message is ack-ed, eg read by SCU */
109 complete(&sc_chan->tx_done); in imx_scu_tx_done()
115 struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc; in imx_scu_rx_callback()
120 if (!sc_ipc->msg) { in imx_scu_rx_callback()
121 dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n", in imx_scu_rx_callback()
122 sc_chan->idx, *data); in imx_scu_rx_callback()
126 if (sc_ipc->fast_ipc) { in imx_scu_rx_callback()
128 sc_ipc->rx_size = hdr->size; in imx_scu_rx_callback()
129 sc_ipc->msg[0] = *data++; in imx_scu_rx_callback()
131 for (i = 1; i < sc_ipc->rx_size; i++) in imx_scu_rx_callback()
132 sc_ipc->msg[i] = *data++; in imx_scu_rx_callback()
134 complete(&sc_ipc->done); in imx_scu_rx_callback()
139 if (sc_chan->idx == 0) { in imx_scu_rx_callback()
141 sc_ipc->rx_size = hdr->size; in imx_scu_rx_callback()
142 dev_dbg(sc_ipc->dev, "msg rx size %u\n", sc_ipc->rx_size); in imx_scu_rx_callback()
143 if (sc_ipc->rx_size > 4) in imx_scu_rx_callback()
144 dev_warn(sc_ipc->dev, "RPC does not support receiving over 4 words: %u\n", in imx_scu_rx_callback()
145 sc_ipc->rx_size); in imx_scu_rx_callback()
148 sc_ipc->msg[sc_chan->idx] = *data; in imx_scu_rx_callback()
149 sc_ipc->count++; in imx_scu_rx_callback()
151 dev_dbg(sc_ipc->dev, "mu %u msg %u 0x%x\n", sc_chan->idx, in imx_scu_rx_callback()
152 sc_ipc->count, *data); in imx_scu_rx_callback()
154 if ((sc_ipc->rx_size != 0) && (sc_ipc->count == sc_ipc->rx_size)) in imx_scu_rx_callback()
155 complete(&sc_ipc->done); in imx_scu_rx_callback()
169 return -EINVAL; in imx_scu_ipc_write()
171 dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc, in imx_scu_ipc_write()
172 hdr.func, hdr.size); in imx_scu_ipc_write()
174 size = sc_ipc->fast_ipc ? 1 : hdr.size; in imx_scu_ipc_write()
176 sc_chan = &sc_ipc->chans[i % 4]; in imx_scu_ipc_write()
187 if (!sc_ipc->fast_ipc) { in imx_scu_ipc_write()
188 wait_for_completion(&sc_chan->tx_done); in imx_scu_ipc_write()
189 reinit_completion(&sc_chan->tx_done); in imx_scu_ipc_write()
192 ret = mbox_send_message(sc_chan->ch, &data[i]); in imx_scu_ipc_write()
210 return -EINVAL; in imx_scu_call_rpc()
212 mutex_lock(&sc_ipc->lock); in imx_scu_call_rpc()
213 reinit_completion(&sc_ipc->done); in imx_scu_call_rpc()
216 sc_ipc->msg = msg; in imx_scu_call_rpc()
217 saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc; in imx_scu_call_rpc()
218 saved_func = ((struct imx_sc_rpc_msg *)msg)->func; in imx_scu_call_rpc()
220 sc_ipc->count = 0; in imx_scu_call_rpc()
223 dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret); in imx_scu_call_rpc()
228 if (!wait_for_completion_timeout(&sc_ipc->done, in imx_scu_call_rpc()
230 dev_err(sc_ipc->dev, "RPC send msg timeout\n"); in imx_scu_call_rpc()
231 mutex_unlock(&sc_ipc->lock); in imx_scu_call_rpc()
232 return -ETIMEDOUT; in imx_scu_call_rpc()
235 /* response status is stored in hdr->func field */ in imx_scu_call_rpc()
237 ret = hdr->func; in imx_scu_call_rpc()
240 * in hdr->func, but they do have response data, those special in imx_scu_call_rpc()
251 sc_ipc->msg = NULL; in imx_scu_call_rpc()
252 mutex_unlock(&sc_ipc->lock); in imx_scu_call_rpc()
254 dev_dbg(sc_ipc->dev, "RPC SVC done\n"); in imx_scu_call_rpc()
262 struct device *dev = &pdev->dev; in imx_scu_probe()
274 return -ENOMEM; in imx_scu_probe()
276 ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes", in imx_scu_probe()
277 "#mbox-cells", 0, &args); in imx_scu_probe()
281 sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu"); in imx_scu_probe()
283 num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM; in imx_scu_probe()
289 i - num_channel / 2); in imx_scu_probe()
292 return -ENOMEM; in imx_scu_probe()
294 sc_chan = &sc_ipc->chans[i]; in imx_scu_probe()
295 cl = &sc_chan->cl; in imx_scu_probe()
296 cl->dev = dev; in imx_scu_probe()
297 cl->tx_block = false; in imx_scu_probe()
298 cl->knows_txdone = true; in imx_scu_probe()
299 cl->rx_callback = imx_scu_rx_callback; in imx_scu_probe()
301 if (!sc_ipc->fast_ipc) { in imx_scu_probe()
303 cl->tx_done = imx_scu_tx_done; in imx_scu_probe()
304 init_completion(&sc_chan->tx_done); in imx_scu_probe()
305 complete(&sc_chan->tx_done); in imx_scu_probe()
308 sc_chan->sc_ipc = sc_ipc; in imx_scu_probe()
309 sc_chan->idx = i % (num_channel / 2); in imx_scu_probe()
310 sc_chan->ch = mbox_request_channel_byname(cl, chan_name); in imx_scu_probe()
311 if (IS_ERR(sc_chan->ch)) { in imx_scu_probe()
312 ret = PTR_ERR(sc_chan->ch); in imx_scu_probe()
313 if (ret != -EPROBE_DEFER) in imx_scu_probe()
325 sc_ipc->dev = dev; in imx_scu_probe()
326 mutex_init(&sc_ipc->lock); in imx_scu_probe()
327 init_completion(&sc_ipc->done); in imx_scu_probe()
346 { .compatible = "fsl,imx-scu", },
352 .name = "imx-scu",