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.");