diff options
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 246 |
1 files changed, 160 insertions, 86 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 81e8ec290756..373b6e4d6e15 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/of.h> | 41 | #include <linux/of.h> |
42 | #include <linux/pci.h> | ||
42 | #include <linux/platform_device.h> | 43 | #include <linux/platform_device.h> |
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
44 | #include <linux/spinlock.h> | 45 | #include <linux/spinlock.h> |
@@ -329,14 +330,7 @@ struct arm_smmu_smr { | |||
329 | u16 id; | 330 | u16 id; |
330 | }; | 331 | }; |
331 | 332 | ||
332 | struct arm_smmu_master { | 333 | struct arm_smmu_master_cfg { |
333 | struct device_node *of_node; | ||
334 | |||
335 | /* | ||
336 | * The following is specific to the master's position in the | ||
337 | * SMMU chain. | ||
338 | */ | ||
339 | struct rb_node node; | ||
340 | int num_streamids; | 334 | int num_streamids; |
341 | u16 streamids[MAX_MASTER_STREAMIDS]; | 335 | u16 streamids[MAX_MASTER_STREAMIDS]; |
342 | 336 | ||
@@ -347,6 +341,17 @@ struct arm_smmu_master { | |||
347 | struct arm_smmu_smr *smrs; | 341 | struct arm_smmu_smr *smrs; |
348 | }; | 342 | }; |
349 | 343 | ||
344 | struct arm_smmu_master { | ||
345 | struct device_node *of_node; | ||
346 | |||
347 | /* | ||
348 | * The following is specific to the master's position in the | ||
349 | * SMMU chain. | ||
350 | */ | ||
351 | struct rb_node node; | ||
352 | struct arm_smmu_master_cfg cfg; | ||
353 | }; | ||
354 | |||
350 | struct arm_smmu_device { | 355 | struct arm_smmu_device { |
351 | struct device *dev; | 356 | struct device *dev; |
352 | struct device_node *parent_of_node; | 357 | struct device_node *parent_of_node; |
@@ -437,6 +442,18 @@ static void parse_driver_options(struct arm_smmu_device *smmu) | |||
437 | } while (arm_smmu_options[++i].opt); | 442 | } while (arm_smmu_options[++i].opt); |
438 | } | 443 | } |
439 | 444 | ||
445 | static struct device *dev_get_master_dev(struct device *dev) | ||
446 | { | ||
447 | if (dev_is_pci(dev)) { | ||
448 | struct pci_bus *bus = to_pci_dev(dev)->bus; | ||
449 | while (!pci_is_root_bus(bus)) | ||
450 | bus = bus->parent; | ||
451 | return bus->bridge->parent; | ||
452 | } | ||
453 | |||
454 | return dev; | ||
455 | } | ||
456 | |||
440 | static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, | 457 | static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, |
441 | struct device_node *dev_node) | 458 | struct device_node *dev_node) |
442 | { | 459 | { |
@@ -457,6 +474,18 @@ static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, | |||
457 | return NULL; | 474 | return NULL; |
458 | } | 475 | } |
459 | 476 | ||
477 | static struct arm_smmu_master_cfg * | ||
478 | find_smmu_master_cfg(struct arm_smmu_device *smmu, struct device *dev) | ||
479 | { | ||
480 | struct arm_smmu_master *master; | ||
481 | |||
482 | if (dev_is_pci(dev)) | ||
483 | return dev->archdata.iommu; | ||
484 | |||
485 | master = find_smmu_master(smmu, dev->of_node); | ||
486 | return master ? &master->cfg : NULL; | ||
487 | } | ||
488 | |||
460 | static int insert_smmu_master(struct arm_smmu_device *smmu, | 489 | static int insert_smmu_master(struct arm_smmu_device *smmu, |
461 | struct arm_smmu_master *master) | 490 | struct arm_smmu_master *master) |
462 | { | 491 | { |
@@ -508,11 +537,11 @@ static int register_smmu_master(struct arm_smmu_device *smmu, | |||
508 | if (!master) | 537 | if (!master) |
509 | return -ENOMEM; | 538 | return -ENOMEM; |
510 | 539 | ||
511 | master->of_node = masterspec->np; | 540 | master->of_node = masterspec->np; |
512 | master->num_streamids = masterspec->args_count; | 541 | master->cfg.num_streamids = masterspec->args_count; |
513 | 542 | ||
514 | for (i = 0; i < master->num_streamids; ++i) | 543 | for (i = 0; i < master->cfg.num_streamids; ++i) |
515 | master->streamids[i] = masterspec->args[i]; | 544 | master->cfg.streamids[i] = masterspec->args[i]; |
516 | 545 | ||
517 | return insert_smmu_master(smmu, master); | 546 | return insert_smmu_master(smmu, master); |
518 | } | 547 | } |
@@ -537,6 +566,42 @@ out_unlock: | |||
537 | return parent; | 566 | return parent; |
538 | } | 567 | } |
539 | 568 | ||
569 | static struct arm_smmu_device *find_parent_smmu_for_device(struct device *dev) | ||
570 | { | ||
571 | struct arm_smmu_device *child, *parent, *smmu; | ||
572 | struct arm_smmu_master *master = NULL; | ||
573 | struct device_node *dev_node = dev_get_master_dev(dev)->of_node; | ||
574 | |||
575 | spin_lock(&arm_smmu_devices_lock); | ||
576 | list_for_each_entry(parent, &arm_smmu_devices, list) { | ||
577 | smmu = parent; | ||
578 | |||
579 | /* Try to find a child of the current SMMU. */ | ||
580 | list_for_each_entry(child, &arm_smmu_devices, list) { | ||
581 | if (child->parent_of_node == parent->dev->of_node) { | ||
582 | /* Does the child sit above our master? */ | ||
583 | master = find_smmu_master(child, dev_node); | ||
584 | if (master) { | ||
585 | smmu = NULL; | ||
586 | break; | ||
587 | } | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /* We found some children, so keep searching. */ | ||
592 | if (!smmu) { | ||
593 | master = NULL; | ||
594 | continue; | ||
595 | } | ||
596 | |||
597 | master = find_smmu_master(smmu, dev_node); | ||
598 | if (master) | ||
599 | break; | ||
600 | } | ||
601 | spin_unlock(&arm_smmu_devices_lock); | ||
602 | return master ? smmu : NULL; | ||
603 | } | ||
604 | |||
540 | static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) | 605 | static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) |
541 | { | 606 | { |
542 | int idx; | 607 | int idx; |
@@ -855,7 +920,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
855 | } | 920 | } |
856 | 921 | ||
857 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, | 922 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, |
858 | struct device *dev) | 923 | struct device *dev, |
924 | struct arm_smmu_device *device_smmu) | ||
859 | { | 925 | { |
860 | int irq, ret, start; | 926 | int irq, ret, start; |
861 | struct arm_smmu_domain *smmu_domain = domain->priv; | 927 | struct arm_smmu_domain *smmu_domain = domain->priv; |
@@ -868,15 +934,15 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
868 | * early, and therefore check that the root SMMU does indeed have | 934 | * early, and therefore check that the root SMMU does indeed have |
869 | * a StreamID for the master in question. | 935 | * a StreamID for the master in question. |
870 | */ | 936 | */ |
871 | parent = dev->archdata.iommu; | 937 | parent = device_smmu; |
872 | smmu_domain->output_mask = -1; | 938 | smmu_domain->output_mask = -1; |
873 | do { | 939 | do { |
874 | smmu = parent; | 940 | smmu = parent; |
875 | smmu_domain->output_mask &= (1ULL << smmu->s2_output_size) - 1; | 941 | smmu_domain->output_mask &= (1ULL << smmu->s2_output_size) - 1; |
876 | } while ((parent = find_parent_smmu(smmu))); | 942 | } while ((parent = find_parent_smmu(smmu))); |
877 | 943 | ||
878 | if (!find_smmu_master(smmu, dev->of_node)) { | 944 | if (!find_smmu_master_cfg(smmu, dev)) { |
879 | dev_err(dev, "unable to find root SMMU for device\n"); | 945 | dev_err(dev, "unable to find root SMMU config for device\n"); |
880 | return -ENODEV; | 946 | return -ENODEV; |
881 | } | 947 | } |
882 | 948 | ||
@@ -920,7 +986,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
920 | 986 | ||
921 | root_cfg->smmu = smmu; | 987 | root_cfg->smmu = smmu; |
922 | arm_smmu_init_context_bank(smmu_domain); | 988 | arm_smmu_init_context_bank(smmu_domain); |
923 | return ret; | 989 | smmu_domain->leaf_smmu = device_smmu; |
990 | return 0; | ||
924 | 991 | ||
925 | out_free_context: | 992 | out_free_context: |
926 | __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx); | 993 | __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx); |
@@ -1056,7 +1123,7 @@ static void arm_smmu_domain_destroy(struct iommu_domain *domain) | |||
1056 | } | 1123 | } |
1057 | 1124 | ||
1058 | static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | 1125 | static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, |
1059 | struct arm_smmu_master *master) | 1126 | struct arm_smmu_master_cfg *cfg) |
1060 | { | 1127 | { |
1061 | int i; | 1128 | int i; |
1062 | struct arm_smmu_smr *smrs; | 1129 | struct arm_smmu_smr *smrs; |
@@ -1065,18 +1132,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | |||
1065 | if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) | 1132 | if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) |
1066 | return 0; | 1133 | return 0; |
1067 | 1134 | ||
1068 | if (master->smrs) | 1135 | if (cfg->smrs) |
1069 | return -EEXIST; | 1136 | return -EEXIST; |
1070 | 1137 | ||
1071 | smrs = kmalloc(sizeof(*smrs) * master->num_streamids, GFP_KERNEL); | 1138 | smrs = kmalloc(sizeof(*smrs) * cfg->num_streamids, GFP_KERNEL); |
1072 | if (!smrs) { | 1139 | if (!smrs) { |
1073 | dev_err(smmu->dev, "failed to allocate %d SMRs for master %s\n", | 1140 | dev_err(smmu->dev, "failed to allocate %d SMRs\n", |
1074 | master->num_streamids, master->of_node->name); | 1141 | cfg->num_streamids); |
1075 | return -ENOMEM; | 1142 | return -ENOMEM; |
1076 | } | 1143 | } |
1077 | 1144 | ||
1078 | /* Allocate the SMRs on the root SMMU */ | 1145 | /* Allocate the SMRs on the root SMMU */ |
1079 | for (i = 0; i < master->num_streamids; ++i) { | 1146 | for (i = 0; i < cfg->num_streamids; ++i) { |
1080 | int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0, | 1147 | int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0, |
1081 | smmu->num_mapping_groups); | 1148 | smmu->num_mapping_groups); |
1082 | if (IS_ERR_VALUE(idx)) { | 1149 | if (IS_ERR_VALUE(idx)) { |
@@ -1087,18 +1154,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | |||
1087 | smrs[i] = (struct arm_smmu_smr) { | 1154 | smrs[i] = (struct arm_smmu_smr) { |
1088 | .idx = idx, | 1155 | .idx = idx, |
1089 | .mask = 0, /* We don't currently share SMRs */ | 1156 | .mask = 0, /* We don't currently share SMRs */ |
1090 | .id = master->streamids[i], | 1157 | .id = cfg->streamids[i], |
1091 | }; | 1158 | }; |
1092 | } | 1159 | } |
1093 | 1160 | ||
1094 | /* It worked! Now, poke the actual hardware */ | 1161 | /* It worked! Now, poke the actual hardware */ |
1095 | for (i = 0; i < master->num_streamids; ++i) { | 1162 | for (i = 0; i < cfg->num_streamids; ++i) { |
1096 | u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT | | 1163 | u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT | |
1097 | smrs[i].mask << SMR_MASK_SHIFT; | 1164 | smrs[i].mask << SMR_MASK_SHIFT; |
1098 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx)); | 1165 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx)); |
1099 | } | 1166 | } |
1100 | 1167 | ||
1101 | master->smrs = smrs; | 1168 | cfg->smrs = smrs; |
1102 | return 0; | 1169 | return 0; |
1103 | 1170 | ||
1104 | err_free_smrs: | 1171 | err_free_smrs: |
@@ -1109,44 +1176,44 @@ err_free_smrs: | |||
1109 | } | 1176 | } |
1110 | 1177 | ||
1111 | static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, | 1178 | static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, |
1112 | struct arm_smmu_master *master) | 1179 | struct arm_smmu_master_cfg *cfg) |
1113 | { | 1180 | { |
1114 | int i; | 1181 | int i; |
1115 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1182 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
1116 | struct arm_smmu_smr *smrs = master->smrs; | 1183 | struct arm_smmu_smr *smrs = cfg->smrs; |
1117 | 1184 | ||
1118 | /* Invalidate the SMRs before freeing back to the allocator */ | 1185 | /* Invalidate the SMRs before freeing back to the allocator */ |
1119 | for (i = 0; i < master->num_streamids; ++i) { | 1186 | for (i = 0; i < cfg->num_streamids; ++i) { |
1120 | u8 idx = smrs[i].idx; | 1187 | u8 idx = smrs[i].idx; |
1121 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx)); | 1188 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx)); |
1122 | __arm_smmu_free_bitmap(smmu->smr_map, idx); | 1189 | __arm_smmu_free_bitmap(smmu->smr_map, idx); |
1123 | } | 1190 | } |
1124 | 1191 | ||
1125 | master->smrs = NULL; | 1192 | cfg->smrs = NULL; |
1126 | kfree(smrs); | 1193 | kfree(smrs); |
1127 | } | 1194 | } |
1128 | 1195 | ||
1129 | static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu, | 1196 | static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu, |
1130 | struct arm_smmu_master *master) | 1197 | struct arm_smmu_master_cfg *cfg) |
1131 | { | 1198 | { |
1132 | int i; | 1199 | int i; |
1133 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1200 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
1134 | 1201 | ||
1135 | for (i = 0; i < master->num_streamids; ++i) { | 1202 | for (i = 0; i < cfg->num_streamids; ++i) { |
1136 | u16 sid = master->streamids[i]; | 1203 | u16 sid = cfg->streamids[i]; |
1137 | writel_relaxed(S2CR_TYPE_BYPASS, | 1204 | writel_relaxed(S2CR_TYPE_BYPASS, |
1138 | gr0_base + ARM_SMMU_GR0_S2CR(sid)); | 1205 | gr0_base + ARM_SMMU_GR0_S2CR(sid)); |
1139 | } | 1206 | } |
1140 | } | 1207 | } |
1141 | 1208 | ||
1142 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | 1209 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, |
1143 | struct arm_smmu_master *master) | 1210 | struct arm_smmu_master_cfg *cfg) |
1144 | { | 1211 | { |
1145 | int i, ret; | 1212 | int i, ret; |
1146 | struct arm_smmu_device *parent, *smmu = smmu_domain->root_cfg.smmu; | 1213 | struct arm_smmu_device *parent, *smmu = smmu_domain->root_cfg.smmu; |
1147 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1214 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
1148 | 1215 | ||
1149 | ret = arm_smmu_master_configure_smrs(smmu, master); | 1216 | ret = arm_smmu_master_configure_smrs(smmu, cfg); |
1150 | if (ret) | 1217 | if (ret) |
1151 | return ret; | 1218 | return ret; |
1152 | 1219 | ||
@@ -1161,14 +1228,14 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | |||
1161 | if (smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) | 1228 | if (smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) |
1162 | continue; | 1229 | continue; |
1163 | 1230 | ||
1164 | arm_smmu_bypass_stream_mapping(smmu, master); | 1231 | arm_smmu_bypass_stream_mapping(smmu, cfg); |
1165 | smmu = parent; | 1232 | smmu = parent; |
1166 | } | 1233 | } |
1167 | 1234 | ||
1168 | /* Now we're at the root, time to point at our context bank */ | 1235 | /* Now we're at the root, time to point at our context bank */ |
1169 | for (i = 0; i < master->num_streamids; ++i) { | 1236 | for (i = 0; i < cfg->num_streamids; ++i) { |
1170 | u32 idx, s2cr; | 1237 | u32 idx, s2cr; |
1171 | idx = master->smrs ? master->smrs[i].idx : master->streamids[i]; | 1238 | idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; |
1172 | s2cr = S2CR_TYPE_TRANS | | 1239 | s2cr = S2CR_TYPE_TRANS | |
1173 | (smmu_domain->root_cfg.cbndx << S2CR_CBNDX_SHIFT); | 1240 | (smmu_domain->root_cfg.cbndx << S2CR_CBNDX_SHIFT); |
1174 | writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx)); | 1241 | writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx)); |
@@ -1178,7 +1245,7 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | |||
1178 | } | 1245 | } |
1179 | 1246 | ||
1180 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | 1247 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, |
1181 | struct arm_smmu_master *master) | 1248 | struct arm_smmu_master_cfg *cfg) |
1182 | { | 1249 | { |
1183 | struct arm_smmu_device *smmu = smmu_domain->root_cfg.smmu; | 1250 | struct arm_smmu_device *smmu = smmu_domain->root_cfg.smmu; |
1184 | 1251 | ||
@@ -1186,18 +1253,19 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | |||
1186 | * We *must* clear the S2CR first, because freeing the SMR means | 1253 | * We *must* clear the S2CR first, because freeing the SMR means |
1187 | * that it can be re-allocated immediately. | 1254 | * that it can be re-allocated immediately. |
1188 | */ | 1255 | */ |
1189 | arm_smmu_bypass_stream_mapping(smmu, master); | 1256 | arm_smmu_bypass_stream_mapping(smmu, cfg); |
1190 | arm_smmu_master_free_smrs(smmu, master); | 1257 | arm_smmu_master_free_smrs(smmu, cfg); |
1191 | } | 1258 | } |
1192 | 1259 | ||
1193 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 1260 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
1194 | { | 1261 | { |
1195 | int ret = -EINVAL; | 1262 | int ret = -EINVAL; |
1196 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1263 | struct arm_smmu_domain *smmu_domain = domain->priv; |
1197 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; | 1264 | struct arm_smmu_device *device_smmu; |
1198 | struct arm_smmu_master *master; | 1265 | struct arm_smmu_master_cfg *cfg; |
1199 | unsigned long flags; | 1266 | unsigned long flags; |
1200 | 1267 | ||
1268 | device_smmu = dev_get_master_dev(dev)->archdata.iommu; | ||
1201 | if (!device_smmu) { | 1269 | if (!device_smmu) { |
1202 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); | 1270 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); |
1203 | return -ENXIO; | 1271 | return -ENXIO; |
@@ -1210,11 +1278,9 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1210 | spin_lock_irqsave(&smmu_domain->lock, flags); | 1278 | spin_lock_irqsave(&smmu_domain->lock, flags); |
1211 | if (!smmu_domain->leaf_smmu) { | 1279 | if (!smmu_domain->leaf_smmu) { |
1212 | /* Now that we have a master, we can finalise the domain */ | 1280 | /* Now that we have a master, we can finalise the domain */ |
1213 | ret = arm_smmu_init_domain_context(domain, dev); | 1281 | ret = arm_smmu_init_domain_context(domain, dev, device_smmu); |
1214 | if (IS_ERR_VALUE(ret)) | 1282 | if (IS_ERR_VALUE(ret)) |
1215 | goto err_unlock; | 1283 | goto err_unlock; |
1216 | |||
1217 | smmu_domain->leaf_smmu = device_smmu; | ||
1218 | } else if (smmu_domain->leaf_smmu != device_smmu) { | 1284 | } else if (smmu_domain->leaf_smmu != device_smmu) { |
1219 | dev_err(dev, | 1285 | dev_err(dev, |
1220 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", | 1286 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", |
@@ -1225,11 +1291,11 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1225 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | 1291 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
1226 | 1292 | ||
1227 | /* Looks ok, so add the device to the domain */ | 1293 | /* Looks ok, so add the device to the domain */ |
1228 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1294 | cfg = find_smmu_master_cfg(smmu_domain->leaf_smmu, dev); |
1229 | if (!master) | 1295 | if (!cfg) |
1230 | return -ENODEV; | 1296 | return -ENODEV; |
1231 | 1297 | ||
1232 | return arm_smmu_domain_add_master(smmu_domain, master); | 1298 | return arm_smmu_domain_add_master(smmu_domain, cfg); |
1233 | 1299 | ||
1234 | err_unlock: | 1300 | err_unlock: |
1235 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | 1301 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
@@ -1239,11 +1305,11 @@ err_unlock: | |||
1239 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | 1305 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) |
1240 | { | 1306 | { |
1241 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1307 | struct arm_smmu_domain *smmu_domain = domain->priv; |
1242 | struct arm_smmu_master *master; | 1308 | struct arm_smmu_master_cfg *cfg; |
1243 | 1309 | ||
1244 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1310 | cfg = find_smmu_master_cfg(smmu_domain->leaf_smmu, dev); |
1245 | if (master) | 1311 | if (cfg) |
1246 | arm_smmu_domain_remove_master(smmu_domain, master); | 1312 | arm_smmu_domain_remove_master(smmu_domain, cfg); |
1247 | } | 1313 | } |
1248 | 1314 | ||
1249 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, | 1315 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, |
@@ -1549,10 +1615,15 @@ static int arm_smmu_domain_has_cap(struct iommu_domain *domain, | |||
1549 | return !!(cap & caps); | 1615 | return !!(cap & caps); |
1550 | } | 1616 | } |
1551 | 1617 | ||
1618 | static int __arm_smmu_get_pci_sid(struct pci_dev *pdev, u16 alias, void *data) | ||
1619 | { | ||
1620 | *((u16 *)data) = alias; | ||
1621 | return 0; /* Continue walking */ | ||
1622 | } | ||
1623 | |||
1552 | static int arm_smmu_add_device(struct device *dev) | 1624 | static int arm_smmu_add_device(struct device *dev) |
1553 | { | 1625 | { |
1554 | struct arm_smmu_device *child, *parent, *smmu; | 1626 | struct arm_smmu_device *smmu; |
1555 | struct arm_smmu_master *master = NULL; | ||
1556 | struct iommu_group *group; | 1627 | struct iommu_group *group; |
1557 | int ret; | 1628 | int ret; |
1558 | 1629 | ||
@@ -1561,35 +1632,8 @@ static int arm_smmu_add_device(struct device *dev) | |||
1561 | return -EINVAL; | 1632 | return -EINVAL; |
1562 | } | 1633 | } |
1563 | 1634 | ||
1564 | spin_lock(&arm_smmu_devices_lock); | 1635 | smmu = find_parent_smmu_for_device(dev); |
1565 | list_for_each_entry(parent, &arm_smmu_devices, list) { | 1636 | if (!smmu) |
1566 | smmu = parent; | ||
1567 | |||
1568 | /* Try to find a child of the current SMMU. */ | ||
1569 | list_for_each_entry(child, &arm_smmu_devices, list) { | ||
1570 | if (child->parent_of_node == parent->dev->of_node) { | ||
1571 | /* Does the child sit above our master? */ | ||
1572 | master = find_smmu_master(child, dev->of_node); | ||
1573 | if (master) { | ||
1574 | smmu = NULL; | ||
1575 | break; | ||
1576 | } | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1580 | /* We found some children, so keep searching. */ | ||
1581 | if (!smmu) { | ||
1582 | master = NULL; | ||
1583 | continue; | ||
1584 | } | ||
1585 | |||
1586 | master = find_smmu_master(smmu, dev->of_node); | ||
1587 | if (master) | ||
1588 | break; | ||
1589 | } | ||
1590 | spin_unlock(&arm_smmu_devices_lock); | ||
1591 | |||
1592 | if (!master) | ||
1593 | return -ENODEV; | 1637 | return -ENODEV; |
1594 | 1638 | ||
1595 | group = iommu_group_alloc(); | 1639 | group = iommu_group_alloc(); |
@@ -1598,15 +1642,40 @@ static int arm_smmu_add_device(struct device *dev) | |||
1598 | return PTR_ERR(group); | 1642 | return PTR_ERR(group); |
1599 | } | 1643 | } |
1600 | 1644 | ||
1645 | if (dev_is_pci(dev)) { | ||
1646 | struct arm_smmu_master_cfg *cfg; | ||
1647 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1648 | |||
1649 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); | ||
1650 | if (!cfg) { | ||
1651 | ret = -ENOMEM; | ||
1652 | goto out_put_group; | ||
1653 | } | ||
1654 | |||
1655 | cfg->num_streamids = 1; | ||
1656 | /* | ||
1657 | * Assume Stream ID == Requester ID for now. | ||
1658 | * We need a way to describe the ID mappings in FDT. | ||
1659 | */ | ||
1660 | pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid, | ||
1661 | &cfg->streamids[0]); | ||
1662 | dev->archdata.iommu = cfg; | ||
1663 | } else { | ||
1664 | dev->archdata.iommu = smmu; | ||
1665 | } | ||
1666 | |||
1601 | ret = iommu_group_add_device(group, dev); | 1667 | ret = iommu_group_add_device(group, dev); |
1602 | iommu_group_put(group); | ||
1603 | dev->archdata.iommu = smmu; | ||
1604 | 1668 | ||
1669 | out_put_group: | ||
1670 | iommu_group_put(group); | ||
1605 | return ret; | 1671 | return ret; |
1606 | } | 1672 | } |
1607 | 1673 | ||
1608 | static void arm_smmu_remove_device(struct device *dev) | 1674 | static void arm_smmu_remove_device(struct device *dev) |
1609 | { | 1675 | { |
1676 | if (dev_is_pci(dev)) | ||
1677 | kfree(dev->archdata.iommu); | ||
1678 | |||
1610 | dev->archdata.iommu = NULL; | 1679 | dev->archdata.iommu = NULL; |
1611 | iommu_group_remove_device(dev); | 1680 | iommu_group_remove_device(dev); |
1612 | } | 1681 | } |
@@ -2050,6 +2119,11 @@ static int __init arm_smmu_init(void) | |||
2050 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); | 2119 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); |
2051 | #endif | 2120 | #endif |
2052 | 2121 | ||
2122 | #ifdef CONFIG_PCI | ||
2123 | if (!iommu_present(&pci_bus_type)) | ||
2124 | bus_set_iommu(&pci_bus_type, &arm_smmu_ops); | ||
2125 | #endif | ||
2126 | |||
2053 | return 0; | 2127 | return 0; |
2054 | } | 2128 | } |
2055 | 2129 | ||