Skip to content

Commit 41bcf30

Browse files
bentheredonethatJassi Brar
authored andcommitted
mailbox: zynqmp: Move buffered IPI setup to of_match selected routine
Move routine that initializes the mailboxes for send and receive to a function pointer that is set based on compatible string. Signed-off-by: Ben Levinsky <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 6efb495 commit 41bcf30

File tree

1 file changed

+87
-35
lines changed

1 file changed

+87
-35
lines changed

drivers/mailbox/zynqmp-ipi-mailbox.c

Lines changed: 87 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ struct zynqmp_ipi_mchan {
7272
unsigned int chan_type;
7373
};
7474

75+
struct zynqmp_ipi_mbox;
76+
77+
typedef int (*setup_ipi_fn)(struct zynqmp_ipi_mbox *ipi_mbox, struct device_node *node);
78+
7579
/**
7680
* struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox
7781
* platform data.
@@ -81,13 +85,15 @@ struct zynqmp_ipi_mchan {
8185
* @remote_id: remote IPI agent ID
8286
* @mbox: mailbox Controller
8387
* @mchans: array for channels, tx channel and rx channel.
88+
* @setup_ipi_fn: Function Pointer to set up IPI Channels
8489
*/
8590
struct zynqmp_ipi_mbox {
8691
struct zynqmp_ipi_pdata *pdata;
8792
struct device dev;
8893
u32 remote_id;
8994
struct mbox_controller mbox;
9095
struct zynqmp_ipi_mchan mchans[2];
96+
setup_ipi_fn setup_ipi_fn;
9197
};
9298

9399
/**
@@ -464,12 +470,9 @@ static void zynqmp_ipi_mbox_dev_release(struct device *dev)
464470
static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
465471
struct device_node *node)
466472
{
467-
struct zynqmp_ipi_mchan *mchan;
468473
struct mbox_chan *chans;
469474
struct mbox_controller *mbox;
470-
struct resource res;
471475
struct device *dev, *mdev;
472-
const char *name;
473476
int ret;
474477

475478
dev = ipi_mbox->pdata->dev;
@@ -489,6 +492,73 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
489492
}
490493
mdev = &ipi_mbox->dev;
491494

495+
/* Get the IPI remote agent ID */
496+
ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
497+
if (ret < 0) {
498+
dev_err(dev, "No IPI remote ID is specified.\n");
499+
return ret;
500+
}
501+
502+
ret = ipi_mbox->setup_ipi_fn(ipi_mbox, node);
503+
if (ret) {
504+
dev_err(dev, "Failed to set up IPI Buffers.\n");
505+
return ret;
506+
}
507+
508+
mbox = &ipi_mbox->mbox;
509+
mbox->dev = mdev;
510+
mbox->ops = &zynqmp_ipi_chan_ops;
511+
mbox->num_chans = 2;
512+
mbox->txdone_irq = false;
513+
mbox->txdone_poll = true;
514+
mbox->txpoll_period = 5;
515+
mbox->of_xlate = zynqmp_ipi_of_xlate;
516+
chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
517+
if (!chans)
518+
return -ENOMEM;
519+
mbox->chans = chans;
520+
chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
521+
chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
522+
ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
523+
ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
524+
ret = devm_mbox_controller_register(mdev, mbox);
525+
if (ret)
526+
dev_err(mdev,
527+
"Failed to register mbox_controller(%d)\n", ret);
528+
else
529+
dev_info(mdev,
530+
"Registered ZynqMP IPI mbox with TX/RX channels.\n");
531+
return ret;
532+
}
533+
534+
/**
535+
* zynqmp_ipi_setup - set up IPI Buffers for classic flow
536+
*
537+
* @ipi_mbox: pointer to IPI mailbox private data structure
538+
* @node: IPI mailbox device node
539+
*
540+
* This will be used to set up IPI Buffers for ZynqMP SOC if user
541+
* wishes to use classic driver usage model on new SOC's with only
542+
* buffered IPIs.
543+
*
544+
* Note that bufferless IPIs and mixed usage of buffered and bufferless
545+
* IPIs are not supported with this flow.
546+
*
547+
* This will be invoked with compatible string "xlnx,zynqmp-ipi-mailbox".
548+
*
549+
* Return: 0 for success, negative value for failure
550+
*/
551+
static int zynqmp_ipi_setup(struct zynqmp_ipi_mbox *ipi_mbox,
552+
struct device_node *node)
553+
{
554+
struct zynqmp_ipi_mchan *mchan;
555+
struct device *mdev;
556+
struct resource res;
557+
const char *name;
558+
int ret;
559+
560+
mdev = &ipi_mbox->dev;
561+
492562
mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
493563
name = "local_request_region";
494564
ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
@@ -563,37 +633,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
563633
if (!mchan->rx_buf)
564634
return -ENOMEM;
565635

566-
/* Get the IPI remote agent ID */
567-
ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
568-
if (ret < 0) {
569-
dev_err(dev, "No IPI remote ID is specified.\n");
570-
return ret;
571-
}
572-
573-
mbox = &ipi_mbox->mbox;
574-
mbox->dev = mdev;
575-
mbox->ops = &zynqmp_ipi_chan_ops;
576-
mbox->num_chans = 2;
577-
mbox->txdone_irq = false;
578-
mbox->txdone_poll = true;
579-
mbox->txpoll_period = 5;
580-
mbox->of_xlate = zynqmp_ipi_of_xlate;
581-
chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
582-
if (!chans)
583-
return -ENOMEM;
584-
mbox->chans = chans;
585-
chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
586-
chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
587-
ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
588-
ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
589-
ret = devm_mbox_controller_register(mdev, mbox);
590-
if (ret)
591-
dev_err(mdev,
592-
"Failed to register mbox_controller(%d)\n", ret);
593-
else
594-
dev_info(mdev,
595-
"Registered ZynqMP IPI mbox with TX/RX channels.\n");
596-
return ret;
636+
return 0;
597637
}
598638

599639
/**
@@ -624,6 +664,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
624664
struct zynqmp_ipi_pdata *pdata;
625665
struct zynqmp_ipi_mbox *mbox;
626666
int num_mboxes, ret = -EINVAL;
667+
setup_ipi_fn ipi_fn;
627668

628669
num_mboxes = of_get_available_child_count(np);
629670
if (num_mboxes == 0) {
@@ -644,9 +685,18 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
644685
return ret;
645686
}
646687

688+
ipi_fn = (setup_ipi_fn)device_get_match_data(&pdev->dev);
689+
if (!ipi_fn) {
690+
dev_err(dev,
691+
"Mbox Compatible String is missing IPI Setup fn.\n");
692+
return -ENODEV;
693+
}
694+
647695
pdata->num_mboxes = num_mboxes;
648696

649697
mbox = pdata->ipi_mboxes;
698+
mbox->setup_ipi_fn = ipi_fn;
699+
650700
for_each_available_child_of_node(np, nc) {
651701
mbox->pdata = pdata;
652702
ret = zynqmp_ipi_mbox_probe(mbox, nc);
@@ -690,7 +740,9 @@ static void zynqmp_ipi_remove(struct platform_device *pdev)
690740
}
691741

692742
static const struct of_device_id zynqmp_ipi_of_match[] = {
693-
{ .compatible = "xlnx,zynqmp-ipi-mailbox" },
743+
{ .compatible = "xlnx,zynqmp-ipi-mailbox",
744+
.data = &zynqmp_ipi_setup,
745+
},
694746
{},
695747
};
696748
MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);

0 commit comments

Comments
 (0)