@@ -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 */
8590struct 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)
464470static 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
692742static 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};
696748MODULE_DEVICE_TABLE (of , zynqmp_ipi_of_match );
0 commit comments