aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mailbox
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2014-09-10 15:20:59 -0400
committerTony Lindgren <tony@atomide.com>2014-09-11 14:39:14 -0400
commit75288cc66dc478b32e43970dd6913396526504ae (patch)
tree570a96edd8b09de0204e038513ddcbcc4e96cfd4 /drivers/mailbox
parentd800386343df6fd07264665244b4d6a7ed21abec (diff)
mailbox/omap: add support for parsing dt devices
Logic has been added to the OMAP2+ mailbox code to parse the mailbox dt nodes and construct the different sub-mailboxes associated with the instance. The DT representation of the sub-mailbox devices is different from legacy platform data representation to allow flexibility of interrupt configuration between Tx and Rx fifos (to also possibly allow simplex devices in the future). The DT representation gathers similar information that was being passed previously through the platform data, except for the interrupt type information, which is gathered through driver compatible match data. The non-DT support has to be maintained for now to not break OMAP3 legacy boot, and the legacy-style code will be cleaned up once OMAP3 is also converted to DT-boot only. Cc: Jassi Brar <jassisinghbrar@gmail.com> Cc: Rob Herring <robh+dt@kernel.org> Signed-off-by: Suman Anna <s-anna@ti.com> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/mailbox')
-rw-r--r--drivers/mailbox/omap-mailbox.c156
1 files changed, 132 insertions, 24 deletions
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index a27e00e63a8a..bcc7ee129276 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -31,6 +31,7 @@
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/notifier.h> 32#include <linux/notifier.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/of_device.h>
34#include <linux/platform_device.h> 35#include <linux/platform_device.h>
35#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
36#include <linux/platform_data/mailbox-omap.h> 37#include <linux/platform_data/mailbox-omap.h>
@@ -94,6 +95,18 @@ struct omap_mbox_device {
94 struct list_head elem; 95 struct list_head elem;
95}; 96};
96 97
98struct omap_mbox_fifo_info {
99 int tx_id;
100 int tx_usr;
101 int tx_irq;
102
103 int rx_id;
104 int rx_usr;
105 int rx_irq;
106
107 const char *name;
108};
109
97struct omap_mbox { 110struct omap_mbox {
98 const char *name; 111 const char *name;
99 int irq; 112 int irq;
@@ -587,24 +600,118 @@ static int omap_mbox_unregister(struct omap_mbox_device *mdev)
587 return 0; 600 return 0;
588} 601}
589 602
603static const struct of_device_id omap_mailbox_of_match[] = {
604 {
605 .compatible = "ti,omap2-mailbox",
606 .data = (void *)MBOX_INTR_CFG_TYPE1,
607 },
608 {
609 .compatible = "ti,omap3-mailbox",
610 .data = (void *)MBOX_INTR_CFG_TYPE1,
611 },
612 {
613 .compatible = "ti,omap4-mailbox",
614 .data = (void *)MBOX_INTR_CFG_TYPE2,
615 },
616 {
617 /* end */
618 },
619};
620MODULE_DEVICE_TABLE(of, omap_mailbox_of_match);
621
590static int omap_mbox_probe(struct platform_device *pdev) 622static int omap_mbox_probe(struct platform_device *pdev)
591{ 623{
592 struct resource *mem; 624 struct resource *mem;
593 int ret; 625 int ret;
594 struct omap_mbox **list, *mbox, *mboxblk; 626 struct omap_mbox **list, *mbox, *mboxblk;
595 struct omap_mbox_pdata *pdata = pdev->dev.platform_data; 627 struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
596 struct omap_mbox_dev_info *info; 628 struct omap_mbox_dev_info *info = NULL;
629 struct omap_mbox_fifo_info *finfo, *finfoblk;
597 struct omap_mbox_device *mdev; 630 struct omap_mbox_device *mdev;
598 struct omap_mbox_fifo *fifo; 631 struct omap_mbox_fifo *fifo;
599 u32 intr_type; 632 struct device_node *node = pdev->dev.of_node;
633 struct device_node *child;
634 const struct of_device_id *match;
635 u32 intr_type, info_count;
636 u32 num_users, num_fifos;
637 u32 tmp[3];
600 u32 l; 638 u32 l;
601 int i; 639 int i;
602 640
603 if (!pdata || !pdata->info_cnt || !pdata->info) { 641 if (!node && (!pdata || !pdata->info_cnt || !pdata->info)) {
604 pr_err("%s: platform not supported\n", __func__); 642 pr_err("%s: platform not supported\n", __func__);
605 return -ENODEV; 643 return -ENODEV;
606 } 644 }
607 645
646 if (node) {
647 match = of_match_device(omap_mailbox_of_match, &pdev->dev);
648 if (!match)
649 return -ENODEV;
650 intr_type = (u32)match->data;
651
652 if (of_property_read_u32(node, "ti,mbox-num-users",
653 &num_users))
654 return -ENODEV;
655
656 if (of_property_read_u32(node, "ti,mbox-num-fifos",
657 &num_fifos))
658 return -ENODEV;
659
660 info_count = of_get_available_child_count(node);
661 if (!info_count) {
662 dev_err(&pdev->dev, "no available mbox devices found\n");
663 return -ENODEV;
664 }
665 } else { /* non-DT device creation */
666 info_count = pdata->info_cnt;
667 info = pdata->info;
668 intr_type = pdata->intr_type;
669 num_users = pdata->num_users;
670 num_fifos = pdata->num_fifos;
671 }
672
673 finfoblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*finfoblk),
674 GFP_KERNEL);
675 if (!finfoblk)
676 return -ENOMEM;
677
678 finfo = finfoblk;
679 child = NULL;
680 for (i = 0; i < info_count; i++, finfo++) {
681 if (node) {
682 child = of_get_next_available_child(node, child);
683 ret = of_property_read_u32_array(child, "ti,mbox-tx",
684 tmp, ARRAY_SIZE(tmp));
685 if (ret)
686 return ret;
687 finfo->tx_id = tmp[0];
688 finfo->tx_irq = tmp[1];
689 finfo->tx_usr = tmp[2];
690
691 ret = of_property_read_u32_array(child, "ti,mbox-rx",
692 tmp, ARRAY_SIZE(tmp));
693 if (ret)
694 return ret;
695 finfo->rx_id = tmp[0];
696 finfo->rx_irq = tmp[1];
697 finfo->rx_usr = tmp[2];
698
699 finfo->name = child->name;
700 } else {
701 finfo->tx_id = info->tx_id;
702 finfo->rx_id = info->rx_id;
703 finfo->tx_usr = info->usr_id;
704 finfo->tx_irq = info->irq_id;
705 finfo->rx_usr = info->usr_id;
706 finfo->rx_irq = info->irq_id;
707 finfo->name = info->name;
708 info++;
709 }
710 if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
711 finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
712 return -EINVAL;
713 }
714
608 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL); 715 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
609 if (!mdev) 716 if (!mdev)
610 return -ENOMEM; 717 return -ENOMEM;
@@ -615,41 +722,40 @@ static int omap_mbox_probe(struct platform_device *pdev)
615 return PTR_ERR(mdev->mbox_base); 722 return PTR_ERR(mdev->mbox_base);
616 723
617 /* allocate one extra for marking end of list */ 724 /* allocate one extra for marking end of list */
618 list = devm_kzalloc(&pdev->dev, (pdata->info_cnt + 1) * sizeof(*list), 725 list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list),
619 GFP_KERNEL); 726 GFP_KERNEL);
620 if (!list) 727 if (!list)
621 return -ENOMEM; 728 return -ENOMEM;
622 729
623 mboxblk = devm_kzalloc(&pdev->dev, pdata->info_cnt * sizeof(*mbox), 730 mboxblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*mbox),
624 GFP_KERNEL); 731 GFP_KERNEL);
625 if (!mboxblk) 732 if (!mboxblk)
626 return -ENOMEM; 733 return -ENOMEM;
627 734
628 info = pdata->info;
629 intr_type = pdata->intr_type;
630 mbox = mboxblk; 735 mbox = mboxblk;
631 for (i = 0; i < pdata->info_cnt; i++, info++) { 736 finfo = finfoblk;
737 for (i = 0; i < info_count; i++, finfo++) {
632 fifo = &mbox->tx_fifo; 738 fifo = &mbox->tx_fifo;
633 fifo->msg = MAILBOX_MESSAGE(info->tx_id); 739 fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
634 fifo->fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); 740 fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
635 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); 741 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
636 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id); 742 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->tx_usr);
637 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id); 743 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->tx_usr);
638 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id); 744 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->tx_usr);
639 745
640 fifo = &mbox->rx_fifo; 746 fifo = &mbox->rx_fifo;
641 fifo->msg = MAILBOX_MESSAGE(info->rx_id); 747 fifo->msg = MAILBOX_MESSAGE(finfo->rx_id);
642 fifo->msg_stat = MAILBOX_MSGSTATUS(info->rx_id); 748 fifo->msg_stat = MAILBOX_MSGSTATUS(finfo->rx_id);
643 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); 749 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(finfo->rx_id);
644 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id); 750 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->rx_usr);
645 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id); 751 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->rx_usr);
646 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id); 752 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->rx_usr);
647 753
648 mbox->intr_type = intr_type; 754 mbox->intr_type = intr_type;
649 755
650 mbox->parent = mdev; 756 mbox->parent = mdev;
651 mbox->name = info->name; 757 mbox->name = finfo->name;
652 mbox->irq = platform_get_irq(pdev, info->irq_id); 758 mbox->irq = platform_get_irq(pdev, finfo->tx_irq);
653 if (mbox->irq < 0) 759 if (mbox->irq < 0)
654 return mbox->irq; 760 return mbox->irq;
655 list[i] = mbox++; 761 list[i] = mbox++;
@@ -657,8 +763,8 @@ static int omap_mbox_probe(struct platform_device *pdev)
657 763
658 mutex_init(&mdev->cfg_lock); 764 mutex_init(&mdev->cfg_lock);
659 mdev->dev = &pdev->dev; 765 mdev->dev = &pdev->dev;
660 mdev->num_users = pdata->num_users; 766 mdev->num_users = num_users;
661 mdev->num_fifos = pdata->num_fifos; 767 mdev->num_fifos = num_fifos;
662 mdev->mboxes = list; 768 mdev->mboxes = list;
663 ret = omap_mbox_register(mdev); 769 ret = omap_mbox_register(mdev);
664 if (ret) 770 if (ret)
@@ -684,6 +790,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
684 if (ret < 0) 790 if (ret < 0)
685 goto unregister; 791 goto unregister;
686 792
793 devm_kfree(&pdev->dev, finfoblk);
687 return 0; 794 return 0;
688 795
689unregister: 796unregister:
@@ -708,6 +815,7 @@ static struct platform_driver omap_mbox_driver = {
708 .driver = { 815 .driver = {
709 .name = "omap-mailbox", 816 .name = "omap-mailbox",
710 .owner = THIS_MODULE, 817 .owner = THIS_MODULE,
818 .of_match_table = of_match_ptr(omap_mailbox_of_match),
711 }, 819 },
712}; 820};
713 821