diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-03-07 18:44:38 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-04-16 10:30:18 -0400 |
commit | 286f600bc890347f7ec7bd50d33210d53a9095a3 (patch) | |
tree | e6af94983a711b69aeb5f5208fc6082d3ab3442d /drivers/iommu | |
parent | 67b779d28d6e8afdd79a70423324273018114cad (diff) |
iommu/omap: Fix map protection value handling
The prot flags passed to the IOMMU map handler are defined in
include/linux/iommu.h as IOMMU_(READ|WRITE|CACHE|EXEC). However, the
driver expects to receive MMU_RAM_* OMAP-specific flags. This causes
IOMMU flags being interpreted as page sizes, leading to failures.
Hardcode the OMAP mapping parameters to little-endian, 8-bits and
non-mixed page attributes. Furthermore, as the OMAP IOMMU doesn't
support read-only or write-only mappings, ignore the prot value.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Suman Anna <s-anna@ti.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/omap-iommu.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 31cebf20285c..895af06a667f 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -1041,8 +1041,7 @@ static void iopte_cachep_ctor(void *iopte) | |||
1041 | clean_dcache_area(iopte, IOPTE_TABLE_SIZE); | 1041 | clean_dcache_area(iopte, IOPTE_TABLE_SIZE); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, | 1044 | static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, int pgsz) |
1045 | u32 flags) | ||
1046 | { | 1045 | { |
1047 | memset(e, 0, sizeof(*e)); | 1046 | memset(e, 0, sizeof(*e)); |
1048 | 1047 | ||
@@ -1050,10 +1049,10 @@ static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, | |||
1050 | e->pa = pa; | 1049 | e->pa = pa; |
1051 | e->valid = MMU_CAM_V; | 1050 | e->valid = MMU_CAM_V; |
1052 | /* FIXME: add OMAP1 support */ | 1051 | /* FIXME: add OMAP1 support */ |
1053 | e->pgsz = flags & MMU_CAM_PGSZ_MASK; | 1052 | e->pgsz = pgsz; |
1054 | e->endian = flags & MMU_RAM_ENDIAN_MASK; | 1053 | e->endian = MMU_RAM_ENDIAN_LITTLE; |
1055 | e->elsz = flags & MMU_RAM_ELSZ_MASK; | 1054 | e->elsz = MMU_RAM_ELSZ_8; |
1056 | e->mixed = flags & MMU_RAM_MIXED_MASK; | 1055 | e->mixed = 0; |
1057 | 1056 | ||
1058 | return iopgsz_to_bytes(e->pgsz); | 1057 | return iopgsz_to_bytes(e->pgsz); |
1059 | } | 1058 | } |
@@ -1066,7 +1065,7 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, | |||
1066 | struct device *dev = oiommu->dev; | 1065 | struct device *dev = oiommu->dev; |
1067 | struct iotlb_entry e; | 1066 | struct iotlb_entry e; |
1068 | int omap_pgsz; | 1067 | int omap_pgsz; |
1069 | u32 ret, flags; | 1068 | u32 ret; |
1070 | 1069 | ||
1071 | omap_pgsz = bytes_to_iopgsz(bytes); | 1070 | omap_pgsz = bytes_to_iopgsz(bytes); |
1072 | if (omap_pgsz < 0) { | 1071 | if (omap_pgsz < 0) { |
@@ -1076,9 +1075,7 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, | |||
1076 | 1075 | ||
1077 | dev_dbg(dev, "mapping da 0x%lx to pa 0x%x size 0x%x\n", da, pa, bytes); | 1076 | dev_dbg(dev, "mapping da 0x%lx to pa 0x%x size 0x%x\n", da, pa, bytes); |
1078 | 1077 | ||
1079 | flags = omap_pgsz | prot; | 1078 | iotlb_init_entry(&e, da, pa, omap_pgsz); |
1080 | |||
1081 | iotlb_init_entry(&e, da, pa, flags); | ||
1082 | 1079 | ||
1083 | ret = omap_iopgtable_store_entry(oiommu, &e); | 1080 | ret = omap_iopgtable_store_entry(oiommu, &e); |
1084 | if (ret) | 1081 | if (ret) |