Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Xilinx Inter Processor Interrupt(IPI) Mailbox Driver
0004  *
0005  * Copyright (C) 2018 Xilinx, Inc.
0006  */
0007 
0008 #include <linux/arm-smccc.h>
0009 #include <linux/delay.h>
0010 #include <linux/device.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/io.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mailbox_controller.h>
0015 #include <linux/mailbox/zynqmp-ipi-message.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/of_address.h>
0019 #include <linux/of_device.h>
0020 #include <linux/of_irq.h>
0021 #include <linux/platform_device.h>
0022 
0023 /* IPI agent ID any */
0024 #define IPI_ID_ANY 0xFFUL
0025 
0026 /* indicate if ZynqMP IPI mailbox driver uses SMC calls or HVC calls */
0027 #define USE_SMC 0
0028 #define USE_HVC 1
0029 
0030 /* Default IPI SMC function IDs */
0031 #define SMC_IPI_MAILBOX_OPEN        0x82001000U
0032 #define SMC_IPI_MAILBOX_RELEASE     0x82001001U
0033 #define SMC_IPI_MAILBOX_STATUS_ENQUIRY  0x82001002U
0034 #define SMC_IPI_MAILBOX_NOTIFY      0x82001003U
0035 #define SMC_IPI_MAILBOX_ACK     0x82001004U
0036 #define SMC_IPI_MAILBOX_ENABLE_IRQ  0x82001005U
0037 #define SMC_IPI_MAILBOX_DISABLE_IRQ 0x82001006U
0038 
0039 /* IPI SMC Macros */
0040 #define IPI_SMC_ENQUIRY_DIRQ_MASK   0x00000001UL /* Flag to indicate if
0041                               * notification interrupt
0042                               * to be disabled.
0043                               */
0044 #define IPI_SMC_ACK_EIRQ_MASK       0x00000001UL /* Flag to indicate if
0045                               * notification interrupt
0046                               * to be enabled.
0047                               */
0048 
0049 /* IPI mailbox status */
0050 #define IPI_MB_STATUS_IDLE      0
0051 #define IPI_MB_STATUS_SEND_PENDING  1
0052 #define IPI_MB_STATUS_RECV_PENDING  2
0053 
0054 #define IPI_MB_CHNL_TX  0 /* IPI mailbox TX channel */
0055 #define IPI_MB_CHNL_RX  1 /* IPI mailbox RX channel */
0056 
0057 /**
0058  * struct zynqmp_ipi_mchan - Description of a Xilinx ZynqMP IPI mailbox channel
0059  * @is_opened: indicate if the IPI channel is opened
0060  * @req_buf: local to remote request buffer start address
0061  * @resp_buf: local to remote response buffer start address
0062  * @req_buf_size: request buffer size
0063  * @resp_buf_size: response buffer size
0064  * @rx_buf: receive buffer to pass received message to client
0065  * @chan_type: channel type
0066  */
0067 struct zynqmp_ipi_mchan {
0068     int is_opened;
0069     void __iomem *req_buf;
0070     void __iomem *resp_buf;
0071     void *rx_buf;
0072     size_t req_buf_size;
0073     size_t resp_buf_size;
0074     unsigned int chan_type;
0075 };
0076 
0077 /**
0078  * struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox
0079  *                          platform data.
0080  * @pdata:        pointer to the IPI private data
0081  * @dev:                  device pointer corresponding to the Xilinx ZynqMP
0082  *                        IPI mailbox
0083  * @remote_id:            remote IPI agent ID
0084  * @mbox:                 mailbox Controller
0085  * @mchans:               array for channels, tx channel and rx channel.
0086  * @irq:                  IPI agent interrupt ID
0087  */
0088 struct zynqmp_ipi_mbox {
0089     struct zynqmp_ipi_pdata *pdata;
0090     struct device dev;
0091     u32 remote_id;
0092     struct mbox_controller mbox;
0093     struct zynqmp_ipi_mchan mchans[2];
0094 };
0095 
0096 /**
0097  * struct zynqmp_ipi_pdata - Description of z ZynqMP IPI agent platform data.
0098  *
0099  * @dev:                  device pointer corresponding to the Xilinx ZynqMP
0100  *                        IPI agent
0101  * @irq:                  IPI agent interrupt ID
0102  * @method:               IPI SMC or HVC is going to be used
0103  * @local_id:             local IPI agent ID
0104  * @num_mboxes:           number of mailboxes of this IPI agent
0105  * @ipi_mboxes:           IPI mailboxes of this IPI agent
0106  */
0107 struct zynqmp_ipi_pdata {
0108     struct device *dev;
0109     int irq;
0110     unsigned int method;
0111     u32 local_id;
0112     int num_mboxes;
0113     struct zynqmp_ipi_mbox *ipi_mboxes;
0114 };
0115 
0116 static struct device_driver zynqmp_ipi_mbox_driver = {
0117     .owner = THIS_MODULE,
0118     .name = "zynqmp-ipi-mbox",
0119 };
0120 
0121 static void zynqmp_ipi_fw_call(struct zynqmp_ipi_mbox *ipi_mbox,
0122                    unsigned long a0, unsigned long a3,
0123                    struct arm_smccc_res *res)
0124 {
0125     struct zynqmp_ipi_pdata *pdata = ipi_mbox->pdata;
0126     unsigned long a1, a2;
0127 
0128     a1 = pdata->local_id;
0129     a2 = ipi_mbox->remote_id;
0130     if (pdata->method == USE_SMC)
0131         arm_smccc_smc(a0, a1, a2, a3, 0, 0, 0, 0, res);
0132     else
0133         arm_smccc_hvc(a0, a1, a2, a3, 0, 0, 0, 0, res);
0134 }
0135 
0136 /**
0137  * zynqmp_ipi_interrupt - Interrupt handler for IPI notification
0138  *
0139  * @irq:  Interrupt number
0140  * @data: ZynqMP IPI mailbox platform data.
0141  *
0142  * Return: -EINVAL if there is no instance
0143  * IRQ_NONE if the interrupt is not ours.
0144  * IRQ_HANDLED if the rx interrupt was successfully handled.
0145  */
0146 static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)
0147 {
0148     struct zynqmp_ipi_pdata *pdata = data;
0149     struct mbox_chan *chan;
0150     struct zynqmp_ipi_mbox *ipi_mbox;
0151     struct zynqmp_ipi_mchan *mchan;
0152     struct zynqmp_ipi_message *msg;
0153     u64 arg0, arg3;
0154     struct arm_smccc_res res;
0155     int ret, i;
0156 
0157     (void)irq;
0158     arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
0159     arg3 = IPI_SMC_ENQUIRY_DIRQ_MASK;
0160     for (i = 0; i < pdata->num_mboxes; i++) {
0161         ipi_mbox = &pdata->ipi_mboxes[i];
0162         mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
0163         chan = &ipi_mbox->mbox.chans[IPI_MB_CHNL_RX];
0164         zynqmp_ipi_fw_call(ipi_mbox, arg0, arg3, &res);
0165         ret = (int)(res.a0 & 0xFFFFFFFF);
0166         if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {
0167             if (mchan->is_opened) {
0168                 msg = mchan->rx_buf;
0169                 msg->len = mchan->req_buf_size;
0170                 memcpy_fromio(msg->data, mchan->req_buf,
0171                           msg->len);
0172                 mbox_chan_received_data(chan, (void *)msg);
0173                 return IRQ_HANDLED;
0174             }
0175         }
0176     }
0177     return IRQ_NONE;
0178 }
0179 
0180 /**
0181  * zynqmp_ipi_peek_data - Peek to see if there are any rx messages.
0182  *
0183  * @chan: Channel Pointer
0184  *
0185  * Return: 'true' if there is pending rx data, 'false' if there is none.
0186  */
0187 static bool zynqmp_ipi_peek_data(struct mbox_chan *chan)
0188 {
0189     struct device *dev = chan->mbox->dev;
0190     struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
0191     struct zynqmp_ipi_mchan *mchan = chan->con_priv;
0192     int ret;
0193     u64 arg0;
0194     struct arm_smccc_res res;
0195 
0196     if (WARN_ON(!ipi_mbox)) {
0197         dev_err(dev, "no platform drv data??\n");
0198         return false;
0199     }
0200 
0201     arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
0202     zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0203     ret = (int)(res.a0 & 0xFFFFFFFF);
0204 
0205     if (mchan->chan_type == IPI_MB_CHNL_TX) {
0206         /* TX channel, check if the message has been acked
0207          * by the remote, if yes, response is available.
0208          */
0209         if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)
0210             return false;
0211         else
0212             return true;
0213     } else if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {
0214         /* RX channel, check if there is message arrived. */
0215         return true;
0216     }
0217     return false;
0218 }
0219 
0220 /**
0221  * zynqmp_ipi_last_tx_done - See if the last tx message is sent
0222  *
0223  * @chan: Channel pointer
0224  *
0225  * Return: 'true' is no pending tx data, 'false' if there are any.
0226  */
0227 static bool zynqmp_ipi_last_tx_done(struct mbox_chan *chan)
0228 {
0229     struct device *dev = chan->mbox->dev;
0230     struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
0231     struct zynqmp_ipi_mchan *mchan = chan->con_priv;
0232     int ret;
0233     u64 arg0;
0234     struct arm_smccc_res res;
0235 
0236     if (WARN_ON(!ipi_mbox)) {
0237         dev_err(dev, "no platform drv data??\n");
0238         return false;
0239     }
0240 
0241     if (mchan->chan_type == IPI_MB_CHNL_TX) {
0242         /* We only need to check if the message been taken
0243          * by the remote in the TX channel
0244          */
0245         arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
0246         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0247         /* Check the SMC call status, a0 of the result */
0248         ret = (int)(res.a0 & 0xFFFFFFFF);
0249         if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)
0250             return false;
0251         return true;
0252     }
0253     /* Always true for the response message in RX channel */
0254     return true;
0255 }
0256 
0257 /**
0258  * zynqmp_ipi_send_data - Send data
0259  *
0260  * @chan: Channel Pointer
0261  * @data: Message Pointer
0262  *
0263  * Return: 0 if all goes good, else appropriate error messages.
0264  */
0265 static int zynqmp_ipi_send_data(struct mbox_chan *chan, void *data)
0266 {
0267     struct device *dev = chan->mbox->dev;
0268     struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
0269     struct zynqmp_ipi_mchan *mchan = chan->con_priv;
0270     struct zynqmp_ipi_message *msg = data;
0271     u64 arg0;
0272     struct arm_smccc_res res;
0273 
0274     if (WARN_ON(!ipi_mbox)) {
0275         dev_err(dev, "no platform drv data??\n");
0276         return -EINVAL;
0277     }
0278 
0279     if (mchan->chan_type == IPI_MB_CHNL_TX) {
0280         /* Send request message */
0281         if (msg && msg->len > mchan->req_buf_size) {
0282             dev_err(dev, "channel %d message length %u > max %lu\n",
0283                 mchan->chan_type, (unsigned int)msg->len,
0284                 mchan->req_buf_size);
0285             return -EINVAL;
0286         }
0287         if (msg && msg->len)
0288             memcpy_toio(mchan->req_buf, msg->data, msg->len);
0289         /* Kick IPI mailbox to send message */
0290         arg0 = SMC_IPI_MAILBOX_NOTIFY;
0291         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0292     } else {
0293         /* Send response message */
0294         if (msg && msg->len > mchan->resp_buf_size) {
0295             dev_err(dev, "channel %d message length %u > max %lu\n",
0296                 mchan->chan_type, (unsigned int)msg->len,
0297                 mchan->resp_buf_size);
0298             return -EINVAL;
0299         }
0300         if (msg && msg->len)
0301             memcpy_toio(mchan->resp_buf, msg->data, msg->len);
0302         arg0 = SMC_IPI_MAILBOX_ACK;
0303         zynqmp_ipi_fw_call(ipi_mbox, arg0, IPI_SMC_ACK_EIRQ_MASK,
0304                    &res);
0305     }
0306     return 0;
0307 }
0308 
0309 /**
0310  * zynqmp_ipi_startup - Startup the IPI channel
0311  *
0312  * @chan: Channel pointer
0313  *
0314  * Return: 0 if all goes good, else return corresponding error message
0315  */
0316 static int zynqmp_ipi_startup(struct mbox_chan *chan)
0317 {
0318     struct device *dev = chan->mbox->dev;
0319     struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
0320     struct zynqmp_ipi_mchan *mchan = chan->con_priv;
0321     u64 arg0;
0322     struct arm_smccc_res res;
0323     int ret = 0;
0324     unsigned int nchan_type;
0325 
0326     if (mchan->is_opened)
0327         return 0;
0328 
0329     /* If no channel has been opened, open the IPI mailbox */
0330     nchan_type = (mchan->chan_type + 1) % 2;
0331     if (!ipi_mbox->mchans[nchan_type].is_opened) {
0332         arg0 = SMC_IPI_MAILBOX_OPEN;
0333         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0334         /* Check the SMC call status, a0 of the result */
0335         ret = (int)(res.a0 & 0xFFFFFFFF);
0336         if (ret < 0) {
0337             dev_err(dev, "SMC to open the IPI channel failed.\n");
0338             return ret;
0339         }
0340         ret = 0;
0341     }
0342 
0343     /* If it is RX channel, enable the IPI notification interrupt */
0344     if (mchan->chan_type == IPI_MB_CHNL_RX) {
0345         arg0 = SMC_IPI_MAILBOX_ENABLE_IRQ;
0346         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0347     }
0348     mchan->is_opened = 1;
0349 
0350     return ret;
0351 }
0352 
0353 /**
0354  * zynqmp_ipi_shutdown - Shutdown the IPI channel
0355  *
0356  * @chan: Channel pointer
0357  */
0358 static void zynqmp_ipi_shutdown(struct mbox_chan *chan)
0359 {
0360     struct device *dev = chan->mbox->dev;
0361     struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
0362     struct zynqmp_ipi_mchan *mchan = chan->con_priv;
0363     u64 arg0;
0364     struct arm_smccc_res res;
0365     unsigned int chan_type;
0366 
0367     if (!mchan->is_opened)
0368         return;
0369 
0370     /* If it is RX channel, disable notification interrupt */
0371     chan_type = mchan->chan_type;
0372     if (chan_type == IPI_MB_CHNL_RX) {
0373         arg0 = SMC_IPI_MAILBOX_DISABLE_IRQ;
0374         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0375     }
0376     /* Release IPI mailbox if no other channel is opened */
0377     chan_type = (chan_type + 1) % 2;
0378     if (!ipi_mbox->mchans[chan_type].is_opened) {
0379         arg0 = SMC_IPI_MAILBOX_RELEASE;
0380         zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);
0381     }
0382 
0383     mchan->is_opened = 0;
0384 }
0385 
0386 /* ZynqMP IPI mailbox operations */
0387 static const struct mbox_chan_ops zynqmp_ipi_chan_ops = {
0388     .startup = zynqmp_ipi_startup,
0389     .shutdown = zynqmp_ipi_shutdown,
0390     .peek_data = zynqmp_ipi_peek_data,
0391     .last_tx_done = zynqmp_ipi_last_tx_done,
0392     .send_data = zynqmp_ipi_send_data,
0393 };
0394 
0395 /**
0396  * zynqmp_ipi_of_xlate - Translate of phandle to IPI mailbox channel
0397  *
0398  * @mbox: mailbox controller pointer
0399  * @p:    phandle pointer
0400  *
0401  * Return: Mailbox channel, else return error pointer.
0402  */
0403 static struct mbox_chan *zynqmp_ipi_of_xlate(struct mbox_controller *mbox,
0404                          const struct of_phandle_args *p)
0405 {
0406     struct mbox_chan *chan;
0407     struct device *dev = mbox->dev;
0408     unsigned int chan_type;
0409 
0410     /* Only supports TX and RX channels */
0411     chan_type = p->args[0];
0412     if (chan_type != IPI_MB_CHNL_TX && chan_type != IPI_MB_CHNL_RX) {
0413         dev_err(dev, "req chnl failure: invalid chnl type %u.\n",
0414             chan_type);
0415         return ERR_PTR(-EINVAL);
0416     }
0417     chan = &mbox->chans[chan_type];
0418     return chan;
0419 }
0420 
0421 static const struct of_device_id zynqmp_ipi_of_match[] = {
0422     { .compatible = "xlnx,zynqmp-ipi-mailbox" },
0423     {},
0424 };
0425 MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);
0426 
0427 /**
0428  * zynqmp_ipi_mbox_get_buf_res - Get buffer resource from the IPI dev node
0429  *
0430  * @node: IPI mbox device child node
0431  * @name: name of the IPI buffer
0432  * @res: pointer to where the resource information will be stored.
0433  *
0434  * Return: 0 for success, negative value for failure
0435  */
0436 static int zynqmp_ipi_mbox_get_buf_res(struct device_node *node,
0437                        const char *name,
0438                        struct resource *res)
0439 {
0440     int ret, index;
0441 
0442     index = of_property_match_string(node, "reg-names", name);
0443     if (index >= 0) {
0444         ret = of_address_to_resource(node, index, res);
0445         if (ret < 0)
0446             return -EINVAL;
0447         return 0;
0448     }
0449     return -ENODEV;
0450 }
0451 
0452 /**
0453  * zynqmp_ipi_mbox_dev_release() - release the existence of a ipi mbox dev
0454  *
0455  * @dev: the ipi mailbox device
0456  *
0457  * This is to avoid the no device release() function kernel warning.
0458  *
0459  */
0460 static void zynqmp_ipi_mbox_dev_release(struct device *dev)
0461 {
0462     (void)dev;
0463 }
0464 
0465 /**
0466  * zynqmp_ipi_mbox_probe - probe IPI mailbox resource from device node
0467  *
0468  * @ipi_mbox: pointer to IPI mailbox private data structure
0469  * @node: IPI mailbox device node
0470  *
0471  * Return: 0 for success, negative value for failure
0472  */
0473 static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
0474                  struct device_node *node)
0475 {
0476     struct zynqmp_ipi_mchan *mchan;
0477     struct mbox_chan *chans;
0478     struct mbox_controller *mbox;
0479     struct resource res;
0480     struct device *dev, *mdev;
0481     const char *name;
0482     int ret;
0483 
0484     dev = ipi_mbox->pdata->dev;
0485     /* Initialize dev for IPI mailbox */
0486     ipi_mbox->dev.parent = dev;
0487     ipi_mbox->dev.release = NULL;
0488     ipi_mbox->dev.of_node = node;
0489     dev_set_name(&ipi_mbox->dev, "%s", of_node_full_name(node));
0490     dev_set_drvdata(&ipi_mbox->dev, ipi_mbox);
0491     ipi_mbox->dev.release = zynqmp_ipi_mbox_dev_release;
0492     ipi_mbox->dev.driver = &zynqmp_ipi_mbox_driver;
0493     ret = device_register(&ipi_mbox->dev);
0494     if (ret) {
0495         dev_err(dev, "Failed to register ipi mbox dev.\n");
0496         return ret;
0497     }
0498     mdev = &ipi_mbox->dev;
0499 
0500     mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
0501     name = "local_request_region";
0502     ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
0503     if (!ret) {
0504         mchan->req_buf_size = resource_size(&res);
0505         mchan->req_buf = devm_ioremap(mdev, res.start,
0506                           mchan->req_buf_size);
0507         if (!mchan->req_buf) {
0508             dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
0509             return -ENOMEM;
0510         }
0511     } else if (ret != -ENODEV) {
0512         dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret);
0513         return ret;
0514     }
0515 
0516     name = "remote_response_region";
0517     ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
0518     if (!ret) {
0519         mchan->resp_buf_size = resource_size(&res);
0520         mchan->resp_buf = devm_ioremap(mdev, res.start,
0521                            mchan->resp_buf_size);
0522         if (!mchan->resp_buf) {
0523             dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
0524             return -ENOMEM;
0525         }
0526     } else if (ret != -ENODEV) {
0527         dev_err(mdev, "Unmatched resource %s.\n", name);
0528         return ret;
0529     }
0530     mchan->rx_buf = devm_kzalloc(mdev,
0531                      mchan->resp_buf_size +
0532                      sizeof(struct zynqmp_ipi_message),
0533                      GFP_KERNEL);
0534     if (!mchan->rx_buf)
0535         return -ENOMEM;
0536 
0537     mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
0538     name = "remote_request_region";
0539     ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
0540     if (!ret) {
0541         mchan->req_buf_size = resource_size(&res);
0542         mchan->req_buf = devm_ioremap(mdev, res.start,
0543                           mchan->req_buf_size);
0544         if (!mchan->req_buf) {
0545             dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
0546             return -ENOMEM;
0547         }
0548     } else if (ret != -ENODEV) {
0549         dev_err(mdev, "Unmatched resource %s.\n", name);
0550         return ret;
0551     }
0552 
0553     name = "local_response_region";
0554     ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
0555     if (!ret) {
0556         mchan->resp_buf_size = resource_size(&res);
0557         mchan->resp_buf = devm_ioremap(mdev, res.start,
0558                            mchan->resp_buf_size);
0559         if (!mchan->resp_buf) {
0560             dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
0561             return -ENOMEM;
0562         }
0563     } else if (ret != -ENODEV) {
0564         dev_err(mdev, "Unmatched resource %s.\n", name);
0565         return ret;
0566     }
0567     mchan->rx_buf = devm_kzalloc(mdev,
0568                      mchan->resp_buf_size +
0569                      sizeof(struct zynqmp_ipi_message),
0570                      GFP_KERNEL);
0571     if (!mchan->rx_buf)
0572         return -ENOMEM;
0573 
0574     /* Get the IPI remote agent ID */
0575     ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
0576     if (ret < 0) {
0577         dev_err(dev, "No IPI remote ID is specified.\n");
0578         return ret;
0579     }
0580 
0581     mbox = &ipi_mbox->mbox;
0582     mbox->dev = mdev;
0583     mbox->ops = &zynqmp_ipi_chan_ops;
0584     mbox->num_chans = 2;
0585     mbox->txdone_irq = false;
0586     mbox->txdone_poll = true;
0587     mbox->txpoll_period = 5;
0588     mbox->of_xlate = zynqmp_ipi_of_xlate;
0589     chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
0590     if (!chans)
0591         return -ENOMEM;
0592     mbox->chans = chans;
0593     chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
0594     chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
0595     ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
0596     ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
0597     ret = devm_mbox_controller_register(mdev, mbox);
0598     if (ret)
0599         dev_err(mdev,
0600             "Failed to register mbox_controller(%d)\n", ret);
0601     else
0602         dev_info(mdev,
0603              "Registered ZynqMP IPI mbox with TX/RX channels.\n");
0604     return ret;
0605 }
0606 
0607 /**
0608  * zynqmp_ipi_free_mboxes - Free IPI mailboxes devices
0609  *
0610  * @pdata: IPI private data
0611  */
0612 static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
0613 {
0614     struct zynqmp_ipi_mbox *ipi_mbox;
0615     int i;
0616 
0617     i = pdata->num_mboxes;
0618     for (; i >= 0; i--) {
0619         ipi_mbox = &pdata->ipi_mboxes[i];
0620         if (ipi_mbox->dev.parent) {
0621             mbox_controller_unregister(&ipi_mbox->mbox);
0622             device_unregister(&ipi_mbox->dev);
0623         }
0624     }
0625 }
0626 
0627 static int zynqmp_ipi_probe(struct platform_device *pdev)
0628 {
0629     struct device *dev = &pdev->dev;
0630     struct device_node *nc, *np = pdev->dev.of_node;
0631     struct zynqmp_ipi_pdata *pdata;
0632     struct zynqmp_ipi_mbox *mbox;
0633     int num_mboxes, ret = -EINVAL;
0634 
0635     num_mboxes = of_get_child_count(np);
0636     pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)),
0637                  GFP_KERNEL);
0638     if (!pdata)
0639         return -ENOMEM;
0640     pdata->dev = dev;
0641 
0642     /* Get the IPI local agents ID */
0643     ret = of_property_read_u32(np, "xlnx,ipi-id", &pdata->local_id);
0644     if (ret < 0) {
0645         dev_err(dev, "No IPI local ID is specified.\n");
0646         return ret;
0647     }
0648 
0649     pdata->num_mboxes = num_mboxes;
0650     pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *)
0651                 ((char *)pdata + sizeof(*pdata));
0652 
0653     mbox = pdata->ipi_mboxes;
0654     for_each_available_child_of_node(np, nc) {
0655         mbox->pdata = pdata;
0656         ret = zynqmp_ipi_mbox_probe(mbox, nc);
0657         if (ret) {
0658             of_node_put(nc);
0659             dev_err(dev, "failed to probe subdev.\n");
0660             ret = -EINVAL;
0661             goto free_mbox_dev;
0662         }
0663         mbox++;
0664     }
0665 
0666     /* IPI IRQ */
0667     ret = platform_get_irq(pdev, 0);
0668     if (ret < 0)
0669         goto free_mbox_dev;
0670 
0671     pdata->irq = ret;
0672     ret = devm_request_irq(dev, pdata->irq, zynqmp_ipi_interrupt,
0673                    IRQF_SHARED, dev_name(dev), pdata);
0674     if (ret) {
0675         dev_err(dev, "IRQ %d is not requested successfully.\n",
0676             pdata->irq);
0677         goto free_mbox_dev;
0678     }
0679 
0680     platform_set_drvdata(pdev, pdata);
0681     return ret;
0682 
0683 free_mbox_dev:
0684     zynqmp_ipi_free_mboxes(pdata);
0685     return ret;
0686 }
0687 
0688 static int zynqmp_ipi_remove(struct platform_device *pdev)
0689 {
0690     struct zynqmp_ipi_pdata *pdata;
0691 
0692     pdata = platform_get_drvdata(pdev);
0693     zynqmp_ipi_free_mboxes(pdata);
0694 
0695     return 0;
0696 }
0697 
0698 static struct platform_driver zynqmp_ipi_driver = {
0699     .probe = zynqmp_ipi_probe,
0700     .remove = zynqmp_ipi_remove,
0701     .driver = {
0702            .name = "zynqmp-ipi",
0703            .of_match_table = of_match_ptr(zynqmp_ipi_of_match),
0704     },
0705 };
0706 
0707 static int __init zynqmp_ipi_init(void)
0708 {
0709     return platform_driver_register(&zynqmp_ipi_driver);
0710 }
0711 subsys_initcall(zynqmp_ipi_init);
0712 
0713 static void __exit zynqmp_ipi_exit(void)
0714 {
0715     platform_driver_unregister(&zynqmp_ipi_driver);
0716 }
0717 module_exit(zynqmp_ipi_exit);
0718 
0719 MODULE_LICENSE("GPL v2");
0720 MODULE_DESCRIPTION("Xilinx ZynqMP IPI Mailbox driver");
0721 MODULE_AUTHOR("Xilinx Inc.");