diff options
author | Joerg Roedel <jroedel@suse.de> | 2017-02-02 12:52:34 -0500 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2017-02-10 07:44:57 -0500 |
commit | 42df43b36163ed7d0ab13992e411093252903273 (patch) | |
tree | 6d6adcc83c96ca415a944af283b99ca8ef583f5c | |
parent | 9648cbc9625b67c91ed1aaf4b8b77f3f0c537496 (diff) |
iommu/msm: Make use of iommu_device_register interface
Register the MSM IOMMUs to the iommu core and add sysfs
entries for that driver.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/msm_iommu.c | 73 | ||||
-rw-r--r-- | drivers/iommu/msm_iommu.h | 3 |
2 files changed, 76 insertions, 0 deletions
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index b09692bb5b0a..30795cbab5ef 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c | |||
@@ -371,6 +371,58 @@ static int msm_iommu_domain_config(struct msm_priv *priv) | |||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
374 | /* Must be called under msm_iommu_lock */ | ||
375 | static struct msm_iommu_dev *find_iommu_for_dev(struct device *dev) | ||
376 | { | ||
377 | struct msm_iommu_dev *iommu, *ret = NULL; | ||
378 | struct msm_iommu_ctx_dev *master; | ||
379 | |||
380 | list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) { | ||
381 | master = list_first_entry(&iommu->ctx_list, | ||
382 | struct msm_iommu_ctx_dev, | ||
383 | list); | ||
384 | if (master->of_node == dev->of_node) { | ||
385 | ret = iommu; | ||
386 | break; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | static int msm_iommu_add_device(struct device *dev) | ||
394 | { | ||
395 | struct msm_iommu_dev *iommu; | ||
396 | unsigned long flags; | ||
397 | int ret = 0; | ||
398 | |||
399 | spin_lock_irqsave(&msm_iommu_lock, flags); | ||
400 | |||
401 | iommu = find_iommu_for_dev(dev); | ||
402 | if (iommu) | ||
403 | iommu_device_link(&iommu->iommu, dev); | ||
404 | else | ||
405 | ret = -ENODEV; | ||
406 | |||
407 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | ||
408 | |||
409 | return ret; | ||
410 | } | ||
411 | |||
412 | static void msm_iommu_remove_device(struct device *dev) | ||
413 | { | ||
414 | struct msm_iommu_dev *iommu; | ||
415 | unsigned long flags; | ||
416 | |||
417 | spin_lock_irqsave(&msm_iommu_lock, flags); | ||
418 | |||
419 | iommu = find_iommu_for_dev(dev); | ||
420 | if (iommu) | ||
421 | iommu_device_unlink(&iommu->iommu, dev); | ||
422 | |||
423 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | ||
424 | } | ||
425 | |||
374 | static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) | 426 | static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) |
375 | { | 427 | { |
376 | int ret = 0; | 428 | int ret = 0; |
@@ -646,6 +698,8 @@ static struct iommu_ops msm_iommu_ops = { | |||
646 | .unmap = msm_iommu_unmap, | 698 | .unmap = msm_iommu_unmap, |
647 | .map_sg = default_iommu_map_sg, | 699 | .map_sg = default_iommu_map_sg, |
648 | .iova_to_phys = msm_iommu_iova_to_phys, | 700 | .iova_to_phys = msm_iommu_iova_to_phys, |
701 | .add_device = msm_iommu_add_device, | ||
702 | .remove_device = msm_iommu_remove_device, | ||
649 | .pgsize_bitmap = MSM_IOMMU_PGSIZES, | 703 | .pgsize_bitmap = MSM_IOMMU_PGSIZES, |
650 | .of_xlate = qcom_iommu_of_xlate, | 704 | .of_xlate = qcom_iommu_of_xlate, |
651 | }; | 705 | }; |
@@ -653,6 +707,7 @@ static struct iommu_ops msm_iommu_ops = { | |||
653 | static int msm_iommu_probe(struct platform_device *pdev) | 707 | static int msm_iommu_probe(struct platform_device *pdev) |
654 | { | 708 | { |
655 | struct resource *r; | 709 | struct resource *r; |
710 | resource_size_t ioaddr; | ||
656 | struct msm_iommu_dev *iommu; | 711 | struct msm_iommu_dev *iommu; |
657 | int ret, par, val; | 712 | int ret, par, val; |
658 | 713 | ||
@@ -696,6 +751,7 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
696 | ret = PTR_ERR(iommu->base); | 751 | ret = PTR_ERR(iommu->base); |
697 | goto fail; | 752 | goto fail; |
698 | } | 753 | } |
754 | ioaddr = r->start; | ||
699 | 755 | ||
700 | iommu->irq = platform_get_irq(pdev, 0); | 756 | iommu->irq = platform_get_irq(pdev, 0); |
701 | if (iommu->irq < 0) { | 757 | if (iommu->irq < 0) { |
@@ -737,6 +793,23 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
737 | } | 793 | } |
738 | 794 | ||
739 | list_add(&iommu->dev_node, &qcom_iommu_devices); | 795 | list_add(&iommu->dev_node, &qcom_iommu_devices); |
796 | |||
797 | ret = iommu_device_sysfs_add(&iommu->iommu, iommu->dev, NULL, | ||
798 | "msm-smmu.%pa", &ioaddr); | ||
799 | if (ret) { | ||
800 | pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr); | ||
801 | goto fail; | ||
802 | } | ||
803 | |||
804 | iommu_device_set_ops(&iommu->iommu, &msm_iommu_ops); | ||
805 | iommu_device_set_fwnode(&iommu->iommu, &pdev->dev.of_node->fwnode); | ||
806 | |||
807 | ret = iommu_device_register(&iommu->iommu); | ||
808 | if (ret) { | ||
809 | pr_err("Could not register msm-smmu at %pa\n", &ioaddr); | ||
810 | goto fail; | ||
811 | } | ||
812 | |||
740 | of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops); | 813 | of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops); |
741 | 814 | ||
742 | pr_info("device mapped at %p, irq %d with %d ctx banks\n", | 815 | pr_info("device mapped at %p, irq %d with %d ctx banks\n", |
diff --git a/drivers/iommu/msm_iommu.h b/drivers/iommu/msm_iommu.h index 4ca25d50d679..ae92d2779c42 100644 --- a/drivers/iommu/msm_iommu.h +++ b/drivers/iommu/msm_iommu.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define MSM_IOMMU_H | 19 | #define MSM_IOMMU_H |
20 | 20 | ||
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/iommu.h> | ||
22 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
23 | 24 | ||
24 | /* Sharability attributes of MSM IOMMU mappings */ | 25 | /* Sharability attributes of MSM IOMMU mappings */ |
@@ -68,6 +69,8 @@ struct msm_iommu_dev { | |||
68 | struct list_head dom_node; | 69 | struct list_head dom_node; |
69 | struct list_head ctx_list; | 70 | struct list_head ctx_list; |
70 | DECLARE_BITMAP(context_map, IOMMU_MAX_CBS); | 71 | DECLARE_BITMAP(context_map, IOMMU_MAX_CBS); |
72 | |||
73 | struct iommu_device iommu; | ||
71 | }; | 74 | }; |
72 | 75 | ||
73 | /** | 76 | /** |