cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

zynqmp-ipi-mailbox.c (19643B)


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