diff options
-rw-r--r-- | drivers/iommu/amd_iommu.c | 14 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 6 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_types.h | 3 | ||||
-rw-r--r-- | drivers/iommu/dmar.c | 13 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 15 | ||||
-rw-r--r-- | drivers/iommu/iommu-sysfs.c | 45 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 1 | ||||
-rw-r--r-- | include/linux/iommu.h | 33 |
8 files changed, 61 insertions, 69 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 689d88fa29a6..4fee2fdbef3e 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -445,6 +445,7 @@ static void init_iommu_group(struct device *dev) | |||
445 | static int iommu_init_device(struct device *dev) | 445 | static int iommu_init_device(struct device *dev) |
446 | { | 446 | { |
447 | struct iommu_dev_data *dev_data; | 447 | struct iommu_dev_data *dev_data; |
448 | struct amd_iommu *iommu; | ||
448 | int devid; | 449 | int devid; |
449 | 450 | ||
450 | if (dev->archdata.iommu) | 451 | if (dev->archdata.iommu) |
@@ -454,6 +455,8 @@ static int iommu_init_device(struct device *dev) | |||
454 | if (devid < 0) | 455 | if (devid < 0) |
455 | return devid; | 456 | return devid; |
456 | 457 | ||
458 | iommu = amd_iommu_rlookup_table[devid]; | ||
459 | |||
457 | dev_data = find_dev_data(devid); | 460 | dev_data = find_dev_data(devid); |
458 | if (!dev_data) | 461 | if (!dev_data) |
459 | return -ENOMEM; | 462 | return -ENOMEM; |
@@ -469,8 +472,7 @@ static int iommu_init_device(struct device *dev) | |||
469 | 472 | ||
470 | dev->archdata.iommu = dev_data; | 473 | dev->archdata.iommu = dev_data; |
471 | 474 | ||
472 | iommu_device_link(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev, | 475 | iommu_device_link(&iommu->iommu.dev, dev); |
473 | dev); | ||
474 | 476 | ||
475 | return 0; | 477 | return 0; |
476 | } | 478 | } |
@@ -495,13 +497,16 @@ static void iommu_ignore_device(struct device *dev) | |||
495 | 497 | ||
496 | static void iommu_uninit_device(struct device *dev) | 498 | static void iommu_uninit_device(struct device *dev) |
497 | { | 499 | { |
498 | int devid; | ||
499 | struct iommu_dev_data *dev_data; | 500 | struct iommu_dev_data *dev_data; |
501 | struct amd_iommu *iommu; | ||
502 | int devid; | ||
500 | 503 | ||
501 | devid = get_device_id(dev); | 504 | devid = get_device_id(dev); |
502 | if (devid < 0) | 505 | if (devid < 0) |
503 | return; | 506 | return; |
504 | 507 | ||
508 | iommu = amd_iommu_rlookup_table[devid]; | ||
509 | |||
505 | dev_data = search_dev_data(devid); | 510 | dev_data = search_dev_data(devid); |
506 | if (!dev_data) | 511 | if (!dev_data) |
507 | return; | 512 | return; |
@@ -509,8 +514,7 @@ static void iommu_uninit_device(struct device *dev) | |||
509 | if (dev_data->domain) | 514 | if (dev_data->domain) |
510 | detach_device(dev); | 515 | detach_device(dev); |
511 | 516 | ||
512 | iommu_device_unlink(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev, | 517 | iommu_device_unlink(&iommu->iommu.dev, dev); |
513 | dev); | ||
514 | 518 | ||
515 | iommu_group_remove_device(dev); | 519 | iommu_group_remove_device(dev); |
516 | 520 | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index b7ccfb21b271..6b9e66122528 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -1637,10 +1637,8 @@ static int iommu_init_pci(struct amd_iommu *iommu) | |||
1637 | amd_iommu_erratum_746_workaround(iommu); | 1637 | amd_iommu_erratum_746_workaround(iommu); |
1638 | amd_iommu_ats_write_check_workaround(iommu); | 1638 | amd_iommu_ats_write_check_workaround(iommu); |
1639 | 1639 | ||
1640 | iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu, | 1640 | iommu_device_sysfs_add(&iommu->iommu, &iommu->dev->dev, |
1641 | amd_iommu_groups, "ivhd%d", | 1641 | amd_iommu_groups, "ivhd%d", iommu->index); |
1642 | iommu->index); | ||
1643 | |||
1644 | iommu_device_set_ops(&iommu->iommu, &amd_iommu_ops); | 1642 | iommu_device_set_ops(&iommu->iommu, &amd_iommu_ops); |
1645 | iommu_device_register(&iommu->iommu); | 1643 | iommu_device_register(&iommu->iommu); |
1646 | 1644 | ||
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 0683505a498a..af00f381a7b1 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h | |||
@@ -535,9 +535,6 @@ struct amd_iommu { | |||
535 | /* if one, we need to send a completion wait command */ | 535 | /* if one, we need to send a completion wait command */ |
536 | bool need_sync; | 536 | bool need_sync; |
537 | 537 | ||
538 | /* IOMMU sysfs device */ | ||
539 | struct device *iommu_dev; | ||
540 | |||
541 | /* Handle for IOMMU core code */ | 538 | /* Handle for IOMMU core code */ |
542 | struct iommu_device iommu; | 539 | struct iommu_device iommu; |
543 | 540 | ||
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 83fee0e8cf43..fc13146f8d16 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c | |||
@@ -1078,14 +1078,11 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
1078 | raw_spin_lock_init(&iommu->register_lock); | 1078 | raw_spin_lock_init(&iommu->register_lock); |
1079 | 1079 | ||
1080 | if (intel_iommu_enabled) { | 1080 | if (intel_iommu_enabled) { |
1081 | iommu->iommu_dev = iommu_device_create(NULL, iommu, | 1081 | err = iommu_device_sysfs_add(&iommu->iommu, NULL, |
1082 | intel_iommu_groups, | 1082 | intel_iommu_groups, |
1083 | "%s", iommu->name); | 1083 | "%s", iommu->name); |
1084 | 1084 | if (err) | |
1085 | if (IS_ERR(iommu->iommu_dev)) { | ||
1086 | err = PTR_ERR(iommu->iommu_dev); | ||
1087 | goto err_unmap; | 1085 | goto err_unmap; |
1088 | } | ||
1089 | 1086 | ||
1090 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); | 1087 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); |
1091 | 1088 | ||
@@ -1109,7 +1106,7 @@ error: | |||
1109 | 1106 | ||
1110 | static void free_iommu(struct intel_iommu *iommu) | 1107 | static void free_iommu(struct intel_iommu *iommu) |
1111 | { | 1108 | { |
1112 | iommu_device_destroy(iommu->iommu_dev); | 1109 | iommu_device_sysfs_remove(&iommu->iommu); |
1113 | iommu_device_unregister(&iommu->iommu); | 1110 | iommu_device_unregister(&iommu->iommu); |
1114 | 1111 | ||
1115 | if (iommu->irq) { | 1112 | if (iommu->irq) { |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index e6e8f5bf3a8f..316730c63af6 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -4834,10 +4834,13 @@ int __init intel_iommu_init(void) | |||
4834 | 4834 | ||
4835 | init_iommu_pm_ops(); | 4835 | init_iommu_pm_ops(); |
4836 | 4836 | ||
4837 | for_each_active_iommu(iommu, drhd) | 4837 | for_each_active_iommu(iommu, drhd) { |
4838 | iommu->iommu_dev = iommu_device_create(NULL, iommu, | 4838 | iommu_device_sysfs_add(&iommu->iommu, NULL, |
4839 | intel_iommu_groups, | 4839 | intel_iommu_groups, |
4840 | "%s", iommu->name); | 4840 | "%s", iommu->name); |
4841 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); | ||
4842 | iommu_device_register(&iommu->iommu); | ||
4843 | } | ||
4841 | 4844 | ||
4842 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); | 4845 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
4843 | bus_register_notifier(&pci_bus_type, &device_nb); | 4846 | bus_register_notifier(&pci_bus_type, &device_nb); |
@@ -5159,7 +5162,7 @@ static int intel_iommu_add_device(struct device *dev) | |||
5159 | if (!iommu) | 5162 | if (!iommu) |
5160 | return -ENODEV; | 5163 | return -ENODEV; |
5161 | 5164 | ||
5162 | iommu_device_link(iommu->iommu_dev, dev); | 5165 | iommu_device_link(&iommu->iommu.dev, dev); |
5163 | 5166 | ||
5164 | group = iommu_group_get_for_dev(dev); | 5167 | group = iommu_group_get_for_dev(dev); |
5165 | 5168 | ||
@@ -5181,7 +5184,7 @@ static void intel_iommu_remove_device(struct device *dev) | |||
5181 | 5184 | ||
5182 | iommu_group_remove_device(dev); | 5185 | iommu_group_remove_device(dev); |
5183 | 5186 | ||
5184 | iommu_device_unlink(iommu->iommu_dev, dev); | 5187 | iommu_device_unlink(&iommu->iommu.dev, dev); |
5185 | } | 5188 | } |
5186 | 5189 | ||
5187 | #ifdef CONFIG_INTEL_IOMMU_SVM | 5190 | #ifdef CONFIG_INTEL_IOMMU_SVM |
diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c index 39b2d9127dbf..bb87d35e471d 100644 --- a/drivers/iommu/iommu-sysfs.c +++ b/drivers/iommu/iommu-sysfs.c | |||
@@ -50,54 +50,45 @@ static int __init iommu_dev_init(void) | |||
50 | postcore_initcall(iommu_dev_init); | 50 | postcore_initcall(iommu_dev_init); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Create an IOMMU device and return a pointer to it. IOMMU specific | 53 | * Init the struct device for the IOMMU. IOMMU specific attributes can |
54 | * attributes can be provided as an attribute group, allowing a unique | 54 | * be provided as an attribute group, allowing a unique namespace per |
55 | * namespace per IOMMU type. | 55 | * IOMMU type. |
56 | */ | 56 | */ |
57 | struct device *iommu_device_create(struct device *parent, void *drvdata, | 57 | int iommu_device_sysfs_add(struct iommu_device *iommu, |
58 | const struct attribute_group **groups, | 58 | struct device *parent, |
59 | const char *fmt, ...) | 59 | const struct attribute_group **groups, |
60 | const char *fmt, ...) | ||
60 | { | 61 | { |
61 | struct device *dev; | ||
62 | va_list vargs; | 62 | va_list vargs; |
63 | int ret; | 63 | int ret; |
64 | 64 | ||
65 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 65 | device_initialize(&iommu->dev); |
66 | if (!dev) | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | 66 | ||
69 | device_initialize(dev); | 67 | iommu->dev.class = &iommu_class; |
70 | 68 | iommu->dev.parent = parent; | |
71 | dev->class = &iommu_class; | 69 | iommu->dev.groups = groups; |
72 | dev->parent = parent; | ||
73 | dev->groups = groups; | ||
74 | dev_set_drvdata(dev, drvdata); | ||
75 | 70 | ||
76 | va_start(vargs, fmt); | 71 | va_start(vargs, fmt); |
77 | ret = kobject_set_name_vargs(&dev->kobj, fmt, vargs); | 72 | ret = kobject_set_name_vargs(&iommu->dev.kobj, fmt, vargs); |
78 | va_end(vargs); | 73 | va_end(vargs); |
79 | if (ret) | 74 | if (ret) |
80 | goto error; | 75 | goto error; |
81 | 76 | ||
82 | ret = device_add(dev); | 77 | ret = device_add(&iommu->dev); |
83 | if (ret) | 78 | if (ret) |
84 | goto error; | 79 | goto error; |
85 | 80 | ||
86 | return dev; | 81 | return 0; |
87 | 82 | ||
88 | error: | 83 | error: |
89 | put_device(dev); | 84 | put_device(&iommu->dev); |
90 | return ERR_PTR(ret); | 85 | return ret; |
91 | } | 86 | } |
92 | 87 | ||
93 | void iommu_device_destroy(struct device *dev) | 88 | void iommu_device_sysfs_remove(struct iommu_device *iommu) |
94 | { | 89 | { |
95 | if (!dev || IS_ERR(dev)) | 90 | device_unregister(&iommu->dev); |
96 | return; | ||
97 | |||
98 | device_unregister(dev); | ||
99 | } | 91 | } |
100 | |||
101 | /* | 92 | /* |
102 | * IOMMU drivers can indicate a device is managed by a given IOMMU using | 93 | * IOMMU drivers can indicate a device is managed by a given IOMMU using |
103 | * this interface. A link to the device will be created in the "devices" | 94 | * this interface. A link to the device will be created in the "devices" |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 99a65a397861..3ba9b536387b 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -440,7 +440,6 @@ struct intel_iommu { | |||
440 | struct irq_domain *ir_domain; | 440 | struct irq_domain *ir_domain; |
441 | struct irq_domain *ir_msi_domain; | 441 | struct irq_domain *ir_msi_domain; |
442 | #endif | 442 | #endif |
443 | struct device *iommu_dev; /* IOMMU-sysfs device */ | ||
444 | struct iommu_device iommu; /* IOMMU core code handle */ | 443 | struct iommu_device iommu; /* IOMMU core code handle */ |
445 | int node; | 444 | int node; |
446 | u32 flags; /* Software defined flags */ | 445 | u32 flags; /* Software defined flags */ |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 900ddd212364..c578ca135bed 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -209,14 +209,21 @@ struct iommu_ops { | |||
209 | * instance | 209 | * instance |
210 | * @list: Used by the iommu-core to keep a list of registered iommus | 210 | * @list: Used by the iommu-core to keep a list of registered iommus |
211 | * @ops: iommu-ops for talking to this iommu | 211 | * @ops: iommu-ops for talking to this iommu |
212 | * @dev: struct device for sysfs handling | ||
212 | */ | 213 | */ |
213 | struct iommu_device { | 214 | struct iommu_device { |
214 | struct list_head list; | 215 | struct list_head list; |
215 | const struct iommu_ops *ops; | 216 | const struct iommu_ops *ops; |
217 | struct device dev; | ||
216 | }; | 218 | }; |
217 | 219 | ||
218 | int iommu_device_register(struct iommu_device *iommu); | 220 | int iommu_device_register(struct iommu_device *iommu); |
219 | void iommu_device_unregister(struct iommu_device *iommu); | 221 | void iommu_device_unregister(struct iommu_device *iommu); |
222 | int iommu_device_sysfs_add(struct iommu_device *iommu, | ||
223 | struct device *parent, | ||
224 | const struct attribute_group **groups, | ||
225 | const char *fmt, ...) __printf(4, 5); | ||
226 | void iommu_device_sysfs_remove(struct iommu_device *iommu); | ||
220 | 227 | ||
221 | static inline void iommu_device_set_ops(struct iommu_device *iommu, | 228 | static inline void iommu_device_set_ops(struct iommu_device *iommu, |
222 | const struct iommu_ops *ops) | 229 | const struct iommu_ops *ops) |
@@ -287,10 +294,6 @@ extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr, | |||
287 | void *data); | 294 | void *data); |
288 | extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, | 295 | extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, |
289 | void *data); | 296 | void *data); |
290 | struct device *iommu_device_create(struct device *parent, void *drvdata, | ||
291 | const struct attribute_group **groups, | ||
292 | const char *fmt, ...) __printf(4, 5); | ||
293 | void iommu_device_destroy(struct device *dev); | ||
294 | int iommu_device_link(struct device *dev, struct device *link); | 297 | int iommu_device_link(struct device *dev, struct device *link); |
295 | void iommu_device_unlink(struct device *dev, struct device *link); | 298 | void iommu_device_unlink(struct device *dev, struct device *link); |
296 | 299 | ||
@@ -567,29 +570,29 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain, | |||
567 | return -EINVAL; | 570 | return -EINVAL; |
568 | } | 571 | } |
569 | 572 | ||
570 | static inline struct device *iommu_device_create(struct device *parent, | 573 | static inline int iommu_device_register(struct iommu_device *iommu) |
571 | void *drvdata, | ||
572 | const struct attribute_group **groups, | ||
573 | const char *fmt, ...) | ||
574 | { | 574 | { |
575 | return ERR_PTR(-ENODEV); | 575 | return -ENODEV; |
576 | } | 576 | } |
577 | 577 | ||
578 | static inline void iommu_device_destroy(struct device *dev) | 578 | static inline void iommu_device_set_ops(struct iommu_device *iommu, |
579 | const struct iommu_ops *ops) | ||
579 | { | 580 | { |
580 | } | 581 | } |
581 | 582 | ||
582 | static inline int iommu_device_register(struct iommu_device *iommu) | 583 | static inline void iommu_device_unregister(struct iommu_device *iommu) |
583 | { | 584 | { |
584 | return -ENODEV; | ||
585 | } | 585 | } |
586 | 586 | ||
587 | static inline void iommu_device_set_ops(struct iommu_device *iommu, | 587 | static inline int iommu_device_sysfs_add(struct iommu_device *iommu, |
588 | const struct iommu_ops *ops) | 588 | struct device *parent, |
589 | const struct attribute_group **groups, | ||
590 | const char *fmt, ...) | ||
589 | { | 591 | { |
592 | return -ENODEV; | ||
590 | } | 593 | } |
591 | 594 | ||
592 | static inline void iommu_device_unregister(struct iommu_device *iommu) | 595 | static inline void iommu_device_sysfs_remove(struct iommu_device *iommu) |
593 | { | 596 | { |
594 | } | 597 | } |
595 | 598 | ||