diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-03-26 08:43:10 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-03-31 09:32:04 -0400 |
commit | 1d672638fca24db2a66101c2109d94dbee084e96 (patch) | |
tree | 8a69eccda1a07c0be0d47e2441ef0cf4162ced69 /drivers/iommu | |
parent | 8cf851e0945251766e8bf1f966a9aef80663ed63 (diff) |
iommu/arm-smmu: Make use of domain_alloc and domain_free
Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index fc13dd56953e..5575c3d485d0 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -343,6 +343,7 @@ struct arm_smmu_domain { | |||
343 | struct arm_smmu_cfg cfg; | 343 | struct arm_smmu_cfg cfg; |
344 | enum arm_smmu_domain_stage stage; | 344 | enum arm_smmu_domain_stage stage; |
345 | struct mutex init_mutex; /* Protects smmu pointer */ | 345 | struct mutex init_mutex; /* Protects smmu pointer */ |
346 | struct iommu_domain domain; | ||
346 | }; | 347 | }; |
347 | 348 | ||
348 | static struct iommu_ops arm_smmu_ops; | 349 | static struct iommu_ops arm_smmu_ops; |
@@ -360,6 +361,11 @@ static struct arm_smmu_option_prop arm_smmu_options[] = { | |||
360 | { 0, NULL}, | 361 | { 0, NULL}, |
361 | }; | 362 | }; |
362 | 363 | ||
364 | static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) | ||
365 | { | ||
366 | return container_of(dom, struct arm_smmu_domain, domain); | ||
367 | } | ||
368 | |||
363 | static void parse_driver_options(struct arm_smmu_device *smmu) | 369 | static void parse_driver_options(struct arm_smmu_device *smmu) |
364 | { | 370 | { |
365 | int i = 0; | 371 | int i = 0; |
@@ -645,7 +651,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
645 | u32 fsr, far, fsynr, resume; | 651 | u32 fsr, far, fsynr, resume; |
646 | unsigned long iova; | 652 | unsigned long iova; |
647 | struct iommu_domain *domain = dev; | 653 | struct iommu_domain *domain = dev; |
648 | struct arm_smmu_domain *smmu_domain = domain->priv; | 654 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
649 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 655 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
650 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 656 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
651 | void __iomem *cb_base; | 657 | void __iomem *cb_base; |
@@ -836,7 +842,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
836 | struct io_pgtable_ops *pgtbl_ops; | 842 | struct io_pgtable_ops *pgtbl_ops; |
837 | struct io_pgtable_cfg pgtbl_cfg; | 843 | struct io_pgtable_cfg pgtbl_cfg; |
838 | enum io_pgtable_fmt fmt; | 844 | enum io_pgtable_fmt fmt; |
839 | struct arm_smmu_domain *smmu_domain = domain->priv; | 845 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
840 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 846 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
841 | 847 | ||
842 | mutex_lock(&smmu_domain->init_mutex); | 848 | mutex_lock(&smmu_domain->init_mutex); |
@@ -958,7 +964,7 @@ out_unlock: | |||
958 | 964 | ||
959 | static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | 965 | static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) |
960 | { | 966 | { |
961 | struct arm_smmu_domain *smmu_domain = domain->priv; | 967 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
962 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 968 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
963 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 969 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
964 | void __iomem *cb_base; | 970 | void __iomem *cb_base; |
@@ -985,10 +991,12 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | |||
985 | __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); | 991 | __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); |
986 | } | 992 | } |
987 | 993 | ||
988 | static int arm_smmu_domain_init(struct iommu_domain *domain) | 994 | static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) |
989 | { | 995 | { |
990 | struct arm_smmu_domain *smmu_domain; | 996 | struct arm_smmu_domain *smmu_domain; |
991 | 997 | ||
998 | if (type != IOMMU_DOMAIN_UNMANAGED) | ||
999 | return NULL; | ||
992 | /* | 1000 | /* |
993 | * Allocate the domain and initialise some of its data structures. | 1001 | * Allocate the domain and initialise some of its data structures. |
994 | * We can't really do anything meaningful until we've added a | 1002 | * We can't really do anything meaningful until we've added a |
@@ -996,17 +1004,17 @@ static int arm_smmu_domain_init(struct iommu_domain *domain) | |||
996 | */ | 1004 | */ |
997 | smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL); | 1005 | smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL); |
998 | if (!smmu_domain) | 1006 | if (!smmu_domain) |
999 | return -ENOMEM; | 1007 | return NULL; |
1000 | 1008 | ||
1001 | mutex_init(&smmu_domain->init_mutex); | 1009 | mutex_init(&smmu_domain->init_mutex); |
1002 | spin_lock_init(&smmu_domain->pgtbl_lock); | 1010 | spin_lock_init(&smmu_domain->pgtbl_lock); |
1003 | domain->priv = smmu_domain; | 1011 | |
1004 | return 0; | 1012 | return &smmu_domain->domain; |
1005 | } | 1013 | } |
1006 | 1014 | ||
1007 | static void arm_smmu_domain_destroy(struct iommu_domain *domain) | 1015 | static void arm_smmu_domain_free(struct iommu_domain *domain) |
1008 | { | 1016 | { |
1009 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1017 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1010 | 1018 | ||
1011 | /* | 1019 | /* |
1012 | * Free the domain resources. We assume that all devices have | 1020 | * Free the domain resources. We assume that all devices have |
@@ -1143,7 +1151,7 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | |||
1143 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 1151 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
1144 | { | 1152 | { |
1145 | int ret; | 1153 | int ret; |
1146 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1154 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1147 | struct arm_smmu_device *smmu; | 1155 | struct arm_smmu_device *smmu; |
1148 | struct arm_smmu_master_cfg *cfg; | 1156 | struct arm_smmu_master_cfg *cfg; |
1149 | 1157 | ||
@@ -1187,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1187 | 1195 | ||
1188 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | 1196 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) |
1189 | { | 1197 | { |
1190 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1198 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1191 | struct arm_smmu_master_cfg *cfg; | 1199 | struct arm_smmu_master_cfg *cfg; |
1192 | 1200 | ||
1193 | cfg = find_smmu_master_cfg(dev); | 1201 | cfg = find_smmu_master_cfg(dev); |
@@ -1203,7 +1211,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, | |||
1203 | { | 1211 | { |
1204 | int ret; | 1212 | int ret; |
1205 | unsigned long flags; | 1213 | unsigned long flags; |
1206 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1214 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1207 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; | 1215 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; |
1208 | 1216 | ||
1209 | if (!ops) | 1217 | if (!ops) |
@@ -1220,7 +1228,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, | |||
1220 | { | 1228 | { |
1221 | size_t ret; | 1229 | size_t ret; |
1222 | unsigned long flags; | 1230 | unsigned long flags; |
1223 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1231 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1224 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; | 1232 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; |
1225 | 1233 | ||
1226 | if (!ops) | 1234 | if (!ops) |
@@ -1235,7 +1243,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, | |||
1235 | static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, | 1243 | static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, |
1236 | dma_addr_t iova) | 1244 | dma_addr_t iova) |
1237 | { | 1245 | { |
1238 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1246 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1239 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 1247 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
1240 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 1248 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
1241 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; | 1249 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; |
@@ -1281,7 +1289,7 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, | |||
1281 | { | 1289 | { |
1282 | phys_addr_t ret; | 1290 | phys_addr_t ret; |
1283 | unsigned long flags; | 1291 | unsigned long flags; |
1284 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1292 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1285 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; | 1293 | struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; |
1286 | 1294 | ||
1287 | if (!ops) | 1295 | if (!ops) |
@@ -1389,7 +1397,7 @@ static void arm_smmu_remove_device(struct device *dev) | |||
1389 | static int arm_smmu_domain_get_attr(struct iommu_domain *domain, | 1397 | static int arm_smmu_domain_get_attr(struct iommu_domain *domain, |
1390 | enum iommu_attr attr, void *data) | 1398 | enum iommu_attr attr, void *data) |
1391 | { | 1399 | { |
1392 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1400 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1393 | 1401 | ||
1394 | switch (attr) { | 1402 | switch (attr) { |
1395 | case DOMAIN_ATTR_NESTING: | 1403 | case DOMAIN_ATTR_NESTING: |
@@ -1404,7 +1412,7 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, | |||
1404 | enum iommu_attr attr, void *data) | 1412 | enum iommu_attr attr, void *data) |
1405 | { | 1413 | { |
1406 | int ret = 0; | 1414 | int ret = 0; |
1407 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1415 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1408 | 1416 | ||
1409 | mutex_lock(&smmu_domain->init_mutex); | 1417 | mutex_lock(&smmu_domain->init_mutex); |
1410 | 1418 | ||
@@ -1432,8 +1440,8 @@ out_unlock: | |||
1432 | 1440 | ||
1433 | static struct iommu_ops arm_smmu_ops = { | 1441 | static struct iommu_ops arm_smmu_ops = { |
1434 | .capable = arm_smmu_capable, | 1442 | .capable = arm_smmu_capable, |
1435 | .domain_init = arm_smmu_domain_init, | 1443 | .domain_alloc = arm_smmu_domain_alloc, |
1436 | .domain_destroy = arm_smmu_domain_destroy, | 1444 | .domain_free = arm_smmu_domain_free, |
1437 | .attach_dev = arm_smmu_attach_dev, | 1445 | .attach_dev = arm_smmu_attach_dev, |
1438 | .detach_dev = arm_smmu_detach_dev, | 1446 | .detach_dev = arm_smmu_detach_dev, |
1439 | .map = arm_smmu_map, | 1447 | .map = arm_smmu_map, |