]> git.dujemihanovic.xyz Git - linux.git/commitdiff
mailbox: zynqmp: Move buffered IPI setup to of_match selected routine
authorBen Levinsky <ben.levinsky@amd.com>
Wed, 10 Apr 2024 17:08:24 +0000 (10:08 -0700)
committerJassi Brar <jassisinghbrar@gmail.com>
Wed, 1 May 2024 01:13:07 +0000 (20:13 -0500)
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 <ben.levinsky@amd.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
drivers/mailbox/zynqmp-ipi-mailbox.c

index c7ce0826383f441c9370429c1c93b687859550a2..56ba7135db545c62a9190e7beecc262a237f9e28 100644 (file)
@@ -72,6 +72,10 @@ struct zynqmp_ipi_mchan {
        unsigned int chan_type;
 };
 
+struct zynqmp_ipi_mbox;
+
+typedef int (*setup_ipi_fn)(struct zynqmp_ipi_mbox *ipi_mbox, struct device_node *node);
+
 /**
  * struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox
  *                          platform data.
@@ -81,6 +85,7 @@ struct zynqmp_ipi_mchan {
  * @remote_id:            remote IPI agent ID
  * @mbox:                 mailbox Controller
  * @mchans:               array for channels, tx channel and rx channel.
+ * @setup_ipi_fn:         Function Pointer to set up IPI Channels
  */
 struct zynqmp_ipi_mbox {
        struct zynqmp_ipi_pdata *pdata;
@@ -88,6 +93,7 @@ struct zynqmp_ipi_mbox {
        u32 remote_id;
        struct mbox_controller mbox;
        struct zynqmp_ipi_mchan mchans[2];
+       setup_ipi_fn setup_ipi_fn;
 };
 
 /**
@@ -464,12 +470,9 @@ static void zynqmp_ipi_mbox_dev_release(struct device *dev)
 static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
                                 struct device_node *node)
 {
-       struct zynqmp_ipi_mchan *mchan;
        struct mbox_chan *chans;
        struct mbox_controller *mbox;
-       struct resource res;
        struct device *dev, *mdev;
-       const char *name;
        int ret;
 
        dev = ipi_mbox->pdata->dev;
@@ -489,6 +492,73 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
        }
        mdev = &ipi_mbox->dev;
 
+       /* Get the IPI remote agent ID */
+       ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
+       if (ret < 0) {
+               dev_err(dev, "No IPI remote ID is specified.\n");
+               return ret;
+       }
+
+       ret = ipi_mbox->setup_ipi_fn(ipi_mbox, node);
+       if (ret) {
+               dev_err(dev, "Failed to set up IPI Buffers.\n");
+               return ret;
+       }
+
+       mbox = &ipi_mbox->mbox;
+       mbox->dev = mdev;
+       mbox->ops = &zynqmp_ipi_chan_ops;
+       mbox->num_chans = 2;
+       mbox->txdone_irq = false;
+       mbox->txdone_poll = true;
+       mbox->txpoll_period = 5;
+       mbox->of_xlate = zynqmp_ipi_of_xlate;
+       chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
+       if (!chans)
+               return -ENOMEM;
+       mbox->chans = chans;
+       chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
+       chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
+       ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
+       ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
+       ret = devm_mbox_controller_register(mdev, mbox);
+       if (ret)
+               dev_err(mdev,
+                       "Failed to register mbox_controller(%d)\n", ret);
+       else
+               dev_info(mdev,
+                        "Registered ZynqMP IPI mbox with TX/RX channels.\n");
+       return ret;
+}
+
+/**
+ * zynqmp_ipi_setup - set up IPI Buffers for classic flow
+ *
+ * @ipi_mbox: pointer to IPI mailbox private data structure
+ * @node: IPI mailbox device node
+ *
+ * This will be used to set up IPI Buffers for ZynqMP SOC if user
+ * wishes to use classic driver usage model on new SOC's with only
+ * buffered IPIs.
+ *
+ * Note that bufferless IPIs and mixed usage of buffered and bufferless
+ * IPIs are not supported with this flow.
+ *
+ * This will be invoked with compatible string "xlnx,zynqmp-ipi-mailbox".
+ *
+ * Return: 0 for success, negative value for failure
+ */
+static int zynqmp_ipi_setup(struct zynqmp_ipi_mbox *ipi_mbox,
+                           struct device_node *node)
+{
+       struct zynqmp_ipi_mchan *mchan;
+       struct device *mdev;
+       struct resource res;
+       const char *name;
+       int ret;
+
+       mdev = &ipi_mbox->dev;
+
        mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
        name = "local_request_region";
        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,
        if (!mchan->rx_buf)
                return -ENOMEM;
 
-       /* Get the IPI remote agent ID */
-       ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
-       if (ret < 0) {
-               dev_err(dev, "No IPI remote ID is specified.\n");
-               return ret;
-       }
-
-       mbox = &ipi_mbox->mbox;
-       mbox->dev = mdev;
-       mbox->ops = &zynqmp_ipi_chan_ops;
-       mbox->num_chans = 2;
-       mbox->txdone_irq = false;
-       mbox->txdone_poll = true;
-       mbox->txpoll_period = 5;
-       mbox->of_xlate = zynqmp_ipi_of_xlate;
-       chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
-       if (!chans)
-               return -ENOMEM;
-       mbox->chans = chans;
-       chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
-       chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
-       ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
-       ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
-       ret = devm_mbox_controller_register(mdev, mbox);
-       if (ret)
-               dev_err(mdev,
-                       "Failed to register mbox_controller(%d)\n", ret);
-       else
-               dev_info(mdev,
-                        "Registered ZynqMP IPI mbox with TX/RX channels.\n");
-       return ret;
+       return 0;
 }
 
 /**
@@ -624,6 +664,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
        struct zynqmp_ipi_pdata *pdata;
        struct zynqmp_ipi_mbox *mbox;
        int num_mboxes, ret = -EINVAL;
+       setup_ipi_fn ipi_fn;
 
        num_mboxes = of_get_available_child_count(np);
        if (num_mboxes == 0) {
@@ -644,9 +685,18 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
                return ret;
        }
 
+       ipi_fn = (setup_ipi_fn)device_get_match_data(&pdev->dev);
+       if (!ipi_fn) {
+               dev_err(dev,
+                       "Mbox Compatible String is missing IPI Setup fn.\n");
+               return -ENODEV;
+       }
+
        pdata->num_mboxes = num_mboxes;
 
        mbox = pdata->ipi_mboxes;
+       mbox->setup_ipi_fn = ipi_fn;
+
        for_each_available_child_of_node(np, nc) {
                mbox->pdata = pdata;
                ret = zynqmp_ipi_mbox_probe(mbox, nc);
@@ -690,7 +740,9 @@ static void zynqmp_ipi_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id zynqmp_ipi_of_match[] = {
-       { .compatible = "xlnx,zynqmp-ipi-mailbox" },
+       { .compatible = "xlnx,zynqmp-ipi-mailbox",
+         .data = &zynqmp_ipi_setup,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);