root/drivers/mailbox/zynqmp-ipi-mailbox.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zynqmp_ipi_fw_call
  2. zynqmp_ipi_interrupt
  3. zynqmp_ipi_peek_data
  4. zynqmp_ipi_last_tx_done
  5. zynqmp_ipi_send_data
  6. zynqmp_ipi_startup
  7. zynqmp_ipi_shutdown
  8. zynqmp_ipi_of_xlate
  9. zynqmp_ipi_mbox_get_buf_res
  10. zynqmp_ipi_mbox_dev_release
  11. zynqmp_ipi_mbox_probe
  12. zynqmp_ipi_free_mboxes
  13. zynqmp_ipi_probe
  14. zynqmp_ipi_remove
  15. zynqmp_ipi_init
  16. zynqmp_ipi_exit

   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  */
  67 struct 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  */
  88 struct 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  */
 107 struct 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 
 116 static struct device_driver zynqmp_ipi_mbox_driver = {
 117         .owner = THIS_MODULE,
 118         .name = "zynqmp-ipi-mbox",
 119 };
 120 
 121 static 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  */
 146 static 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  */
 187 static 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  */
 227 static 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  */
 265 static 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  */
 316 static 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  */
 358 static 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 */
 387 static 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  */
 403 static 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 
 421 static const struct of_device_id zynqmp_ipi_of_match[] = {
 422         { .compatible = "xlnx,zynqmp-ipi-mailbox" },
 423         {},
 424 };
 425 MODULE_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  */
 436 static 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  */
 460 static 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  */
 473 static 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 (IS_ERR(mchan->req_buf)) {
 508                         dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
 509                         ret = PTR_ERR(mchan->req_buf);
 510                         return ret;
 511                 }
 512         } else if (ret != -ENODEV) {
 513                 dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret);
 514                 return ret;
 515         }
 516 
 517         name = "remote_response_region";
 518         ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
 519         if (!ret) {
 520                 mchan->resp_buf_size = resource_size(&res);
 521                 mchan->resp_buf = devm_ioremap(mdev, res.start,
 522                                                mchan->resp_buf_size);
 523                 if (IS_ERR(mchan->resp_buf)) {
 524                         dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
 525                         ret = PTR_ERR(mchan->resp_buf);
 526                         return ret;
 527                 }
 528         } else if (ret != -ENODEV) {
 529                 dev_err(mdev, "Unmatched resource %s.\n", name);
 530                 return ret;
 531         }
 532         mchan->rx_buf = devm_kzalloc(mdev,
 533                                      mchan->resp_buf_size +
 534                                      sizeof(struct zynqmp_ipi_message),
 535                                      GFP_KERNEL);
 536         if (!mchan->rx_buf)
 537                 return -ENOMEM;
 538 
 539         mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
 540         name = "remote_request_region";
 541         ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
 542         if (!ret) {
 543                 mchan->req_buf_size = resource_size(&res);
 544                 mchan->req_buf = devm_ioremap(mdev, res.start,
 545                                               mchan->req_buf_size);
 546                 if (IS_ERR(mchan->req_buf)) {
 547                         dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
 548                         ret = PTR_ERR(mchan->req_buf);
 549                         return ret;
 550                 }
 551         } else if (ret != -ENODEV) {
 552                 dev_err(mdev, "Unmatched resource %s.\n", name);
 553                 return ret;
 554         }
 555 
 556         name = "local_response_region";
 557         ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
 558         if (!ret) {
 559                 mchan->resp_buf_size = resource_size(&res);
 560                 mchan->resp_buf = devm_ioremap(mdev, res.start,
 561                                                mchan->resp_buf_size);
 562                 if (IS_ERR(mchan->resp_buf)) {
 563                         dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
 564                         ret = PTR_ERR(mchan->resp_buf);
 565                         return ret;
 566                 }
 567         } else if (ret != -ENODEV) {
 568                 dev_err(mdev, "Unmatched resource %s.\n", name);
 569                 return ret;
 570         }
 571         mchan->rx_buf = devm_kzalloc(mdev,
 572                                      mchan->resp_buf_size +
 573                                      sizeof(struct zynqmp_ipi_message),
 574                                      GFP_KERNEL);
 575         if (!mchan->rx_buf)
 576                 return -ENOMEM;
 577 
 578         /* Get the IPI remote agent ID */
 579         ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
 580         if (ret < 0) {
 581                 dev_err(dev, "No IPI remote ID is specified.\n");
 582                 return ret;
 583         }
 584 
 585         mbox = &ipi_mbox->mbox;
 586         mbox->dev = mdev;
 587         mbox->ops = &zynqmp_ipi_chan_ops;
 588         mbox->num_chans = 2;
 589         mbox->txdone_irq = false;
 590         mbox->txdone_poll = true;
 591         mbox->txpoll_period = 5;
 592         mbox->of_xlate = zynqmp_ipi_of_xlate;
 593         chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
 594         if (!chans)
 595                 return -ENOMEM;
 596         mbox->chans = chans;
 597         chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
 598         chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
 599         ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
 600         ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
 601         ret = devm_mbox_controller_register(mdev, mbox);
 602         if (ret)
 603                 dev_err(mdev,
 604                         "Failed to register mbox_controller(%d)\n", ret);
 605         else
 606                 dev_info(mdev,
 607                          "Registered ZynqMP IPI mbox with TX/RX channels.\n");
 608         return ret;
 609 }
 610 
 611 /**
 612  * zynqmp_ipi_free_mboxes - Free IPI mailboxes devices
 613  *
 614  * @pdata: IPI private data
 615  */
 616 static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
 617 {
 618         struct zynqmp_ipi_mbox *ipi_mbox;
 619         int i;
 620 
 621         i = pdata->num_mboxes;
 622         for (; i >= 0; i--) {
 623                 ipi_mbox = &pdata->ipi_mboxes[i];
 624                 if (ipi_mbox->dev.parent) {
 625                         mbox_controller_unregister(&ipi_mbox->mbox);
 626                         device_unregister(&ipi_mbox->dev);
 627                 }
 628         }
 629 }
 630 
 631 static int zynqmp_ipi_probe(struct platform_device *pdev)
 632 {
 633         struct device *dev = &pdev->dev;
 634         struct device_node *nc, *np = pdev->dev.of_node;
 635         struct zynqmp_ipi_pdata *pdata;
 636         struct zynqmp_ipi_mbox *mbox;
 637         int num_mboxes, ret = -EINVAL;
 638 
 639         num_mboxes = of_get_child_count(np);
 640         pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)),
 641                              GFP_KERNEL);
 642         if (!pdata)
 643                 return -ENOMEM;
 644         pdata->dev = dev;
 645 
 646         /* Get the IPI local agents ID */
 647         ret = of_property_read_u32(np, "xlnx,ipi-id", &pdata->local_id);
 648         if (ret < 0) {
 649                 dev_err(dev, "No IPI local ID is specified.\n");
 650                 return ret;
 651         }
 652 
 653         pdata->num_mboxes = num_mboxes;
 654         pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *)
 655                             ((char *)pdata + sizeof(*pdata));
 656 
 657         mbox = pdata->ipi_mboxes;
 658         for_each_available_child_of_node(np, nc) {
 659                 mbox->pdata = pdata;
 660                 ret = zynqmp_ipi_mbox_probe(mbox, nc);
 661                 if (ret) {
 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                 dev_err(dev, "unable to find IPI IRQ.\n");
 673                 goto free_mbox_dev;
 674         }
 675         pdata->irq = ret;
 676         ret = devm_request_irq(dev, pdata->irq, zynqmp_ipi_interrupt,
 677                                IRQF_SHARED, dev_name(dev), pdata);
 678         if (ret) {
 679                 dev_err(dev, "IRQ %d is not requested successfully.\n",
 680                         pdata->irq);
 681                 goto free_mbox_dev;
 682         }
 683 
 684         platform_set_drvdata(pdev, pdata);
 685         return ret;
 686 
 687 free_mbox_dev:
 688         zynqmp_ipi_free_mboxes(pdata);
 689         return ret;
 690 }
 691 
 692 static int zynqmp_ipi_remove(struct platform_device *pdev)
 693 {
 694         struct zynqmp_ipi_pdata *pdata;
 695 
 696         pdata = platform_get_drvdata(pdev);
 697         zynqmp_ipi_free_mboxes(pdata);
 698 
 699         return 0;
 700 }
 701 
 702 static struct platform_driver zynqmp_ipi_driver = {
 703         .probe = zynqmp_ipi_probe,
 704         .remove = zynqmp_ipi_remove,
 705         .driver = {
 706                    .name = "zynqmp-ipi",
 707                    .of_match_table = of_match_ptr(zynqmp_ipi_of_match),
 708         },
 709 };
 710 
 711 static int __init zynqmp_ipi_init(void)
 712 {
 713         return platform_driver_register(&zynqmp_ipi_driver);
 714 }
 715 subsys_initcall(zynqmp_ipi_init);
 716 
 717 static void __exit zynqmp_ipi_exit(void)
 718 {
 719         platform_driver_unregister(&zynqmp_ipi_driver);
 720 }
 721 module_exit(zynqmp_ipi_exit);
 722 
 723 MODULE_LICENSE("GPL v2");
 724 MODULE_DESCRIPTION("Xilinx ZynqMP IPI Mailbox driver");
 725 MODULE_AUTHOR("Xilinx Inc.");

/* [<][>][^][v][top][bottom][index][help] */