On Tue, Jun 18, 2013 at 3:34 PM, Suman Anna <s-anna@xxxxxx> wrote: > Logic has been added to the OMAP2+ mailbox code to > parse the mailbox dt nodes and construct the different > mailboxes associated with the instance. The design is > based on gathering the same information that was being > passed previously through the platform data, except for > the interrupt type configuration information. > > Signed-off-by: Suman Anna <s-anna@xxxxxx> Reviewed-by: Russ Dill <russ.dill@xxxxxx> > --- > .../devicetree/bindings/mailbox/omap-mailbox.txt | 46 +++++++ > drivers/mailbox/mailbox-omap2.c | 141 ++++++++++++++++++--- > 2 files changed, 172 insertions(+), 15 deletions(-) > create mode 100644 Documentation/devicetree/bindings/mailbox/omap-mailbox.txt > > diff --git a/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt > new file mode 100644 > index 0000000..913bc13 > --- /dev/null > +++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt > @@ -0,0 +1,46 @@ > +OMAP2+ Mailbox Driver > + > +Required properties: > +- compatible: Should be one of the following, > + "ti,omap2-mailbox" for > + OMAP2420, OMAP2430, OMAP3430, OMAP3630 SoCs > + "ti,omap4-mailbox" for > + OMAP44xx, OMAP54xx, AM33xx, AM43xx, DRA7xx SoCs > +- reg: Contains the mailbox register address range (base address > + and length) > +- interrupts: Contains the interrupt information for the mailbox > + device. The format is dependent on which interrupt > + controller the OMAP device uses > +- ti,hwmods: Name of the hwmod associated with the mailbox > +- ti,mbox-num-users: Number of targets (processor devices) that the mailbox device > + can interrupt > +- ti,mbox-num-fifos: Number of h/w fifos within the mailbox device > +- #ti,mbox-data-cells: Cell size for describing a mailbox > + (currently should be 4) > +- ti,mbox-names: Array of the names of the mailboxes > +- ti,mbox-data: Mailbox descriptor data private to each mailbox. The 4 > + cells represent the following data, > + Cell #1 (tx_id) - mailbox fifo id used for > + transmitting messages > + Cell #2 (rx_id) - mailbox fifo id on which messages > + are received > + Cell #3 (irq_id) - irq identifier index number to use > + from the interrupts data > + Cell #4 (usr_id) - mailbox user id for identifying the > + interrupt into the MPU interrupt > + controller. > + > +Example: > + > +/* OMAP4 */ > +mailbox: mailbox@4a0f4000 { > + compatible = "ti,omap4-mailbox"; > + reg = <0x4a0f4000 0x200>; > + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; > + ti,hwmods = "mailbox"; > + ti,mbox-num-users = <3>; > + ti,mbox-num-fifos = <8>; > + #ti,mbox-data-cells = <4> > + ti,mbox-names = "mbox-ipu", "mbox-dsp"; > + ti,mbox-data = <0 1 0 0>, <3 2 0 0>; > +}; > diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c > index 6c0687c..3fe08de 100644 > --- a/drivers/mailbox/mailbox-omap2.c > +++ b/drivers/mailbox/mailbox-omap2.c > @@ -14,6 +14,7 @@ > #include <linux/slab.h> > #include <linux/clk.h> > #include <linux/err.h> > +#include <linux/of_device.h> > #include <linux/platform_device.h> > #include <linux/io.h> > #include <linux/pm_runtime.h> > @@ -222,6 +223,21 @@ static struct omap_mbox_ops omap2_mbox_ops = { > .restore_ctx = omap2_mbox_restore_ctx, > }; > > +static const struct of_device_id omap_mailbox_of_match[] = { > + { > + .compatible = "ti,omap2-mailbox", > + .data = (void *) MBOX_INTR_CFG_TYPE1, > + }, > + { > + .compatible = "ti,omap4-mailbox", > + .data = (void *) MBOX_INTR_CFG_TYPE2, > + }, > + { > + /* end */ > + }, > +}; > +MODULE_DEVICE_TABLE(of, omap_mailbox_of_match); > + > static int omap2_mbox_probe(struct platform_device *pdev) > { > struct resource *mem; > @@ -229,47 +245,138 @@ static int omap2_mbox_probe(struct platform_device *pdev) > struct omap_mbox **list, *mbox, *mboxblk; > struct omap_mbox2_priv *priv, *privblk; > struct omap_mbox_pdata *pdata = pdev->dev.platform_data; > - struct omap_mbox_dev_info *info; > struct omap_mbox_device *mdev; > - int i; > - > - if (!pdata || !pdata->info_cnt || !pdata->info) { > + struct omap_mbox_dev_info *info, *of_info = NULL; > + struct device_node *node = pdev->dev.of_node; > + int i, j; > + u32 info_count = 0, intr_type = 0; > + u32 num_users = 0, num_fifos = 0; > + u32 dlen, dsize; > + u32 *tmp; > + const __be32 *mbox_data; > + > + if (!node && (!pdata || !pdata->info_cnt || !pdata->info)) { > pr_err("%s: platform not supported\n", __func__); > return -ENODEV; > } > > + if (node) { > + intr_type = (u32)of_match_device(omap_mailbox_of_match, > + &pdev->dev)->data; > + if (intr_type != 0 && intr_type != 1) { > + dev_err(&pdev->dev, "invalid match data value\n"); > + return -EINVAL; > + } > + > + if (of_property_read_u32(node, "ti,mbox-num-users", > + &num_users)) { > + dev_err(&pdev->dev, > + "no ti,mbox-num-users configuration found\n"); > + return -ENODEV; > + } > + > + if (of_property_read_u32(node, "ti,mbox-num-fifos", > + &num_fifos)) { > + dev_err(&pdev->dev, > + "no ti,mbox-num-fifos configuration found\n"); > + return -ENODEV; > + } > + > + if (of_property_read_u32(node, "#ti,mbox-data-cells", &dsize)) { > + dev_err(&pdev->dev, > + "no #ti,mbox-data-cells configuration found\n"); > + return -ENODEV; > + } > + if (dsize != 4) { > + dev_err(&pdev->dev, > + "invalid size for #ti,mbox-data-cells\n"); > + return -EINVAL; > + } > + > + info_count = of_property_count_strings(node, "ti,mbox-names"); > + if (!info_count) { > + dev_err(&pdev->dev, "no mbox devices found\n"); > + return -ENODEV; > + } > + > + mbox_data = of_get_property(node, "ti,mbox-data", &dlen); > + if (!mbox_data) { > + dev_err(&pdev->dev, "no mbox device data found\n"); > + return -ENODEV; > + } > + dlen /= sizeof(dsize); > + if (dlen != dsize * info_count) { > + dev_err(&pdev->dev, "mbox device data is truncated\n"); > + return -ENODEV; > + } > + > + of_info = kzalloc(info_count * sizeof(*of_info), GFP_KERNEL); > + if (!of_info) > + return -ENOMEM; > + > + i = 0; > + while (i < info_count) { > + info = of_info + i; > + if (of_property_read_string_index(node, > + "ti,mbox-names", i, &info->name)) { > + dev_err(&pdev->dev, > + "mbox_name [%d] read failed\n", i); > + ret = -ENODEV; > + goto free_of; > + } > + > + tmp = &info->tx_id; > + for (j = 0; j < dsize; j++) { > + tmp[j] = of_read_number( > + mbox_data + j + (i * dsize), 1); > + } > + i++; > + } > + } > + > + if (!node) { /* non-DT device creation */ > + info_count = pdata->info_cnt; > + info = pdata->info; > + intr_type = pdata->intr_type; > + num_users = pdata->num_users; > + num_fifos = pdata->num_fifos; > + } else { > + info = of_info; > + } > + > mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); > - if (!mdev) > - return -ENOMEM; > + if (!mdev) { > + ret = -ENOMEM; > + goto free_of; > + } > > /* allocate one extra for marking end of list */ > - list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL); > + list = kzalloc((info_count + 1) * sizeof(*list), GFP_KERNEL); > if (!list) { > ret = -ENOMEM; > goto free_mdev; > } > > - mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL); > + mboxblk = mbox = kzalloc(info_count * sizeof(*mbox), GFP_KERNEL); > if (!mboxblk) { > ret = -ENOMEM; > goto free_list; > } > > - privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL); > + privblk = priv = kzalloc(info_count * sizeof(*priv), GFP_KERNEL); > if (!privblk) { > ret = -ENOMEM; > goto free_mboxblk; > } > > - info = pdata->info; > - for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { > + for (i = 0; i < info_count; i++, info++, priv++) { > priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); > priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); > priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); > priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); > priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); > priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); > - if (pdata->intr_type) { > + if (intr_type) { > priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id); > priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id); > priv->irqdisable = > @@ -279,7 +386,7 @@ static int omap2_mbox_probe(struct platform_device *pdev) > priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id); > priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id); > } > - priv->intr_type = pdata->intr_type; > + priv->intr_type = intr_type; > > mbox->priv = priv; > mbox->parent = mdev; > @@ -307,8 +414,8 @@ static int omap2_mbox_probe(struct platform_device *pdev) > > mutex_init(&mdev->cfg_lock); > mdev->dev = &pdev->dev; > - mdev->num_users = pdata->num_users; > - mdev->num_fifos = pdata->num_fifos; > + mdev->num_users = num_users; > + mdev->num_fifos = num_fifos; > mdev->mboxes = list; > ret = omap_mbox_register(&pdev->dev, list); > if (ret) > @@ -317,6 +424,7 @@ static int omap2_mbox_probe(struct platform_device *pdev) > > pm_runtime_enable(mdev->dev); > > + kfree(of_info); > return 0; > > unmap_mbox: > @@ -329,6 +437,8 @@ free_list: > kfree(list); > free_mdev: > kfree(mdev); > +free_of: > + kfree(of_info); > return ret; > } > > @@ -358,6 +468,7 @@ static struct platform_driver omap2_mbox_driver = { > .remove = omap2_mbox_remove, > .driver = { > .name = "omap-mailbox", > + .of_match_table = omap_mailbox_of_match, > }, > }; > > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html