1040 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Xilinx Inter Processor Interrupt(IPI) Mailbox Driver4 *5 * Copyright (C) 2018 Xilinx, Inc.6 */7 8#include <linux/arm-smccc.h>9#include <linux/cpuhotplug.h>10#include <linux/delay.h>11#include <linux/device.h>12#include <linux/interrupt.h>13#include <linux/irqdomain.h>14#include <linux/io.h>15#include <linux/kernel.h>16#include <linux/mailbox_controller.h>17#include <linux/mailbox/zynqmp-ipi-message.h>18#include <linux/module.h>19#include <linux/of.h>20#include <linux/of_address.h>21#include <linux/of_irq.h>22#include <linux/platform_device.h>23 24/* IPI agent ID any */25#define IPI_ID_ANY 0xFFUL26 27/* indicate if ZynqMP IPI mailbox driver uses SMC calls or HVC calls */28#define USE_SMC 029#define USE_HVC 130 31/* Default IPI SMC function IDs */32#define SMC_IPI_MAILBOX_OPEN 0x82001000U33#define SMC_IPI_MAILBOX_RELEASE 0x82001001U34#define SMC_IPI_MAILBOX_STATUS_ENQUIRY 0x82001002U35#define SMC_IPI_MAILBOX_NOTIFY 0x82001003U36#define SMC_IPI_MAILBOX_ACK 0x82001004U37#define SMC_IPI_MAILBOX_ENABLE_IRQ 0x82001005U38#define SMC_IPI_MAILBOX_DISABLE_IRQ 0x82001006U39 40/* IPI SMC Macros */41#define IPI_SMC_ENQUIRY_DIRQ_MASK 0x00000001UL /* Flag to indicate if42 * notification interrupt43 * to be disabled.44 */45#define IPI_SMC_ACK_EIRQ_MASK 0x00000001UL /* Flag to indicate if46 * notification interrupt47 * to be enabled.48 */49 50/* IPI mailbox status */51#define IPI_MB_STATUS_IDLE 052#define IPI_MB_STATUS_SEND_PENDING 153#define IPI_MB_STATUS_RECV_PENDING 254 55#define IPI_MB_CHNL_TX 0 /* IPI mailbox TX channel */56#define IPI_MB_CHNL_RX 1 /* IPI mailbox RX channel */57 58/* IPI Message Buffer Information */59#define RESP_OFFSET 0x20U60#define DEST_OFFSET 0x40U61#define IPI_BUF_SIZE 0x20U62#define DST_BIT_POS 9U63#define SRC_BITMASK GENMASK(11, 8)64 65#define MAX_SGI 1666 67/*68 * Module parameters69 */70static int tx_poll_period = 5;71module_param_named(tx_poll_period, tx_poll_period, int, 0644);72MODULE_PARM_DESC(tx_poll_period, "Poll period waiting for ack after send.");73 74/**75 * struct zynqmp_ipi_mchan - Description of a Xilinx ZynqMP IPI mailbox channel76 * @is_opened: indicate if the IPI channel is opened77 * @req_buf: local to remote request buffer start address78 * @resp_buf: local to remote response buffer start address79 * @req_buf_size: request buffer size80 * @resp_buf_size: response buffer size81 * @rx_buf: receive buffer to pass received message to client82 * @chan_type: channel type83 */84struct zynqmp_ipi_mchan {85 int is_opened;86 void __iomem *req_buf;87 void __iomem *resp_buf;88 void *rx_buf;89 size_t req_buf_size;90 size_t resp_buf_size;91 unsigned int chan_type;92};93 94struct zynqmp_ipi_mbox;95 96typedef int (*setup_ipi_fn)(struct zynqmp_ipi_mbox *ipi_mbox, struct device_node *node);97 98/**99 * struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox100 * platform data.101 * @pdata: pointer to the IPI private data102 * @dev: device pointer corresponding to the Xilinx ZynqMP103 * IPI mailbox104 * @remote_id: remote IPI agent ID105 * @mbox: mailbox Controller106 * @mchans: array for channels, tx channel and rx channel.107 * @setup_ipi_fn: Function Pointer to set up IPI Channels108 */109struct zynqmp_ipi_mbox {110 struct zynqmp_ipi_pdata *pdata;111 struct device dev;112 u32 remote_id;113 struct mbox_controller mbox;114 struct zynqmp_ipi_mchan mchans[2];115 setup_ipi_fn setup_ipi_fn;116};117 118/**119 * struct zynqmp_ipi_pdata - Description of z ZynqMP IPI agent platform data.120 *121 * @dev: device pointer corresponding to the Xilinx ZynqMP122 * IPI agent123 * @irq: IPI agent interrupt ID124 * @method: IPI SMC or HVC is going to be used125 * @local_id: local IPI agent ID126 * @virq_sgi: IRQ number mapped to SGI127 * @num_mboxes: number of mailboxes of this IPI agent128 * @ipi_mboxes: IPI mailboxes of this IPI agent129 */130struct zynqmp_ipi_pdata {131 struct device *dev;132 int irq;133 unsigned int method;134 u32 local_id;135 int virq_sgi;136 int num_mboxes;137 struct zynqmp_ipi_mbox ipi_mboxes[] __counted_by(num_mboxes);138};139 140static DEFINE_PER_CPU(struct zynqmp_ipi_pdata *, per_cpu_pdata);141 142static struct device_driver zynqmp_ipi_mbox_driver = {143 .owner = THIS_MODULE,144 .name = "zynqmp-ipi-mbox",145};146 147static void zynqmp_ipi_fw_call(struct zynqmp_ipi_mbox *ipi_mbox,148 unsigned long a0, unsigned long a3,149 struct arm_smccc_res *res)150{151 struct zynqmp_ipi_pdata *pdata = ipi_mbox->pdata;152 unsigned long a1, a2;153 154 a1 = pdata->local_id;155 a2 = ipi_mbox->remote_id;156 if (pdata->method == USE_SMC)157 arm_smccc_smc(a0, a1, a2, a3, 0, 0, 0, 0, res);158 else159 arm_smccc_hvc(a0, a1, a2, a3, 0, 0, 0, 0, res);160}161 162/**163 * zynqmp_ipi_interrupt - Interrupt handler for IPI notification164 *165 * @irq: Interrupt number166 * @data: ZynqMP IPI mailbox platform data.167 *168 * Return: -EINVAL if there is no instance169 * IRQ_NONE if the interrupt is not ours.170 * IRQ_HANDLED if the rx interrupt was successfully handled.171 */172static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)173{174 struct zynqmp_ipi_pdata *pdata = data;175 struct mbox_chan *chan;176 struct zynqmp_ipi_mbox *ipi_mbox;177 struct zynqmp_ipi_mchan *mchan;178 struct zynqmp_ipi_message *msg;179 u64 arg0, arg3;180 struct arm_smccc_res res;181 int ret, i, status = IRQ_NONE;182 183 (void)irq;184 arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;185 arg3 = IPI_SMC_ENQUIRY_DIRQ_MASK;186 for (i = 0; i < pdata->num_mboxes; i++) {187 ipi_mbox = &pdata->ipi_mboxes[i];188 mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];189 chan = &ipi_mbox->mbox.chans[IPI_MB_CHNL_RX];190 zynqmp_ipi_fw_call(ipi_mbox, arg0, arg3, &res);191 ret = (int)(res.a0 & 0xFFFFFFFF);192 if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {193 if (mchan->is_opened) {194 msg = mchan->rx_buf;195 if (msg) {196 msg->len = mchan->req_buf_size;197 memcpy_fromio(msg->data, mchan->req_buf,198 msg->len);199 }200 mbox_chan_received_data(chan, (void *)msg);201 status = IRQ_HANDLED;202 }203 }204 }205 return status;206}207 208static irqreturn_t zynqmp_sgi_interrupt(int irq, void *data)209{210 struct zynqmp_ipi_pdata **pdata_ptr = data;211 struct zynqmp_ipi_pdata *pdata = *pdata_ptr;212 213 return zynqmp_ipi_interrupt(irq, pdata);214}215 216/**217 * zynqmp_ipi_peek_data - Peek to see if there are any rx messages.218 *219 * @chan: Channel Pointer220 *221 * Return: 'true' if there is pending rx data, 'false' if there is none.222 */223static bool zynqmp_ipi_peek_data(struct mbox_chan *chan)224{225 struct device *dev = chan->mbox->dev;226 struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);227 struct zynqmp_ipi_mchan *mchan = chan->con_priv;228 int ret;229 u64 arg0;230 struct arm_smccc_res res;231 232 if (WARN_ON(!ipi_mbox)) {233 dev_err(dev, "no platform drv data??\n");234 return false;235 }236 237 arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;238 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);239 ret = (int)(res.a0 & 0xFFFFFFFF);240 241 if (mchan->chan_type == IPI_MB_CHNL_TX) {242 /* TX channel, check if the message has been acked243 * by the remote, if yes, response is available.244 */245 if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)246 return false;247 else248 return true;249 } else if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {250 /* RX channel, check if there is message arrived. */251 return true;252 }253 return false;254}255 256/**257 * zynqmp_ipi_last_tx_done - See if the last tx message is sent258 *259 * @chan: Channel pointer260 *261 * Return: 'true' is no pending tx data, 'false' if there are any.262 */263static bool zynqmp_ipi_last_tx_done(struct mbox_chan *chan)264{265 struct device *dev = chan->mbox->dev;266 struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);267 struct zynqmp_ipi_mchan *mchan = chan->con_priv;268 int ret;269 u64 arg0;270 struct arm_smccc_res res;271 272 if (WARN_ON(!ipi_mbox)) {273 dev_err(dev, "no platform drv data??\n");274 return false;275 }276 277 if (mchan->chan_type == IPI_MB_CHNL_TX) {278 /* We only need to check if the message been taken279 * by the remote in the TX channel280 */281 arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;282 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);283 /* Check the SMC call status, a0 of the result */284 ret = (int)(res.a0 & 0xFFFFFFFF);285 if (ret < 0 || ret & IPI_MB_STATUS_SEND_PENDING)286 return false;287 return true;288 }289 /* Always true for the response message in RX channel */290 return true;291}292 293/**294 * zynqmp_ipi_send_data - Send data295 *296 * @chan: Channel Pointer297 * @data: Message Pointer298 *299 * Return: 0 if all goes good, else appropriate error messages.300 */301static int zynqmp_ipi_send_data(struct mbox_chan *chan, void *data)302{303 struct device *dev = chan->mbox->dev;304 struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);305 struct zynqmp_ipi_mchan *mchan = chan->con_priv;306 struct zynqmp_ipi_message *msg = data;307 u64 arg0;308 struct arm_smccc_res res;309 310 if (WARN_ON(!ipi_mbox)) {311 dev_err(dev, "no platform drv data??\n");312 return -EINVAL;313 }314 315 if (mchan->chan_type == IPI_MB_CHNL_TX) {316 /* Send request message */317 if (msg && msg->len > mchan->req_buf_size && mchan->req_buf) {318 dev_err(dev, "channel %d message length %u > max %lu\n",319 mchan->chan_type, (unsigned int)msg->len,320 mchan->req_buf_size);321 return -EINVAL;322 }323 if (msg && msg->len && mchan->req_buf)324 memcpy_toio(mchan->req_buf, msg->data, msg->len);325 /* Kick IPI mailbox to send message */326 arg0 = SMC_IPI_MAILBOX_NOTIFY;327 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);328 } else {329 /* Send response message */330 if (msg && msg->len > mchan->resp_buf_size && mchan->resp_buf) {331 dev_err(dev, "channel %d message length %u > max %lu\n",332 mchan->chan_type, (unsigned int)msg->len,333 mchan->resp_buf_size);334 return -EINVAL;335 }336 if (msg && msg->len && mchan->resp_buf)337 memcpy_toio(mchan->resp_buf, msg->data, msg->len);338 arg0 = SMC_IPI_MAILBOX_ACK;339 zynqmp_ipi_fw_call(ipi_mbox, arg0, IPI_SMC_ACK_EIRQ_MASK,340 &res);341 }342 return 0;343}344 345/**346 * zynqmp_ipi_startup - Startup the IPI channel347 *348 * @chan: Channel pointer349 *350 * Return: 0 if all goes good, else return corresponding error message351 */352static int zynqmp_ipi_startup(struct mbox_chan *chan)353{354 struct device *dev = chan->mbox->dev;355 struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);356 struct zynqmp_ipi_mchan *mchan = chan->con_priv;357 u64 arg0;358 struct arm_smccc_res res;359 int ret = 0;360 unsigned int nchan_type;361 362 if (mchan->is_opened)363 return 0;364 365 /* If no channel has been opened, open the IPI mailbox */366 nchan_type = (mchan->chan_type + 1) % 2;367 if (!ipi_mbox->mchans[nchan_type].is_opened) {368 arg0 = SMC_IPI_MAILBOX_OPEN;369 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);370 /* Check the SMC call status, a0 of the result */371 ret = (int)(res.a0 & 0xFFFFFFFF);372 if (ret < 0) {373 dev_err(dev, "SMC to open the IPI channel failed.\n");374 return ret;375 }376 ret = 0;377 }378 379 /* If it is RX channel, enable the IPI notification interrupt */380 if (mchan->chan_type == IPI_MB_CHNL_RX) {381 arg0 = SMC_IPI_MAILBOX_ENABLE_IRQ;382 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);383 }384 mchan->is_opened = 1;385 386 return ret;387}388 389/**390 * zynqmp_ipi_shutdown - Shutdown the IPI channel391 *392 * @chan: Channel pointer393 */394static void zynqmp_ipi_shutdown(struct mbox_chan *chan)395{396 struct device *dev = chan->mbox->dev;397 struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);398 struct zynqmp_ipi_mchan *mchan = chan->con_priv;399 u64 arg0;400 struct arm_smccc_res res;401 unsigned int chan_type;402 403 if (!mchan->is_opened)404 return;405 406 /* If it is RX channel, disable notification interrupt */407 chan_type = mchan->chan_type;408 if (chan_type == IPI_MB_CHNL_RX) {409 arg0 = SMC_IPI_MAILBOX_DISABLE_IRQ;410 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);411 }412 /* Release IPI mailbox if no other channel is opened */413 chan_type = (chan_type + 1) % 2;414 if (!ipi_mbox->mchans[chan_type].is_opened) {415 arg0 = SMC_IPI_MAILBOX_RELEASE;416 zynqmp_ipi_fw_call(ipi_mbox, arg0, 0, &res);417 }418 419 mchan->is_opened = 0;420}421 422/* ZynqMP IPI mailbox operations */423static const struct mbox_chan_ops zynqmp_ipi_chan_ops = {424 .startup = zynqmp_ipi_startup,425 .shutdown = zynqmp_ipi_shutdown,426 .peek_data = zynqmp_ipi_peek_data,427 .last_tx_done = zynqmp_ipi_last_tx_done,428 .send_data = zynqmp_ipi_send_data,429};430 431/**432 * zynqmp_ipi_of_xlate - Translate of phandle to IPI mailbox channel433 *434 * @mbox: mailbox controller pointer435 * @p: phandle pointer436 *437 * Return: Mailbox channel, else return error pointer.438 */439static struct mbox_chan *zynqmp_ipi_of_xlate(struct mbox_controller *mbox,440 const struct of_phandle_args *p)441{442 struct mbox_chan *chan;443 struct device *dev = mbox->dev;444 unsigned int chan_type;445 446 /* Only supports TX and RX channels */447 chan_type = p->args[0];448 if (chan_type != IPI_MB_CHNL_TX && chan_type != IPI_MB_CHNL_RX) {449 dev_err(dev, "req chnl failure: invalid chnl type %u.\n",450 chan_type);451 return ERR_PTR(-EINVAL);452 }453 chan = &mbox->chans[chan_type];454 return chan;455}456 457/**458 * zynqmp_ipi_mbox_get_buf_res - Get buffer resource from the IPI dev node459 *460 * @node: IPI mbox device child node461 * @name: name of the IPI buffer462 * @res: pointer to where the resource information will be stored.463 *464 * Return: 0 for success, negative value for failure465 */466static int zynqmp_ipi_mbox_get_buf_res(struct device_node *node,467 const char *name,468 struct resource *res)469{470 int ret, index;471 472 index = of_property_match_string(node, "reg-names", name);473 if (index >= 0) {474 ret = of_address_to_resource(node, index, res);475 if (ret < 0)476 return -EINVAL;477 return 0;478 }479 return -ENODEV;480}481 482/**483 * zynqmp_ipi_mbox_dev_release() - release the existence of a ipi mbox dev484 *485 * @dev: the ipi mailbox device486 *487 * This is to avoid the no device release() function kernel warning.488 *489 */490static void zynqmp_ipi_mbox_dev_release(struct device *dev)491{492 (void)dev;493}494 495/**496 * zynqmp_ipi_mbox_probe - probe IPI mailbox resource from device node497 *498 * @ipi_mbox: pointer to IPI mailbox private data structure499 * @node: IPI mailbox device node500 *501 * Return: 0 for success, negative value for failure502 */503static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,504 struct device_node *node)505{506 struct mbox_chan *chans;507 struct mbox_controller *mbox;508 struct device *dev, *mdev;509 int ret;510 511 dev = ipi_mbox->pdata->dev;512 /* Initialize dev for IPI mailbox */513 ipi_mbox->dev.parent = dev;514 ipi_mbox->dev.release = NULL;515 ipi_mbox->dev.of_node = node;516 dev_set_name(&ipi_mbox->dev, "%s", of_node_full_name(node));517 dev_set_drvdata(&ipi_mbox->dev, ipi_mbox);518 ipi_mbox->dev.release = zynqmp_ipi_mbox_dev_release;519 ipi_mbox->dev.driver = &zynqmp_ipi_mbox_driver;520 ret = device_register(&ipi_mbox->dev);521 if (ret) {522 dev_err(dev, "Failed to register ipi mbox dev.\n");523 put_device(&ipi_mbox->dev);524 return ret;525 }526 mdev = &ipi_mbox->dev;527 528 /* Get the IPI remote agent ID */529 ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);530 if (ret < 0) {531 dev_err(dev, "No IPI remote ID is specified.\n");532 return ret;533 }534 535 ret = ipi_mbox->setup_ipi_fn(ipi_mbox, node);536 if (ret) {537 dev_err(dev, "Failed to set up IPI Buffers.\n");538 return ret;539 }540 541 mbox = &ipi_mbox->mbox;542 mbox->dev = mdev;543 mbox->ops = &zynqmp_ipi_chan_ops;544 mbox->num_chans = 2;545 mbox->txdone_irq = false;546 mbox->txdone_poll = true;547 mbox->txpoll_period = tx_poll_period;548 mbox->of_xlate = zynqmp_ipi_of_xlate;549 chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);550 if (!chans)551 return -ENOMEM;552 mbox->chans = chans;553 chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];554 chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];555 ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;556 ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;557 ret = devm_mbox_controller_register(mdev, mbox);558 if (ret)559 dev_err(mdev,560 "Failed to register mbox_controller(%d)\n", ret);561 else562 dev_info(mdev,563 "Registered ZynqMP IPI mbox with TX/RX channels.\n");564 return ret;565}566 567/**568 * zynqmp_ipi_setup - set up IPI Buffers for classic flow569 *570 * @ipi_mbox: pointer to IPI mailbox private data structure571 * @node: IPI mailbox device node572 *573 * This will be used to set up IPI Buffers for ZynqMP SOC if user574 * wishes to use classic driver usage model on new SOC's with only575 * buffered IPIs.576 *577 * Note that bufferless IPIs and mixed usage of buffered and bufferless578 * IPIs are not supported with this flow.579 *580 * This will be invoked with compatible string "xlnx,zynqmp-ipi-mailbox".581 *582 * Return: 0 for success, negative value for failure583 */584static int zynqmp_ipi_setup(struct zynqmp_ipi_mbox *ipi_mbox,585 struct device_node *node)586{587 struct zynqmp_ipi_mchan *mchan;588 struct device *mdev;589 struct resource res;590 const char *name;591 int ret;592 593 mdev = &ipi_mbox->dev;594 595 mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];596 name = "local_request_region";597 ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);598 if (!ret) {599 mchan->req_buf_size = resource_size(&res);600 mchan->req_buf = devm_ioremap(mdev, res.start,601 mchan->req_buf_size);602 if (!mchan->req_buf) {603 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");604 return -ENOMEM;605 }606 } else if (ret != -ENODEV) {607 dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret);608 return ret;609 }610 611 name = "remote_response_region";612 ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);613 if (!ret) {614 mchan->resp_buf_size = resource_size(&res);615 mchan->resp_buf = devm_ioremap(mdev, res.start,616 mchan->resp_buf_size);617 if (!mchan->resp_buf) {618 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");619 return -ENOMEM;620 }621 } else if (ret != -ENODEV) {622 dev_err(mdev, "Unmatched resource %s.\n", name);623 return ret;624 }625 mchan->rx_buf = devm_kzalloc(mdev,626 mchan->resp_buf_size +627 sizeof(struct zynqmp_ipi_message),628 GFP_KERNEL);629 if (!mchan->rx_buf)630 return -ENOMEM;631 632 mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];633 name = "remote_request_region";634 ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);635 if (!ret) {636 mchan->req_buf_size = resource_size(&res);637 mchan->req_buf = devm_ioremap(mdev, res.start,638 mchan->req_buf_size);639 if (!mchan->req_buf) {640 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");641 return -ENOMEM;642 }643 } else if (ret != -ENODEV) {644 dev_err(mdev, "Unmatched resource %s.\n", name);645 return ret;646 }647 648 name = "local_response_region";649 ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);650 if (!ret) {651 mchan->resp_buf_size = resource_size(&res);652 mchan->resp_buf = devm_ioremap(mdev, res.start,653 mchan->resp_buf_size);654 if (!mchan->resp_buf) {655 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");656 return -ENOMEM;657 }658 } else if (ret != -ENODEV) {659 dev_err(mdev, "Unmatched resource %s.\n", name);660 return ret;661 }662 mchan->rx_buf = devm_kzalloc(mdev,663 mchan->resp_buf_size +664 sizeof(struct zynqmp_ipi_message),665 GFP_KERNEL);666 if (!mchan->rx_buf)667 return -ENOMEM;668 669 return 0;670}671 672/**673 * versal_ipi_setup - Set up IPIs to support mixed usage of674 * Buffered and Bufferless IPIs.675 *676 * @ipi_mbox: pointer to IPI mailbox private data structure677 * @node: IPI mailbox device node678 *679 * Return: 0 for success, negative value for failure680 */681static int versal_ipi_setup(struct zynqmp_ipi_mbox *ipi_mbox,682 struct device_node *node)683{684 struct zynqmp_ipi_mchan *tx_mchan, *rx_mchan;685 struct resource host_res, remote_res;686 struct device_node *parent_node;687 int host_idx, remote_idx;688 struct device *mdev;689 690 tx_mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];691 rx_mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];692 parent_node = of_get_parent(node);693 mdev = &ipi_mbox->dev;694 695 host_idx = zynqmp_ipi_mbox_get_buf_res(parent_node, "msg", &host_res);696 remote_idx = zynqmp_ipi_mbox_get_buf_res(node, "msg", &remote_res);697 698 /*699 * Only set up buffers if both sides claim to have msg buffers.700 * This is because each buffered IPI's corresponding msg buffers701 * are reserved for use by other buffered IPI's.702 */703 if (!host_idx && !remote_idx) {704 u32 host_src, host_dst, remote_src, remote_dst;705 u32 buff_sz;706 707 buff_sz = resource_size(&host_res);708 709 host_src = host_res.start & SRC_BITMASK;710 remote_src = remote_res.start & SRC_BITMASK;711 712 host_dst = (host_src >> DST_BIT_POS) * DEST_OFFSET;713 remote_dst = (remote_src >> DST_BIT_POS) * DEST_OFFSET;714 715 /* Validate that IPI IDs is within IPI Message buffer space. */716 if (host_dst >= buff_sz || remote_dst >= buff_sz) {717 dev_err(mdev,718 "Invalid IPI Message buffer values: %x %x\n",719 host_dst, remote_dst);720 return -EINVAL;721 }722 723 tx_mchan->req_buf = devm_ioremap(mdev,724 host_res.start | remote_dst,725 IPI_BUF_SIZE);726 if (!tx_mchan->req_buf) {727 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");728 return -ENOMEM;729 }730 731 tx_mchan->resp_buf = devm_ioremap(mdev,732 (remote_res.start | host_dst) +733 RESP_OFFSET, IPI_BUF_SIZE);734 if (!tx_mchan->resp_buf) {735 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");736 return -ENOMEM;737 }738 739 rx_mchan->req_buf = devm_ioremap(mdev,740 remote_res.start | host_dst,741 IPI_BUF_SIZE);742 if (!rx_mchan->req_buf) {743 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");744 return -ENOMEM;745 }746 747 rx_mchan->resp_buf = devm_ioremap(mdev,748 (host_res.start | remote_dst) +749 RESP_OFFSET, IPI_BUF_SIZE);750 if (!rx_mchan->resp_buf) {751 dev_err(mdev, "Unable to map IPI buffer I/O memory\n");752 return -ENOMEM;753 }754 755 tx_mchan->resp_buf_size = IPI_BUF_SIZE;756 tx_mchan->req_buf_size = IPI_BUF_SIZE;757 tx_mchan->rx_buf = devm_kzalloc(mdev, IPI_BUF_SIZE +758 sizeof(struct zynqmp_ipi_message),759 GFP_KERNEL);760 if (!tx_mchan->rx_buf)761 return -ENOMEM;762 763 rx_mchan->resp_buf_size = IPI_BUF_SIZE;764 rx_mchan->req_buf_size = IPI_BUF_SIZE;765 rx_mchan->rx_buf = devm_kzalloc(mdev, IPI_BUF_SIZE +766 sizeof(struct zynqmp_ipi_message),767 GFP_KERNEL);768 if (!rx_mchan->rx_buf)769 return -ENOMEM;770 }771 772 return 0;773}774 775static int xlnx_mbox_cpuhp_start(unsigned int cpu)776{777 struct zynqmp_ipi_pdata *pdata;778 779 pdata = get_cpu_var(per_cpu_pdata);780 put_cpu_var(per_cpu_pdata);781 enable_percpu_irq(pdata->virq_sgi, IRQ_TYPE_NONE);782 783 return 0;784}785 786static int xlnx_mbox_cpuhp_down(unsigned int cpu)787{788 struct zynqmp_ipi_pdata *pdata;789 790 pdata = get_cpu_var(per_cpu_pdata);791 put_cpu_var(per_cpu_pdata);792 disable_percpu_irq(pdata->virq_sgi);793 794 return 0;795}796 797static void xlnx_disable_percpu_irq(void *data)798{799 struct zynqmp_ipi_pdata *pdata;800 801 pdata = *this_cpu_ptr(&per_cpu_pdata);802 803 disable_percpu_irq(pdata->virq_sgi);804}805 806static int xlnx_mbox_init_sgi(struct platform_device *pdev,807 int sgi_num,808 struct zynqmp_ipi_pdata *pdata)809{810 int ret = 0;811 int cpu;812 813 /*814 * IRQ related structures are used for the following:815 * for each SGI interrupt ensure its mapped by GIC IRQ domain816 * and that each corresponding linux IRQ for the HW IRQ has817 * a handler for when receiving an interrupt from the remote818 * processor.819 */820 struct irq_domain *domain;821 struct irq_fwspec sgi_fwspec;822 struct device_node *interrupt_parent = NULL;823 struct device *dev = &pdev->dev;824 825 /* Find GIC controller to map SGIs. */826 interrupt_parent = of_irq_find_parent(dev->of_node);827 if (!interrupt_parent) {828 dev_err(&pdev->dev, "Failed to find property for Interrupt parent\n");829 return -EINVAL;830 }831 832 /* Each SGI needs to be associated with GIC's IRQ domain. */833 domain = irq_find_host(interrupt_parent);834 of_node_put(interrupt_parent);835 836 /* Each mapping needs GIC domain when finding IRQ mapping. */837 sgi_fwspec.fwnode = domain->fwnode;838 839 /*840 * When irq domain looks at mapping each arg is as follows:841 * 3 args for: interrupt type (SGI), interrupt # (set later), type842 */843 sgi_fwspec.param_count = 1;844 845 /* Set SGI's hwirq */846 sgi_fwspec.param[0] = sgi_num;847 pdata->virq_sgi = irq_create_fwspec_mapping(&sgi_fwspec);848 849 for_each_possible_cpu(cpu)850 per_cpu(per_cpu_pdata, cpu) = pdata;851 852 ret = request_percpu_irq(pdata->virq_sgi, zynqmp_sgi_interrupt, pdev->name,853 &per_cpu_pdata);854 WARN_ON(ret);855 if (ret) {856 irq_dispose_mapping(pdata->virq_sgi);857 return ret;858 }859 860 irq_set_status_flags(pdata->virq_sgi, IRQ_PER_CPU);861 862 /* Setup function for the CPU hot-plug cases */863 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "mailbox/sgi:starting",864 xlnx_mbox_cpuhp_start, xlnx_mbox_cpuhp_down);865 866 return ret;867}868 869static void xlnx_mbox_cleanup_sgi(struct zynqmp_ipi_pdata *pdata)870{871 cpuhp_remove_state(CPUHP_AP_ONLINE_DYN);872 873 on_each_cpu(xlnx_disable_percpu_irq, NULL, 1);874 875 irq_clear_status_flags(pdata->virq_sgi, IRQ_PER_CPU);876 free_percpu_irq(pdata->virq_sgi, &per_cpu_pdata);877 irq_dispose_mapping(pdata->virq_sgi);878}879 880/**881 * zynqmp_ipi_free_mboxes - Free IPI mailboxes devices882 *883 * @pdata: IPI private data884 */885static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)886{887 struct zynqmp_ipi_mbox *ipi_mbox;888 int i;889 890 if (pdata->irq < MAX_SGI)891 xlnx_mbox_cleanup_sgi(pdata);892 893 i = pdata->num_mboxes;894 for (; i >= 0; i--) {895 ipi_mbox = &pdata->ipi_mboxes[i];896 if (ipi_mbox->dev.parent) {897 mbox_controller_unregister(&ipi_mbox->mbox);898 if (device_is_registered(&ipi_mbox->dev))899 device_unregister(&ipi_mbox->dev);900 }901 }902}903 904static int zynqmp_ipi_probe(struct platform_device *pdev)905{906 struct device *dev = &pdev->dev;907 struct device_node *nc, *np = pdev->dev.of_node;908 struct zynqmp_ipi_pdata __percpu *pdata;909 struct of_phandle_args out_irq;910 struct zynqmp_ipi_mbox *mbox;911 int num_mboxes, ret = -EINVAL;912 setup_ipi_fn ipi_fn;913 914 num_mboxes = of_get_available_child_count(np);915 if (num_mboxes == 0) {916 dev_err(dev, "mailbox nodes not available\n");917 return -EINVAL;918 }919 920 pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),921 GFP_KERNEL);922 if (!pdata)923 return -ENOMEM;924 pdata->dev = dev;925 926 /* Get the IPI local agents ID */927 ret = of_property_read_u32(np, "xlnx,ipi-id", &pdata->local_id);928 if (ret < 0) {929 dev_err(dev, "No IPI local ID is specified.\n");930 return ret;931 }932 933 ipi_fn = (setup_ipi_fn)device_get_match_data(&pdev->dev);934 if (!ipi_fn) {935 dev_err(dev,936 "Mbox Compatible String is missing IPI Setup fn.\n");937 return -ENODEV;938 }939 940 pdata->num_mboxes = num_mboxes;941 942 mbox = pdata->ipi_mboxes;943 mbox->setup_ipi_fn = ipi_fn;944 945 for_each_available_child_of_node(np, nc) {946 mbox->pdata = pdata;947 ret = zynqmp_ipi_mbox_probe(mbox, nc);948 if (ret) {949 of_node_put(nc);950 dev_err(dev, "failed to probe subdev.\n");951 ret = -EINVAL;952 goto free_mbox_dev;953 }954 mbox++;955 }956 957 ret = of_irq_parse_one(dev_of_node(dev), 0, &out_irq);958 if (ret < 0) {959 dev_err(dev, "failed to parse interrupts\n");960 goto free_mbox_dev;961 }962 ret = out_irq.args[1];963 964 /*965 * If Interrupt number is in SGI range, then request SGI else request966 * IPI system IRQ.967 */968 if (ret < MAX_SGI) {969 pdata->irq = ret;970 ret = xlnx_mbox_init_sgi(pdev, pdata->irq, pdata);971 if (ret)972 goto free_mbox_dev;973 } else {974 ret = platform_get_irq(pdev, 0);975 if (ret < 0)976 goto free_mbox_dev;977 978 pdata->irq = ret;979 ret = devm_request_irq(dev, pdata->irq, zynqmp_ipi_interrupt,980 IRQF_SHARED, dev_name(dev), pdata);981 }982 983 if (ret) {984 dev_err(dev, "IRQ %d is not requested successfully.\n",985 pdata->irq);986 goto free_mbox_dev;987 }988 989 platform_set_drvdata(pdev, pdata);990 return ret;991 992free_mbox_dev:993 zynqmp_ipi_free_mboxes(pdata);994 return ret;995}996 997static void zynqmp_ipi_remove(struct platform_device *pdev)998{999 struct zynqmp_ipi_pdata *pdata;1000 1001 pdata = platform_get_drvdata(pdev);1002 zynqmp_ipi_free_mboxes(pdata);1003}1004 1005static const struct of_device_id zynqmp_ipi_of_match[] = {1006 { .compatible = "xlnx,zynqmp-ipi-mailbox",1007 .data = &zynqmp_ipi_setup,1008 },1009 { .compatible = "xlnx,versal-ipi-mailbox",1010 .data = &versal_ipi_setup,1011 },1012 {},1013};1014MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);1015 1016static struct platform_driver zynqmp_ipi_driver = {1017 .probe = zynqmp_ipi_probe,1018 .remove_new = zynqmp_ipi_remove,1019 .driver = {1020 .name = "zynqmp-ipi",1021 .of_match_table = of_match_ptr(zynqmp_ipi_of_match),1022 },1023};1024 1025static int __init zynqmp_ipi_init(void)1026{1027 return platform_driver_register(&zynqmp_ipi_driver);1028}1029subsys_initcall(zynqmp_ipi_init);1030 1031static void __exit zynqmp_ipi_exit(void)1032{1033 platform_driver_unregister(&zynqmp_ipi_driver);1034}1035module_exit(zynqmp_ipi_exit);1036 1037MODULE_LICENSE("GPL v2");1038MODULE_DESCRIPTION("Xilinx ZynqMP IPI Mailbox driver");1039MODULE_AUTHOR("Xilinx Inc.");1040