aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/omap-iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/omap-iommu.c')
-rw-r--r--drivers/iommu/omap-iommu.c80
1 files changed, 37 insertions, 43 deletions
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 8f32b2bf758..d8edd979d01 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -33,6 +33,9 @@
33 (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ 33 (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \
34 __i++) 34 __i++)
35 35
36/* bitmap of the page sizes currently supported */
37#define OMAP_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)
38
36/** 39/**
37 * struct omap_iommu_domain - omap iommu domain 40 * struct omap_iommu_domain - omap iommu domain
38 * @pgtable: the page table 41 * @pgtable: the page table
@@ -86,20 +89,24 @@ EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch);
86 89
87/** 90/**
88 * omap_iommu_save_ctx - Save registers for pm off-mode support 91 * omap_iommu_save_ctx - Save registers for pm off-mode support
89 * @obj: target iommu 92 * @dev: client device
90 **/ 93 **/
91void omap_iommu_save_ctx(struct omap_iommu *obj) 94void omap_iommu_save_ctx(struct device *dev)
92{ 95{
96 struct omap_iommu *obj = dev_to_omap_iommu(dev);
97
93 arch_iommu->save_ctx(obj); 98 arch_iommu->save_ctx(obj);
94} 99}
95EXPORT_SYMBOL_GPL(omap_iommu_save_ctx); 100EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
96 101
97/** 102/**
98 * omap_iommu_restore_ctx - Restore registers for pm off-mode support 103 * omap_iommu_restore_ctx - Restore registers for pm off-mode support
99 * @obj: target iommu 104 * @dev: client device
100 **/ 105 **/
101void omap_iommu_restore_ctx(struct omap_iommu *obj) 106void omap_iommu_restore_ctx(struct device *dev)
102{ 107{
108 struct omap_iommu *obj = dev_to_omap_iommu(dev);
109
103 arch_iommu->restore_ctx(obj); 110 arch_iommu->restore_ctx(obj);
104} 111}
105EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); 112EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);
@@ -820,35 +827,23 @@ static int device_match_by_alias(struct device *dev, void *data)
820} 827}
821 828
822/** 829/**
823 * omap_find_iommu_device() - find an omap iommu device by name
824 * @name: name of the iommu device
825 *
826 * The generic iommu API requires the caller to provide the device
827 * he wishes to attach to a certain iommu domain.
828 *
829 * Drivers generally should not bother with this as it should just
830 * be taken care of by the DMA-API using dev_archdata.
831 *
832 * This function is provided as an interim solution until the latter
833 * materializes, and omap3isp is fully migrated to the DMA-API.
834 */
835struct device *omap_find_iommu_device(const char *name)
836{
837 return driver_find_device(&omap_iommu_driver.driver, NULL,
838 (void *)name,
839 device_match_by_alias);
840}
841EXPORT_SYMBOL_GPL(omap_find_iommu_device);
842
843/**
844 * omap_iommu_attach() - attach iommu device to an iommu domain 830 * omap_iommu_attach() - attach iommu device to an iommu domain
845 * @dev: target omap iommu device 831 * @name: name of target omap iommu device
846 * @iopgd: page table 832 * @iopgd: page table
847 **/ 833 **/
848static struct omap_iommu *omap_iommu_attach(struct device *dev, u32 *iopgd) 834static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
849{ 835{
850 int err = -ENOMEM; 836 int err = -ENOMEM;
851 struct omap_iommu *obj = to_iommu(dev); 837 struct device *dev;
838 struct omap_iommu *obj;
839
840 dev = driver_find_device(&omap_iommu_driver.driver, NULL,
841 (void *)name,
842 device_match_by_alias);
843 if (!dev)
844 return NULL;
845
846 obj = to_iommu(dev);
852 847
853 spin_lock(&obj->iommu_lock); 848 spin_lock(&obj->iommu_lock);
854 849
@@ -1019,12 +1014,11 @@ static void iopte_cachep_ctor(void *iopte)
1019} 1014}
1020 1015
1021static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, 1016static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
1022 phys_addr_t pa, int order, int prot) 1017 phys_addr_t pa, size_t bytes, int prot)
1023{ 1018{
1024 struct omap_iommu_domain *omap_domain = domain->priv; 1019 struct omap_iommu_domain *omap_domain = domain->priv;
1025 struct omap_iommu *oiommu = omap_domain->iommu_dev; 1020 struct omap_iommu *oiommu = omap_domain->iommu_dev;
1026 struct device *dev = oiommu->dev; 1021 struct device *dev = oiommu->dev;
1027 size_t bytes = PAGE_SIZE << order;
1028 struct iotlb_entry e; 1022 struct iotlb_entry e;
1029 int omap_pgsz; 1023 int omap_pgsz;
1030 u32 ret, flags; 1024 u32 ret, flags;
@@ -1049,19 +1043,16 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
1049 return ret; 1043 return ret;
1050} 1044}
1051 1045
1052static int omap_iommu_unmap(struct iommu_domain *domain, unsigned long da, 1046static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
1053 int order) 1047 size_t size)
1054{ 1048{
1055 struct omap_iommu_domain *omap_domain = domain->priv; 1049 struct omap_iommu_domain *omap_domain = domain->priv;
1056 struct omap_iommu *oiommu = omap_domain->iommu_dev; 1050 struct omap_iommu *oiommu = omap_domain->iommu_dev;
1057 struct device *dev = oiommu->dev; 1051 struct device *dev = oiommu->dev;
1058 size_t unmap_size;
1059
1060 dev_dbg(dev, "unmapping da 0x%lx order %d\n", da, order);
1061 1052
1062 unmap_size = iopgtable_clear_entry(oiommu, da); 1053 dev_dbg(dev, "unmapping da 0x%lx size %u\n", da, size);
1063 1054
1064 return unmap_size ? get_order(unmap_size) : -EINVAL; 1055 return iopgtable_clear_entry(oiommu, da);
1065} 1056}
1066 1057
1067static int 1058static int
@@ -1069,6 +1060,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
1069{ 1060{
1070 struct omap_iommu_domain *omap_domain = domain->priv; 1061 struct omap_iommu_domain *omap_domain = domain->priv;
1071 struct omap_iommu *oiommu; 1062 struct omap_iommu *oiommu;
1063 struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
1072 int ret = 0; 1064 int ret = 0;
1073 1065
1074 spin_lock(&omap_domain->lock); 1066 spin_lock(&omap_domain->lock);
@@ -1081,14 +1073,14 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
1081 } 1073 }
1082 1074
1083 /* get a handle to and enable the omap iommu */ 1075 /* get a handle to and enable the omap iommu */
1084 oiommu = omap_iommu_attach(dev, omap_domain->pgtable); 1076 oiommu = omap_iommu_attach(arch_data->name, omap_domain->pgtable);
1085 if (IS_ERR(oiommu)) { 1077 if (IS_ERR(oiommu)) {
1086 ret = PTR_ERR(oiommu); 1078 ret = PTR_ERR(oiommu);
1087 dev_err(dev, "can't get omap iommu: %d\n", ret); 1079 dev_err(dev, "can't get omap iommu: %d\n", ret);
1088 goto out; 1080 goto out;
1089 } 1081 }
1090 1082
1091 omap_domain->iommu_dev = oiommu; 1083 omap_domain->iommu_dev = arch_data->iommu_dev = oiommu;
1092 oiommu->domain = domain; 1084 oiommu->domain = domain;
1093 1085
1094out: 1086out:
@@ -1100,7 +1092,8 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain,
1100 struct device *dev) 1092 struct device *dev)
1101{ 1093{
1102 struct omap_iommu_domain *omap_domain = domain->priv; 1094 struct omap_iommu_domain *omap_domain = domain->priv;
1103 struct omap_iommu *oiommu = to_iommu(dev); 1095 struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
1096 struct omap_iommu *oiommu = dev_to_omap_iommu(dev);
1104 1097
1105 spin_lock(&omap_domain->lock); 1098 spin_lock(&omap_domain->lock);
1106 1099
@@ -1114,7 +1107,7 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain,
1114 1107
1115 omap_iommu_detach(oiommu); 1108 omap_iommu_detach(oiommu);
1116 1109
1117 omap_domain->iommu_dev = NULL; 1110 omap_domain->iommu_dev = arch_data->iommu_dev = NULL;
1118 1111
1119out: 1112out:
1120 spin_unlock(&omap_domain->lock); 1113 spin_unlock(&omap_domain->lock);
@@ -1183,14 +1176,14 @@ static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain,
1183 else if (iopte_is_large(*pte)) 1176 else if (iopte_is_large(*pte))
1184 ret = omap_iommu_translate(*pte, da, IOLARGE_MASK); 1177 ret = omap_iommu_translate(*pte, da, IOLARGE_MASK);
1185 else 1178 else
1186 dev_err(dev, "bogus pte 0x%x", *pte); 1179 dev_err(dev, "bogus pte 0x%x, da 0x%lx", *pte, da);
1187 } else { 1180 } else {
1188 if (iopgd_is_section(*pgd)) 1181 if (iopgd_is_section(*pgd))
1189 ret = omap_iommu_translate(*pgd, da, IOSECTION_MASK); 1182 ret = omap_iommu_translate(*pgd, da, IOSECTION_MASK);
1190 else if (iopgd_is_super(*pgd)) 1183 else if (iopgd_is_super(*pgd))
1191 ret = omap_iommu_translate(*pgd, da, IOSUPER_MASK); 1184 ret = omap_iommu_translate(*pgd, da, IOSUPER_MASK);
1192 else 1185 else
1193 dev_err(dev, "bogus pgd 0x%x", *pgd); 1186 dev_err(dev, "bogus pgd 0x%x, da 0x%lx", *pgd, da);
1194 } 1187 }
1195 1188
1196 return ret; 1189 return ret;
@@ -1211,6 +1204,7 @@ static struct iommu_ops omap_iommu_ops = {
1211 .unmap = omap_iommu_unmap, 1204 .unmap = omap_iommu_unmap,
1212 .iova_to_phys = omap_iommu_iova_to_phys, 1205 .iova_to_phys = omap_iommu_iova_to_phys,
1213 .domain_has_cap = omap_iommu_domain_has_cap, 1206 .domain_has_cap = omap_iommu_domain_has_cap,
1207 .pgsize_bitmap = OMAP_IOMMU_PGSIZES,
1214}; 1208};
1215 1209
1216static int __init omap_iommu_init(void) 1210static int __init omap_iommu_init(void)