[PATCH 2/3] mailbox/omap: add support for parsing dt devices
Russ Dill
Russ.Dill at ti.com
Thu Jun 20 12:11:28 EST 2013
On Tue, Jun 18, 2013 at 3:34 PM, Suman Anna <s-anna at ti.com> 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 at ti.com>
Reviewed-by: Russ Dill <russ.dill at ti.com>
> ---
> .../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 at 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 at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the devicetree-discuss
mailing list