aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSricharan R <sricharan@codeaurora.org>2016-06-13 07:36:05 -0400
committerJoerg Roedel <jroedel@suse.de>2016-06-21 07:57:13 -0400
commitf78ebca8ff3d61fb45fef1274595a72d1314d955 (patch)
tree9f177fd118bc148b5a1e7595468579e378679377
parentf7f125ef0b0210a2eb269148df9a1d641521857b (diff)
iommu/msm: Add support for generic master bindings
This adds the xlate callback which gets invoked during device registration from DT. The master devices gets added through this. Signed-off-by: Sricharan R <sricharan@codeaurora.org> Tested-by: Archit Taneja <architt@codeaurora.org> Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/msm_iommu.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 792b3526b4a5..8ab064324a68 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -28,6 +28,7 @@
28#include <linux/iommu.h> 28#include <linux/iommu.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/of_iommu.h>
31 32
32#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
33#include <asm/sizes.h> 34#include <asm/sizes.h>
@@ -702,6 +703,54 @@ static void print_ctx_regs(void __iomem *base, int ctx)
702 GET_PRRR(base, ctx), GET_NMRR(base, ctx)); 703 GET_PRRR(base, ctx), GET_NMRR(base, ctx));
703} 704}
704 705
706static void insert_iommu_master(struct device *dev,
707 struct msm_iommu_dev **iommu,
708 struct of_phandle_args *spec)
709{
710 struct msm_iommu_ctx_dev *master = dev->archdata.iommu;
711 int sid;
712
713 if (list_empty(&(*iommu)->ctx_list)) {
714 master = kzalloc(sizeof(*master), GFP_ATOMIC);
715 master->of_node = dev->of_node;
716 list_add(&master->list, &(*iommu)->ctx_list);
717 dev->archdata.iommu = master;
718 }
719
720 for (sid = 0; sid < master->num_mids; sid++)
721 if (master->mids[sid] == spec->args[0]) {
722 dev_warn(dev, "Stream ID 0x%hx repeated; ignoring\n",
723 sid);
724 return;
725 }
726
727 master->mids[master->num_mids++] = spec->args[0];
728}
729
730static int qcom_iommu_of_xlate(struct device *dev,
731 struct of_phandle_args *spec)
732{
733 struct msm_iommu_dev *iommu;
734 unsigned long flags;
735 int ret = 0;
736
737 spin_lock_irqsave(&msm_iommu_lock, flags);
738 list_for_each_entry(iommu, &qcom_iommu_devices, dev_node)
739 if (iommu->dev->of_node == spec->np)
740 break;
741
742 if (!iommu || iommu->dev->of_node != spec->np) {
743 ret = -ENODEV;
744 goto fail;
745 }
746
747 insert_iommu_master(dev, &iommu, spec);
748fail:
749 spin_unlock_irqrestore(&msm_iommu_lock, flags);
750
751 return ret;
752}
753
705irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) 754irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
706{ 755{
707 struct msm_iommu_dev *iommu = dev_id; 756 struct msm_iommu_dev *iommu = dev_id;
@@ -737,7 +786,7 @@ fail:
737 return 0; 786 return 0;
738} 787}
739 788
740static const struct iommu_ops msm_iommu_ops = { 789static struct iommu_ops msm_iommu_ops = {
741 .capable = msm_iommu_capable, 790 .capable = msm_iommu_capable,
742 .domain_alloc = msm_iommu_domain_alloc, 791 .domain_alloc = msm_iommu_domain_alloc,
743 .domain_free = msm_iommu_domain_free, 792 .domain_free = msm_iommu_domain_free,
@@ -748,6 +797,7 @@ static const struct iommu_ops msm_iommu_ops = {
748 .map_sg = default_iommu_map_sg, 797 .map_sg = default_iommu_map_sg,
749 .iova_to_phys = msm_iommu_iova_to_phys, 798 .iova_to_phys = msm_iommu_iova_to_phys,
750 .pgsize_bitmap = MSM_IOMMU_PGSIZES, 799 .pgsize_bitmap = MSM_IOMMU_PGSIZES,
800 .of_xlate = qcom_iommu_of_xlate,
751}; 801};
752 802
753static int msm_iommu_probe(struct platform_device *pdev) 803static int msm_iommu_probe(struct platform_device *pdev)
@@ -837,6 +887,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
837 } 887 }
838 888
839 list_add(&iommu->dev_node, &qcom_iommu_devices); 889 list_add(&iommu->dev_node, &qcom_iommu_devices);
890 of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops);
840 891
841 pr_info("device mapped at %p, irq %d with %d ctx banks\n", 892 pr_info("device mapped at %p, irq %d with %d ctx banks\n",
842 iommu->base, iommu->irq, iommu->ncb); 893 iommu->base, iommu->irq, iommu->ncb);
@@ -935,7 +986,13 @@ static int __init msm_iommu_init(void)
935 return 0; 986 return 0;
936} 987}
937 988
938subsys_initcall(msm_iommu_init); 989static int __init msm_iommu_of_setup(struct device_node *np)
990{
991 msm_iommu_init();
992 return 0;
993}
994
995IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
939 996
940MODULE_LICENSE("GPL v2"); 997MODULE_LICENSE("GPL v2");
941MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>"); 998MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");