xref: /linux/drivers/mailbox/zynqmp-ipi-mailbox.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Xilinx Inter Processor Interrupt(IPI) Mailbox Driver
4  *
5  * Copyright (C) 2018 Xilinx, Inc.
6  */
7 
8 #include <linux/arm-smccc.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/kernel.h>
14 #include <linux/mailbox_controller.h>
15 #include <linux/mailbox/zynqmp-ipi-message.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_address.h>
19 #include <linux/platform_device.h>
20 
21 /* IPI agent ID any */
22 #define IPI_ID_ANY 0xFFUL
23 
24 /* indicate if ZynqMP IPI mailbox driver uses SMC calls or HVC calls */
25 #define USE_SMC 0
26 #define USE_HVC 1
27 
28 /* Default IPI SMC function IDs */
29 #define SMC_IPI_MAILBOX_OPEN		0x82001000U
30 #define SMC_IPI_MAILBOX_RELEASE		0x82001001U
31 #define SMC_IPI_MAILBOX_STATUS_ENQUIRY	0x82001002U
32 #define SMC_IPI_MAILBOX_NOTIFY		0x82001003U
33 #define SMC_IPI_MAILBOX_ACK		0x82001004U
34 #define SMC_IPI_MAILBOX_ENABLE_IRQ	0x82001005U
35 #define SMC_IPI_MAILBOX_DISABLE_IRQ	0x82001006U
36 
37 /* IPI SMC Macros */
38 #define IPI_SMC_ENQUIRY_DIRQ_MASK	0x00000001UL /* Flag to indicate if
39 						      * notification interrupt
40 						      * to be disabled.
41 						      */
42 #define IPI_SMC_ACK_EIRQ_MASK		0x00000001UL /* Flag to indicate if
43 						      * notification interrupt
44 						      * to be enabled.
45 						      */
46 
47 /* IPI mailbox status */
48 #define IPI_MB_STATUS_IDLE		0
49 #define IPI_MB_STATUS_SEND_PENDING	1
50 #define IPI_MB_STATUS_RECV_PENDING	2
51 
52 #define IPI_MB_CHNL_TX	0 /* IPI mailbox TX channel */
53 #define IPI_MB_CHNL_RX	1 /* IPI mailbox RX channel */
54 
55 /**
56  * struct zynqmp_ipi_mchan - Description of a Xilinx ZynqMP IPI mailbox channel
57  * @is_opened: indicate if the IPI channel is opened
58  * @req_buf: local to remote request buffer start address
59  * @resp_buf: local to remote response buffer start address
60  * @req_buf_size: request buffer size
61  * @resp_buf_size: response buffer size
62  * @rx_buf: receive buffer to pass received message to client
63  * @chan_type: channel type
64  */
65 struct zynqmp_ipi_mchan {
66 	int is_opened;
67 	void __iomem *req_buf;
68 	void __iomem *resp_buf;
69 	void *rx_buf;
70 	size_t req_buf_size;
71 	size_t resp_buf_size;
72 	unsigned int chan_type;
73 };
74 
75 /**
76  * struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox
77  *                          platform data.
78  * @pdata:		  pointer to the IPI private data
79  * @dev:                  device pointer corresponding to the Xilinx ZynqMP
80  *                        IPI mailbox
81  * @remote_id:            remote IPI agent ID
82  * @mbox:                 mailbox Controller
83  * @mchans:               array for channels, tx channel and rx channel.
84  * @irq:                  IPI agent interrupt ID
85  */
86 struct zynqmp_ipi_mbox {
87 	struct zynqmp_ipi_pdata *pdata;
88 	struct device dev;
89 	u32 remote_id;
90 	struct mbox_controller mbox;
91 	struct zynqmp_ipi_mchan mchans[2];
92 };
93 
94 /**
95  * struct zynqmp_ipi_pdata - Description of z ZynqMP IPI agent platform data.
96  *
97  * @dev:                  device pointer corresponding to the Xilinx ZynqMP
98  *                        IPI agent
99  * @irq:                  IPI agent interrupt ID
100  * @method:               IPI SMC or HVC is going to be used
101  * @local_id:             local IPI agent ID
102  * @num_mboxes:           number of mailboxes of this IPI agent
103  * @ipi_mboxes:           IPI mailboxes of this IPI agent
104  */
105 struct zynqmp_ipi_pdata {
106 	struct device *dev;
107 	int irq;
108 	unsigned int method;
109 	u32 local_id;
110 	int num_mboxes;
111 	struct zynqmp_ipi_mbox ipi_mboxes[];
112 };
113 
114 static struct device_driver zynqmp_ipi_mbox_driver = {
115 	.owner = THIS_MODULE,
116 	.name = "zynqmp-ipi-mbox",
117 };
118 
119 static void zynqmp_ipi_fw_call(struct zynqmp_ipi_mbox *ipi_mbox,
120 			       unsigned long a0, unsigned long a3,
121 			       struct arm_smccc_res *res)
122 {
123 	struct zynqmp_ipi_pdata *pdata = ipi_mbox->pdata;
124 	unsigned long a1, a2;
125 
126 	a1 = pdata->local_id;
127 	a2 = ipi_mbox->remote_id;
128 	if (pdata->method == USE_SMC)
129 		arm_smccc_smc(a0, a1, a2, a3, 0, 0, 0, 0, res);
130 	else
131 		arm_smccc_hvc(a0, a1, a2, a3, 0, 0, 0, 0, res);
132 }
133 
134 /**
135  * zynqmp_ipi_interrupt - Interrupt handler for IPI notification
136  *
137  * @irq:  Interrupt number
138  * @data: ZynqMP IPI mailbox platform data.
139  *
140  * Return: -EINVAL if there is no instance
141  * IRQ_NONE if the interrupt is not ours.
142  * IRQ_HANDLED if the rx interrupt was successfully handled.
143  */
144 static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)
145 {
146 	struct zynqmp_ipi_pdata *pdata = data;
147 	struct mbox_chan *chan;
148 	struct zynqmp_ipi_mbox *ipi_mbox;
149 	struct zynqmp_ipi_mchan *mchan;
150 	struct zynqmp_ipi_message *msg;
151 	u64 arg0, arg3;
152 	struct arm_smccc_res res;
153 	int ret, i, status = IRQ_NONE;
154 
155 	(void)irq;
156 	arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
157 	arg3 = IPI_SMC_ENQUIRY_DIRQ_MASK;
158 	for (i = 0; i < pdata->num_mboxes; i++) {
159 		ipi_mbox = &pdata->ipi_mboxes[i];
160 		mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
161 		chan = &ipi_mbox->mbox.chans[IPI_MB_CHNL_RX];
162 		zynqmp_ipi_fw_call(ipi_mbox, arg0, arg3, &res);
163 		ret = (int)(res.a0 & 0xFFFFFFFF);
164 		if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {
165 			if (mchan->is_opened) {
166 				msg = mchan->rx_buf;
167 				msg->len = mchan->req_buf_size;
168 				memcpy_fromio(msg->data, mchan->req_buf,
169 					      msg->len);
170 				mbox_chan_received_data(chan, (void *)msg);
171 				status = IRQ_HANDLED;
172 			}
173 		}
174 	}
175 	return status;
176 }
177 
178 /**
179  * zynqmp_ipi_peek_data - Peek to see if there are any rx messages.
180  *
181  * @chan: Channel Pointer
182  *
183  * Return: 'true' if there is pending rx data, 'false' if there is none.
184  */
185 static bool zynqmp_ipi_peek_data(struct mbox_chan *chan)
186 {
187 	struct device *dev = chan->mbox->dev;
188 	struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
189 	struct zynqmp_ipi_mchan *mchan = chan->con_priv;
190 	int ret;
191 	u64 arg0;
192 	struct arm_smccc_res res;
193 
194 	if (WARN_ON(!ipi_mbox)) {
195 		dev_err(dev, "no platform drv data??\n");
196 		return false;
197 	}
198 
199 	arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
200 	zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
201 	ret = (int)(res.a0 & 0xFFFFFFFF);
202 
203 	if (mchan->chan_type == IPI_MB_CHNL_TX) {
204 		/* TX channel, check if the message has been acked
205 		 * by the remote, if yes, response is available.
206 		 */
207 		if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)
208 			return false;
209 		else
210 			return true;
211 	} else if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {
212 		/* RX channel, check if there is message arrived. */
213 		return true;
214 	}
215 	return false;
216 }
217 
218 /**
219  * zynqmp_ipi_last_tx_done - See if the last tx message is sent
220  *
221  * @chan: Channel pointer
222  *
223  * Return: 'true' is no pending tx data, 'false' if there are any.
224  */
225 static bool zynqmp_ipi_last_tx_done(struct mbox_chan *chan)
226 {
227 	struct device *dev = chan->mbox->dev;
228 	struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
229 	struct zynqmp_ipi_mchan *mchan = chan->con_priv;
230 	int ret;
231 	u64 arg0;
232 	struct arm_smccc_res res;
233 
234 	if (WARN_ON(!ipi_mbox)) {
235 		dev_err(dev, "no platform drv data??\n");
236 		return false;
237 	}
238 
239 	if (mchan->chan_type == IPI_MB_CHNL_TX) {
240 		/* We only need to check if the message been taken
241 		 * by the remote in the TX channel
242 		 */
243 		arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
244 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
245 		/* Check the SMC call status, a0 of the result */
246 		ret = (int)(res.a0 & 0xFFFFFFFF);
247 		if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)
248 			return false;
249 		return true;
250 	}
251 	/* Always true for the response message in RX channel */
252 	return true;
253 }
254 
255 /**
256  * zynqmp_ipi_send_data - Send data
257  *
258  * @chan: Channel Pointer
259  * @data: Message Pointer
260  *
261  * Return: 0 if all goes good, else appropriate error messages.
262  */
263 static int zynqmp_ipi_send_data(struct mbox_chan *chan, void *data)
264 {
265 	struct device *dev = chan->mbox->dev;
266 	struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
267 	struct zynqmp_ipi_mchan *mchan = chan->con_priv;
268 	struct zynqmp_ipi_message *msg = data;
269 	u64 arg0;
270 	struct arm_smccc_res res;
271 
272 	if (WARN_ON(!ipi_mbox)) {
273 		dev_err(dev, "no platform drv data??\n");
274 		return -EINVAL;
275 	}
276 
277 	if (mchan->chan_type == IPI_MB_CHNL_TX) {
278 		/* Send request message */
279 		if (msg && msg->len > mchan->req_buf_size) {
280 			dev_err(dev, "channel %d message length %u > max %lu\n",
281 				mchan->chan_type, (unsigned int)msg->len,
282 				mchan->req_buf_size);
283 			return -EINVAL;
284 		}
285 		if (msg && msg->len)
286 			memcpy_toio(mchan->req_buf, msg->data, msg->len);
287 		/* Kick IPI mailbox to send message */
288 		arg0 = SMC_IPI_MAILBOX_NOTIFY;
289 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
290 	} else {
291 		/* Send response message */
292 		if (msg && msg->len > mchan->resp_buf_size) {
293 			dev_err(dev, "channel %d message length %u > max %lu\n",
294 				mchan->chan_type, (unsigned int)msg->len,
295 				mchan->resp_buf_size);
296 			return -EINVAL;
297 		}
298 		if (msg && msg->len)
299 			memcpy_toio(mchan->resp_buf, msg->data, msg->len);
300 		arg0 = SMC_IPI_MAILBOX_ACK;
301 		zynqmp_ipi_fw_call(ipi_mbox, arg0, IPI_SMC_ACK_EIRQ_MASK,
302 				   &res);
303 	}
304 	return 0;
305 }
306 
307 /**
308  * zynqmp_ipi_startup - Startup the IPI channel
309  *
310  * @chan: Channel pointer
311  *
312  * Return: 0 if all goes good, else return corresponding error message
313  */
314 static int zynqmp_ipi_startup(struct mbox_chan *chan)
315 {
316 	struct device *dev = chan->mbox->dev;
317 	struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
318 	struct zynqmp_ipi_mchan *mchan = chan->con_priv;
319 	u64 arg0;
320 	struct arm_smccc_res res;
321 	int ret = 0;
322 	unsigned int nchan_type;
323 
324 	if (mchan->is_opened)
325 		return 0;
326 
327 	/* If no channel has been opened, open the IPI mailbox */
328 	nchan_type = (mchan->chan_type + 1) % 2;
329 	if (!ipi_mbox->mchans[nchan_type].is_opened) {
330 		arg0 = SMC_IPI_MAILBOX_OPEN;
331 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
332 		/* Check the SMC call status, a0 of the result */
333 		ret = (int)(res.a0 & 0xFFFFFFFF);
334 		if (ret < 0) {
335 			dev_err(dev, "SMC to open the IPI channel failed.\n");
336 			return ret;
337 		}
338 		ret = 0;
339 	}
340 
341 	/* If it is RX channel, enable the IPI notification interrupt */
342 	if (mchan->chan_type == IPI_MB_CHNL_RX) {
343 		arg0 = SMC_IPI_MAILBOX_ENABLE_IRQ;
344 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
345 	}
346 	mchan->is_opened = 1;
347 
348 	return ret;
349 }
350 
351 /**
352  * zynqmp_ipi_shutdown - Shutdown the IPI channel
353  *
354  * @chan: Channel pointer
355  */
356 static void zynqmp_ipi_shutdown(struct mbox_chan *chan)
357 {
358 	struct device *dev = chan->mbox->dev;
359 	struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
360 	struct zynqmp_ipi_mchan *mchan = chan->con_priv;
361 	u64 arg0;
362 	struct arm_smccc_res res;
363 	unsigned int chan_type;
364 
365 	if (!mchan->is_opened)
366 		return;
367 
368 	/* If it is RX channel, disable notification interrupt */
369 	chan_type = mchan->chan_type;
370 	if (chan_type == IPI_MB_CHNL_RX) {
371 		arg0 = SMC_IPI_MAILBOX_DISABLE_IRQ;
372 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
373 	}
374 	/* Release IPI mailbox if no other channel is opened */
375 	chan_type = (chan_type + 1) % 2;
376 	if (!ipi_mbox->mchans[chan_type].is_opened) {
377 		arg0 = SMC_IPI_MAILBOX_RELEASE;
378 		zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
379 	}
380 
381 	mchan->is_opened = 0;
382 }
383 
384 /* ZynqMP IPI mailbox operations */
385 static const struct mbox_chan_ops zynqmp_ipi_chan_ops = {
386 	.startup = zynqmp_ipi_startup,
387 	.shutdown = zynqmp_ipi_shutdown,
388 	.peek_data = zynqmp_ipi_peek_data,
389 	.last_tx_done = zynqmp_ipi_last_tx_done,
390 	.send_data = zynqmp_ipi_send_data,
391 };
392 
393 /**
394  * zynqmp_ipi_of_xlate - Translate of phandle to IPI mailbox channel
395  *
396  * @mbox: mailbox controller pointer
397  * @p:    phandle pointer
398  *
399  * Return: Mailbox channel, else return error pointer.
400  */
401 static struct mbox_chan *zynqmp_ipi_of_xlate(struct mbox_controller *mbox,
402 					     const struct of_phandle_args *p)
403 {
404 	struct mbox_chan *chan;
405 	struct device *dev = mbox->dev;
406 	unsigned int chan_type;
407 
408 	/* Only supports TX and RX channels */
409 	chan_type = p->args[0];
410 	if (chan_type != IPI_MB_CHNL_TX && chan_type != IPI_MB_CHNL_RX) {
411 		dev_err(dev, "req chnl failure: invalid chnl type %u.\n",
412 			chan_type);
413 		return ERR_PTR(-EINVAL);
414 	}
415 	chan = &mbox->chans[chan_type];
416 	return chan;
417 }
418 
419 static const struct of_device_id zynqmp_ipi_of_match[] = {
420 	{ .compatible = "xlnx,zynqmp-ipi-mailbox" },
421 	{},
422 };
423 MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);
424 
425 /**
426  * zynqmp_ipi_mbox_get_buf_res - Get buffer resource from the IPI dev node
427  *
428  * @node: IPI mbox device child node
429  * @name: name of the IPI buffer
430  * @res: pointer to where the resource information will be stored.
431  *
432  * Return: 0 for success, negative value for failure
433  */
434 static int zynqmp_ipi_mbox_get_buf_res(struct device_node *node,
435 				       const char *name,
436 				       struct resource *res)
437 {
438 	int ret, index;
439 
440 	index = of_property_match_string(node, "reg-names", name);
441 	if (index >= 0) {
442 		ret = of_address_to_resource(node, index, res);
443 		if (ret < 0)
444 			return -EINVAL;
445 		return 0;
446 	}
447 	return -ENODEV;
448 }
449 
450 /**
451  * zynqmp_ipi_mbox_dev_release() - release the existence of a ipi mbox dev
452  *
453  * @dev: the ipi mailbox device
454  *
455  * This is to avoid the no device release() function kernel warning.
456  *
457  */
458 static void zynqmp_ipi_mbox_dev_release(struct device *dev)
459 {
460 	(void)dev;
461 }
462 
463 /**
464  * zynqmp_ipi_mbox_probe - probe IPI mailbox resource from device node
465  *
466  * @ipi_mbox: pointer to IPI mailbox private data structure
467  * @node: IPI mailbox device node
468  *
469  * Return: 0 for success, negative value for failure
470  */
471 static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
472 				 struct device_node *node)
473 {
474 	struct zynqmp_ipi_mchan *mchan;
475 	struct mbox_chan *chans;
476 	struct mbox_controller *mbox;
477 	struct resource res;
478 	struct device *dev, *mdev;
479 	const char *name;
480 	int ret;
481 
482 	dev = ipi_mbox->pdata->dev;
483 	/* Initialize dev for IPI mailbox */
484 	ipi_mbox->dev.parent = dev;
485 	ipi_mbox->dev.release = NULL;
486 	ipi_mbox->dev.of_node = node;
487 	dev_set_name(&ipi_mbox->dev, "%s", of_node_full_name(node));
488 	dev_set_drvdata(&ipi_mbox->dev, ipi_mbox);
489 	ipi_mbox->dev.release = zynqmp_ipi_mbox_dev_release;
490 	ipi_mbox->dev.driver = &zynqmp_ipi_mbox_driver;
491 	ret = device_register(&ipi_mbox->dev);
492 	if (ret) {
493 		dev_err(dev, "Failed to register ipi mbox dev.\n");
494 		put_device(&ipi_mbox->dev);
495 		return ret;
496 	}
497 	mdev = &ipi_mbox->dev;
498 
499 	mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
500 	name = "local_request_region";
501 	ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
502 	if (!ret) {
503 		mchan->req_buf_size = resource_size(&res);
504 		mchan->req_buf = devm_ioremap(mdev, res.start,
505 					      mchan->req_buf_size);
506 		if (!mchan->req_buf) {
507 			dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
508 			return -ENOMEM;
509 		}
510 	} else if (ret != -ENODEV) {
511 		dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret);
512 		return ret;
513 	}
514 
515 	name = "remote_response_region";
516 	ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
517 	if (!ret) {
518 		mchan->resp_buf_size = resource_size(&res);
519 		mchan->resp_buf = devm_ioremap(mdev, res.start,
520 					       mchan->resp_buf_size);
521 		if (!mchan->resp_buf) {
522 			dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
523 			return -ENOMEM;
524 		}
525 	} else if (ret != -ENODEV) {
526 		dev_err(mdev, "Unmatched resource %s.\n", name);
527 		return ret;
528 	}
529 	mchan->rx_buf = devm_kzalloc(mdev,
530 				     mchan->resp_buf_size +
531 				     sizeof(struct zynqmp_ipi_message),
532 				     GFP_KERNEL);
533 	if (!mchan->rx_buf)
534 		return -ENOMEM;
535 
536 	mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
537 	name = "remote_request_region";
538 	ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
539 	if (!ret) {
540 		mchan->req_buf_size = resource_size(&res);
541 		mchan->req_buf = devm_ioremap(mdev, res.start,
542 					      mchan->req_buf_size);
543 		if (!mchan->req_buf) {
544 			dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
545 			return -ENOMEM;
546 		}
547 	} else if (ret != -ENODEV) {
548 		dev_err(mdev, "Unmatched resource %s.\n", name);
549 		return ret;
550 	}
551 
552 	name = "local_response_region";
553 	ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
554 	if (!ret) {
555 		mchan->resp_buf_size = resource_size(&res);
556 		mchan->resp_buf = devm_ioremap(mdev, res.start,
557 					       mchan->resp_buf_size);
558 		if (!mchan->resp_buf) {
559 			dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
560 			return -ENOMEM;
561 		}
562 	} else if (ret != -ENODEV) {
563 		dev_err(mdev, "Unmatched resource %s.\n", name);
564 		return ret;
565 	}
566 	mchan->rx_buf = devm_kzalloc(mdev,
567 				     mchan->resp_buf_size +
568 				     sizeof(struct zynqmp_ipi_message),
569 				     GFP_KERNEL);
570 	if (!mchan->rx_buf)
571 		return -ENOMEM;
572 
573 	/* Get the IPI remote agent ID */
574 	ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
575 	if (ret < 0) {
576 		dev_err(dev, "No IPI remote ID is specified.\n");
577 		return ret;
578 	}
579 
580 	mbox = &ipi_mbox->mbox;
581 	mbox->dev = mdev;
582 	mbox->ops = &zynqmp_ipi_chan_ops;
583 	mbox->num_chans = 2;
584 	mbox->txdone_irq = false;
585 	mbox->txdone_poll = true;
586 	mbox->txpoll_period = 5;
587 	mbox->of_xlate = zynqmp_ipi_of_xlate;
588 	chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
589 	if (!chans)
590 		return -ENOMEM;
591 	mbox->chans = chans;
592 	chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
593 	chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
594 	ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
595 	ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
596 	ret = devm_mbox_controller_register(mdev, mbox);
597 	if (ret)
598 		dev_err(mdev,
599 			"Failed to register mbox_controller(%d)\n", ret);
600 	else
601 		dev_info(mdev,
602 			 "Registered ZynqMP IPI mbox with TX/RX channels.\n");
603 	return ret;
604 }
605 
606 /**
607  * zynqmp_ipi_free_mboxes - Free IPI mailboxes devices
608  *
609  * @pdata: IPI private data
610  */
611 static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
612 {
613 	struct zynqmp_ipi_mbox *ipi_mbox;
614 	int i;
615 
616 	i = pdata->num_mboxes;
617 	for (; i >= 0; i--) {
618 		ipi_mbox = &pdata->ipi_mboxes[i];
619 		if (ipi_mbox->dev.parent) {
620 			mbox_controller_unregister(&ipi_mbox->mbox);
621 			if (device_is_registered(&ipi_mbox->dev))
622 				device_unregister(&ipi_mbox->dev);
623 		}
624 	}
625 }
626 
627 static int zynqmp_ipi_probe(struct platform_device *pdev)
628 {
629 	struct device *dev = &pdev->dev;
630 	struct device_node *nc, *np = pdev->dev.of_node;
631 	struct zynqmp_ipi_pdata *pdata;
632 	struct zynqmp_ipi_mbox *mbox;
633 	int num_mboxes, ret = -EINVAL;
634 
635 	num_mboxes = of_get_available_child_count(np);
636 	if (num_mboxes == 0) {
637 		dev_err(dev, "mailbox nodes not available\n");
638 		return -EINVAL;
639 	}
640 
641 	pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),
642 			     GFP_KERNEL);
643 	if (!pdata)
644 		return -ENOMEM;
645 	pdata->dev = dev;
646 
647 	/* Get the IPI local agents ID */
648 	ret = of_property_read_u32(np, "xlnx,ipi-id", &pdata->local_id);
649 	if (ret < 0) {
650 		dev_err(dev, "No IPI local ID is specified.\n");
651 		return ret;
652 	}
653 
654 	pdata->num_mboxes = num_mboxes;
655 
656 	mbox = pdata->ipi_mboxes;
657 	for_each_available_child_of_node(np, nc) {
658 		mbox->pdata = pdata;
659 		ret = zynqmp_ipi_mbox_probe(mbox, nc);
660 		if (ret) {
661 			of_node_put(nc);
662 			dev_err(dev, "failed to probe subdev.\n");
663 			ret = -EINVAL;
664 			goto free_mbox_dev;
665 		}
666 		mbox++;
667 	}
668 
669 	/* IPI IRQ */
670 	ret = platform_get_irq(pdev, 0);
671 	if (ret < 0)
672 		goto free_mbox_dev;
673 
674 	pdata->irq = ret;
675 	ret = devm_request_irq(dev, pdata->irq, zynqmp_ipi_interrupt,
676 			       IRQF_SHARED, dev_name(dev), pdata);
677 	if (ret) {
678 		dev_err(dev, "IRQ %d is not requested successfully.\n",
679 			pdata->irq);
680 		goto free_mbox_dev;
681 	}
682 
683 	platform_set_drvdata(pdev, pdata);
684 	return ret;
685 
686 free_mbox_dev:
687 	zynqmp_ipi_free_mboxes(pdata);
688 	return ret;
689 }
690 
691 static int zynqmp_ipi_remove(struct platform_device *pdev)
692 {
693 	struct zynqmp_ipi_pdata *pdata;
694 
695 	pdata = platform_get_drvdata(pdev);
696 	zynqmp_ipi_free_mboxes(pdata);
697 
698 	return 0;
699 }
700 
701 static struct platform_driver zynqmp_ipi_driver = {
702 	.probe = zynqmp_ipi_probe,
703 	.remove = zynqmp_ipi_remove,
704 	.driver = {
705 		   .name = "zynqmp-ipi",
706 		   .of_match_table = of_match_ptr(zynqmp_ipi_of_match),
707 	},
708 };
709 
710 static int __init zynqmp_ipi_init(void)
711 {
712 	return platform_driver_register(&zynqmp_ipi_driver);
713 }
714 subsys_initcall(zynqmp_ipi_init);
715 
716 static void __exit zynqmp_ipi_exit(void)
717 {
718 	platform_driver_unregister(&zynqmp_ipi_driver);
719 }
720 module_exit(zynqmp_ipi_exit);
721 
722 MODULE_LICENSE("GPL v2");
723 MODULE_DESCRIPTION("Xilinx ZynqMP IPI Mailbox driver");
724 MODULE_AUTHOR("Xilinx Inc.");
725