summaryrefslogtreecommitdiffstats
path: root/drivers/mailbox
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2016-04-06 19:37:18 -0400
committerJassi Brar <jaswinder.singh@linaro.org>2016-04-26 00:49:38 -0400
commitaf1d2f5cb9d24f0e477158dada6baf893a32ee04 (patch)
treed88c0fd9404e510c205a535f1c329bdba6a68b36 /drivers/mailbox
parent2240f8aefcaea151653e70fbf3eef09650fa027c (diff)
mailbox/omap: add support for suspend/resume
Support has been added to the OMAP mailbox driver to allow it to work across a system suspend/resume. The OMAP mailbox driver requires only the interrupt configuration registers to be saved and restored, and this is done in the suspend/resume callbacks. The registers need to be saved only if there are active clients at the time of suspend. The enabling and disabling of the mailbox clocks is done automatically by the omap_device layer. Signed-off-by: Suman Anna <s-anna@ti.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Diffstat (limited to 'drivers/mailbox')
-rw-r--r--drivers/mailbox/omap-mailbox.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index d837def4c390..e402aa23226d 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -88,6 +88,7 @@ struct omap_mbox_device {
88 struct device *dev; 88 struct device *dev;
89 struct mutex cfg_lock; 89 struct mutex cfg_lock;
90 void __iomem *mbox_base; 90 void __iomem *mbox_base;
91 u32 *irq_ctx;
91 u32 num_users; 92 u32 num_users;
92 u32 num_fifos; 93 u32 num_fifos;
93 u32 intr_type; 94 u32 intr_type;
@@ -650,6 +651,44 @@ static const struct mbox_chan_ops omap_mbox_chan_ops = {
650 .shutdown = omap_mbox_chan_shutdown, 651 .shutdown = omap_mbox_chan_shutdown,
651}; 652};
652 653
654#ifdef CONFIG_PM_SLEEP
655static int omap_mbox_suspend(struct device *dev)
656{
657 struct omap_mbox_device *mdev = dev_get_drvdata(dev);
658 u32 usr, reg;
659
660 if (pm_runtime_status_suspended(dev))
661 return 0;
662
663 for (usr = 0; usr < mdev->num_users; usr++) {
664 reg = MAILBOX_IRQENABLE(mdev->intr_type, usr);
665 mdev->irq_ctx[usr] = mbox_read_reg(mdev, reg);
666 }
667
668 return 0;
669}
670
671static int omap_mbox_resume(struct device *dev)
672{
673 struct omap_mbox_device *mdev = dev_get_drvdata(dev);
674 u32 usr, reg;
675
676 if (pm_runtime_status_suspended(dev))
677 return 0;
678
679 for (usr = 0; usr < mdev->num_users; usr++) {
680 reg = MAILBOX_IRQENABLE(mdev->intr_type, usr);
681 mbox_write_reg(mdev, mdev->irq_ctx[usr], reg);
682 }
683
684 return 0;
685}
686#endif
687
688static const struct dev_pm_ops omap_mbox_pm_ops = {
689 SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend, omap_mbox_resume)
690};
691
653static const struct of_device_id omap_mailbox_of_match[] = { 692static const struct of_device_id omap_mailbox_of_match[] = {
654 { 693 {
655 .compatible = "ti,omap2-mailbox", 694 .compatible = "ti,omap2-mailbox",
@@ -777,6 +816,11 @@ static int omap_mbox_probe(struct platform_device *pdev)
777 if (IS_ERR(mdev->mbox_base)) 816 if (IS_ERR(mdev->mbox_base))
778 return PTR_ERR(mdev->mbox_base); 817 return PTR_ERR(mdev->mbox_base);
779 818
819 mdev->irq_ctx = devm_kzalloc(&pdev->dev, num_users * sizeof(u32),
820 GFP_KERNEL);
821 if (!mdev->irq_ctx)
822 return -ENOMEM;
823
780 /* allocate one extra for marking end of list */ 824 /* allocate one extra for marking end of list */
781 list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list), 825 list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list),
782 GFP_KERNEL); 826 GFP_KERNEL);
@@ -887,6 +931,7 @@ static struct platform_driver omap_mbox_driver = {
887 .remove = omap_mbox_remove, 931 .remove = omap_mbox_remove,
888 .driver = { 932 .driver = {
889 .name = "omap-mailbox", 933 .name = "omap-mailbox",
934 .pm = &omap_mbox_pm_ops,
890 .of_match_table = of_match_ptr(omap_mailbox_of_match), 935 .of_match_table = of_match_ptr(omap_mailbox_of_match),
891 }, 936 },
892}; 937};