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

1 // SPDX-License-Identifier: GPL-2.0+
30 struct mbox_chan *ch; member
70 -EINVAL, /* IMX_SC_ERR_VERSION */
71 -EINVAL, /* IMX_SC_ERR_CONFIG */
72 -EINVAL, /* IMX_SC_ERR_PARM */
73 -EACCES, /* IMX_SC_ERR_NOACCESS */
74 -EACCES, /* IMX_SC_ERR_LOCKED */
75 -ERANGE, /* IMX_SC_ERR_UNAVAILABLE */
76 -EEXIST, /* IMX_SC_ERR_NOTFOUND */
77 -EPERM, /* IMX_SC_ERR_NOPOWER */
78 -EPIPE, /* IMX_SC_ERR_IPC */
79 -EBUSY, /* IMX_SC_ERR_BUSY */
80 -EIO, /* IMX_SC_ERR_FAIL */
89 return -EIO; in imx_sc_to_linux_errno()
98 return -EPROBE_DEFER; in imx_scu_get_handle()
105 /* Callback called when the word of a message is ack-ed, eg read by SCU */
110 complete(&sc_chan->tx_done); in imx_scu_tx_done()
116 struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc; in imx_scu_rx_callback()
121 if (!sc_ipc->msg) { in imx_scu_rx_callback()
122 dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n", in imx_scu_rx_callback()
123 sc_chan->idx, *data); in imx_scu_rx_callback()
127 if (sc_ipc->fast_ipc) { in imx_scu_rx_callback()
129 sc_ipc->rx_size = hdr->size; in imx_scu_rx_callback()
130 sc_ipc->msg[0] = *data++; in imx_scu_rx_callback()
132 for (i = 1; i < sc_ipc->rx_size; i++) in imx_scu_rx_callback()
133 sc_ipc->msg[i] = *data++; in imx_scu_rx_callback()
135 complete(&sc_ipc->done); in imx_scu_rx_callback()
140 if (sc_chan->idx == 0) { in imx_scu_rx_callback()
142 sc_ipc->rx_size = hdr->size; in imx_scu_rx_callback()
143 dev_dbg(sc_ipc->dev, "msg rx size %u\n", sc_ipc->rx_size); in imx_scu_rx_callback()
144 if (sc_ipc->rx_size > 4) in imx_scu_rx_callback()
145 dev_warn(sc_ipc->dev, "RPC does not support receiving over 4 words: %u\n", in imx_scu_rx_callback()
146 sc_ipc->rx_size); in imx_scu_rx_callback()
149 sc_ipc->msg[sc_chan->idx] = *data; in imx_scu_rx_callback()
150 sc_ipc->count++; in imx_scu_rx_callback()
152 dev_dbg(sc_ipc->dev, "mu %u msg %u 0x%x\n", sc_chan->idx, in imx_scu_rx_callback()
153 sc_ipc->count, *data); in imx_scu_rx_callback()
155 if ((sc_ipc->rx_size != 0) && (sc_ipc->count == sc_ipc->rx_size)) in imx_scu_rx_callback()
156 complete(&sc_ipc->done); in imx_scu_rx_callback()
170 return -EINVAL; in imx_scu_ipc_write()
172 dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc, in imx_scu_ipc_write()
173 hdr.func, hdr.size); in imx_scu_ipc_write()
175 size = sc_ipc->fast_ipc ? 1 : hdr.size; in imx_scu_ipc_write()
177 sc_chan = &sc_ipc->chans[i % 4]; in imx_scu_ipc_write()
188 if (!sc_ipc->fast_ipc) { in imx_scu_ipc_write()
189 wait_for_completion(&sc_chan->tx_done); in imx_scu_ipc_write()
190 reinit_completion(&sc_chan->tx_done); in imx_scu_ipc_write()
193 ret = mbox_send_message(sc_chan->ch, &data[i]); in imx_scu_ipc_write()
211 return -EINVAL; in imx_scu_call_rpc()
213 mutex_lock(&sc_ipc->lock); in imx_scu_call_rpc()
214 reinit_completion(&sc_ipc->done); in imx_scu_call_rpc()
217 sc_ipc->msg = msg; in imx_scu_call_rpc()
218 saved_svc = ((struct imx_sc_rpc_msg *)msg)->svc; in imx_scu_call_rpc()
219 saved_func = ((struct imx_sc_rpc_msg *)msg)->func; in imx_scu_call_rpc()
221 sc_ipc->count = 0; in imx_scu_call_rpc()
224 dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret); in imx_scu_call_rpc()
229 if (!wait_for_completion_timeout(&sc_ipc->done, in imx_scu_call_rpc()
231 dev_err(sc_ipc->dev, "RPC send msg timeout\n"); in imx_scu_call_rpc()
232 mutex_unlock(&sc_ipc->lock); in imx_scu_call_rpc()
233 return -ETIMEDOUT; in imx_scu_call_rpc()
236 /* response status is stored in hdr->func field */ in imx_scu_call_rpc()
238 ret = hdr->func; in imx_scu_call_rpc()
241 * in hdr->func, but they do have response data, those special in imx_scu_call_rpc()
252 sc_ipc->msg = NULL; in imx_scu_call_rpc()
253 mutex_unlock(&sc_ipc->lock); in imx_scu_call_rpc()
255 dev_dbg(sc_ipc->dev, "RPC SVC done\n"); in imx_scu_call_rpc()
263 struct device *dev = &pdev->dev; in imx_scu_probe()
275 return -ENOMEM; in imx_scu_probe()
277 ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes", in imx_scu_probe()
278 "#mbox-cells", 0, &args); in imx_scu_probe()
282 sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu"); in imx_scu_probe()
284 num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM; in imx_scu_probe()
290 i - num_channel / 2); in imx_scu_probe()
293 return -ENOMEM; in imx_scu_probe()
295 sc_chan = &sc_ipc->chans[i]; in imx_scu_probe()
296 cl = &sc_chan->cl; in imx_scu_probe()
297 cl->dev = dev; in imx_scu_probe()
298 cl->tx_block = false; in imx_scu_probe()
299 cl->knows_txdone = true; in imx_scu_probe()
300 cl->rx_callback = imx_scu_rx_callback; in imx_scu_probe()
302 if (!sc_ipc->fast_ipc) { in imx_scu_probe()
304 cl->tx_done = imx_scu_tx_done; in imx_scu_probe()
305 init_completion(&sc_chan->tx_done); in imx_scu_probe()
306 complete(&sc_chan->tx_done); in imx_scu_probe()
309 sc_chan->sc_ipc = sc_ipc; in imx_scu_probe()
310 sc_chan->idx = i % (num_channel / 2); in imx_scu_probe()
311 sc_chan->ch = mbox_request_channel_byname(cl, chan_name); in imx_scu_probe()
312 if (IS_ERR(sc_chan->ch)) { in imx_scu_probe()
313 ret = PTR_ERR(sc_chan->ch); 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",