Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1574945 > unrolled thread
| Started by | Joerg Roedel <joro@8bytes.org> |
|---|---|
| First post | 2017-02-06 17:20 +0100 |
| Last post | 2017-02-06 17:20 +0100 |
| Articles | 11 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 00/10 v2] Let IOMMU core know about individual IOMMUs Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 02/10] iommu: Rename struct iommu_device Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface Marek Szyprowski <m.szyprowski@samsung.com> - 2017-02-07 13:40 +0100
Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface Marek Szyprowski <m.szyprowski@samsung.com> - 2017-02-08 15:40 +0100
Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface Joerg Roedel <joro@8bytes.org> - 2017-02-08 16:00 +0100
[PATCH 06/10] iommu/arm-smmu: Make use of the iommu_register interface Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 03/10] iommu: Introduce new 'struct iommu_device' Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 10/10] iommu: Remove iommu_register_instance interface Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 08/10] iommu/mediatek: Make use of iommu_device_register interface Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
[PATCH 04/10] iommu: Add sysfs bindings for struct iommu_device Joerg Roedel <joro@8bytes.org> - 2017-02-06 17:20 +0100
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 00/10 v2] Let IOMMU core know about individual IOMMUs |
| Message-ID | <t7Ubg-7e3-5@gated-at.bofh.it> |
Changes since v1:
* Rebased to v4.10-rc7
* Fixed build failures found by the
kbuild test robot
Hi,
the IOMMU core code already has two ways of representing
individual hardware IOMMUs. One is the sysfs code and the
other is the newer iommu_register_instance interface. These
two interfaces are special purpose and can be unified.
This unification is attempted in this patch-set. It
introduces an extensible 'struct iommu_device' which
represents a hardware IOMMU in the IOMMU core code.
For now the struct contains a pointer to the iommu_ops, which
is a step to get rid of the per-bus iommu_ops, and a pointer
to a firmware-node structure.
The patches have been tested on x86 hardware and an AMD Seattle
ARM64 system.
Please review, test and provide feedback!
Thanks a lot,
Joerg
Joerg Roedel (10):
iommu: Rename iommu_get_instance()
iommu: Rename struct iommu_device
iommu: Introduce new 'struct iommu_device'
iommu: Add sysfs bindings for struct iommu_device
iommu: Make iommu_device_link/unlink take a struct iommu_device
iommu/arm-smmu: Make use of the iommu_register interface
iommu/msm: Make use of iommu_device_register interface
iommu/mediatek: Make use of iommu_device_register interface
iommu/exynos: Make use of iommu_device_register interface
iommu: Remove iommu_register_instance interface
drivers/acpi/arm64/iort.c | 2 +-
drivers/iommu/amd_iommu.c | 18 ++++++----
drivers/iommu/amd_iommu_init.c | 9 +++--
drivers/iommu/amd_iommu_types.h | 4 +--
drivers/iommu/arm-smmu-v3.c | 21 ++++++++++--
drivers/iommu/arm-smmu.c | 31 ++++++++++++++++-
drivers/iommu/dmar.c | 20 +++++++----
drivers/iommu/exynos-iommu.c | 18 ++++++++--
drivers/iommu/intel-iommu.c | 19 ++++++-----
drivers/iommu/iommu-sysfs.c | 61 +++++++++++++++-------------------
drivers/iommu/iommu.c | 68 +++++++++++++++++---------------------
drivers/iommu/msm_iommu.c | 73 ++++++++++++++++++++++++++++++++++++++++-
drivers/iommu/msm_iommu.h | 3 ++
drivers/iommu/mtk_iommu.c | 27 ++++++++++++++-
drivers/iommu/mtk_iommu.h | 2 ++
include/linux/intel-iommu.h | 3 +-
include/linux/iommu.h | 65 ++++++++++++++++++++++++------------
include/linux/of_iommu.h | 8 +----
18 files changed, 316 insertions(+), 136 deletions(-)
--
1.9.1
[toc] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 02/10] iommu: Rename struct iommu_device |
| Message-ID | <t7Ubg-7e3-27@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
The struct is used to link devices to iommu-groups, so
'struct group_device' is a better name. Further this makes
the name iommu_device available for a struct representing
hardware iommus.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/iommu.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 0ee05bb..e4e8a93 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -55,7 +55,7 @@ struct iommu_group {
struct iommu_domain *domain;
};
-struct iommu_device {
+struct group_device {
struct list_head list;
struct device *dev;
char *name;
@@ -374,7 +374,7 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
int iommu_group_add_device(struct iommu_group *group, struct device *dev)
{
int ret, i = 0;
- struct iommu_device *device;
+ struct group_device *device;
device = kzalloc(sizeof(*device), GFP_KERNEL);
if (!device)
@@ -449,7 +449,7 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
void iommu_group_remove_device(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
- struct iommu_device *tmp_device, *device = NULL;
+ struct group_device *tmp_device, *device = NULL;
pr_info("Removing device %s from group %d\n", dev_name(dev), group->id);
@@ -484,7 +484,7 @@ void iommu_group_remove_device(struct device *dev)
static int iommu_group_device_count(struct iommu_group *group)
{
- struct iommu_device *entry;
+ struct group_device *entry;
int ret = 0;
list_for_each_entry(entry, &group->devices, list)
@@ -507,7 +507,7 @@ static int iommu_group_device_count(struct iommu_group *group)
static int __iommu_group_for_each_dev(struct iommu_group *group, void *data,
int (*fn)(struct device *, void *))
{
- struct iommu_device *device;
+ struct group_device *device;
int ret = 0;
list_for_each_entry(device, &group->devices, list) {
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface |
| Message-ID | <t7Ubg-7e3-19@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
Register Exynos IOMMUs to the IOMMU core and make them
visible in sysfs. This patch does not add the links between
IOMMUs and translated devices yet.
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/exynos-iommu.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 57ba0d3..90f0f52 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -276,6 +276,8 @@ struct sysmmu_drvdata {
struct list_head owner_node; /* node for owner controllers list */
phys_addr_t pgtable; /* assigned page table structure */
unsigned int version; /* our version */
+
+ struct iommu_device iommu; /* IOMMU core handle */
};
static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
@@ -556,6 +558,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sysmmu_drvdata *data;
struct resource *res;
+ resource_size_t ioaddr;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -565,6 +568,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
data->sfrbase = devm_ioremap_resource(dev, res);
if (IS_ERR(data->sfrbase))
return PTR_ERR(data->sfrbase);
+ ioaddr = res->start;
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
@@ -611,6 +615,18 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
data->sysmmu = dev;
spin_lock_init(&data->lock);
+ ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
+ "sysmmu.%pa", &ioaddr);
+ if (ret)
+ return ret;
+
+ data->iommu.ops = &exynos_iommu_ops;
+ data->iommu.fwnode = &dev->of_node->fwnode;
+
+ ret = iommu_device_register(&data->iommu);
+ if (ret)
+ return ret;
+
platform_set_drvdata(pdev, data);
__sysmmu_get_version(data);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2017-02-07 13:40 +0100 |
| Subject | Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface |
| Message-ID | <t8ddT-2Qi-5@gated-at.bofh.it> |
| In reply to | #1574947 |
Hi Joerg,
On 2017-02-06 17:10, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
>
> Register Exynos IOMMUs to the IOMMU core and make them
> visible in sysfs. This patch does not add the links between
> IOMMUs and translated devices yet.
>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-samsung-soc@vger.kernel.org
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
> drivers/iommu/exynos-iommu.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 57ba0d3..90f0f52 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -276,6 +276,8 @@ struct sysmmu_drvdata {
> struct list_head owner_node; /* node for owner controllers list */
> phys_addr_t pgtable; /* assigned page table structure */
> unsigned int version; /* our version */
> +
> + struct iommu_device iommu; /* IOMMU core handle */
> };
>
> static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
> @@ -556,6 +558,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
> struct device *dev = &pdev->dev;
> struct sysmmu_drvdata *data;
> struct resource *res;
> + resource_size_t ioaddr;
>
> data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> @@ -565,6 +568,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
> data->sfrbase = devm_ioremap_resource(dev, res);
> if (IS_ERR(data->sfrbase))
> return PTR_ERR(data->sfrbase);
> + ioaddr = res->start;
>
> irq = platform_get_irq(pdev, 0);
> if (irq <= 0) {
> @@ -611,6 +615,18 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
> data->sysmmu = dev;
> spin_lock_init(&data->lock);
>
> + ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
> + "sysmmu.%pa", &ioaddr);
Can we stick to the common name across the /sysfs and use
dev_name(data->sysmmu)
or even dev_name(dev) here?
ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
dev_name(dev));
> + if (ret)
> + return ret;
> +
> + data->iommu.ops = &exynos_iommu_ops;
> + data->iommu.fwnode = &dev->of_node->fwnode;
> +
> + ret = iommu_device_register(&data->iommu);
> + if (ret)
> + return ret;
> +
> platform_set_drvdata(pdev, data);
>
> __sysmmu_get_version(data);
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2017-02-08 15:40 +0100 |
| Subject | Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface |
| Message-ID | <t8BzA-1u7-21@gated-at.bofh.it> |
| In reply to | #1575621 |
Hi Joerg, On 2017-02-08 14:57, Joerg Roedel wrote: > On Tue, Feb 07, 2017 at 01:36:15PM +0100, Marek Szyprowski wrote: >>> + ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, >>> + "sysmmu.%pa", &ioaddr); >> Can we stick to the common name across the /sysfs and use >> dev_name(data->sysmmu) >> or even dev_name(dev) here? >> >> ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, >> dev_name(dev)); > That means that we have multiple 'struct device' with the same name, > no? I think will lead to confusion when using dev_printk, as its not > clear anymore which device is refered to in the message. Each sysmmu device has unique name, like every other platform device instantiated from device tree. Here is an example from the OdroidXU3 (Exynos5422 based): # ls -1 /sys/bus/platform/devices/ | grep sysmmu 10a60000.sysmmu 10a70000.sysmmu 11200000.sysmmu 11210000.sysmmu 11d40000.sysmmu 11f10000.sysmmu 11f20000.sysmmu 12880000.sysmmu 12890000.sysmmu 128a0000.sysmmu 128c0000.sysmmu 128d0000.sysmmu 128e0000.sysmmu 13e80000.sysmmu 13e90000.sysmmu 14640000.sysmmu 14650000.sysmmu 14680000.sysmmu IMHO there is no need for open coding new unique names if device name, which already contains the base address, can be used instead. Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-08 16:00 +0100 |
| Subject | Re: [PATCH 09/10] iommu/exynos: Make use of iommu_device_register interface |
| Message-ID | <t8BzA-1u7-23@gated-at.bofh.it> |
| In reply to | #1575621 |
Hi Marek, On Tue, Feb 07, 2017 at 01:36:15PM +0100, Marek Szyprowski wrote: > >+ ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, > >+ "sysmmu.%pa", &ioaddr); > > Can we stick to the common name across the /sysfs and use > dev_name(data->sysmmu) > or even dev_name(dev) here? > > ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, > dev_name(dev)); That means that we have multiple 'struct device' with the same name, no? I think will lead to confusion when using dev_printk, as its not clear anymore which device is refered to in the message. Joerg
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 06/10] iommu/arm-smmu: Make use of the iommu_register interface |
| Message-ID | <t7Ubg-7e3-21@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
Also add the smmu devices to sysfs.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/arm-smmu-v3.c | 20 +++++++++++++++++++-
drivers/iommu/arm-smmu.c | 29 +++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4d6ec44..37094b5 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -616,6 +616,9 @@ struct arm_smmu_device {
unsigned int sid_bits;
struct arm_smmu_strtab_cfg strtab_cfg;
+
+ /* IOMMU core code handle */
+ struct iommu_device iommu;
};
/* SMMU private data for each master */
@@ -1795,8 +1798,10 @@ static int arm_smmu_add_device(struct device *dev)
}
group = iommu_group_get_for_dev(dev);
- if (!IS_ERR(group))
+ if (!IS_ERR(group)) {
iommu_group_put(group);
+ iommu_device_link(&smmu->iommu, dev);
+ }
return PTR_ERR_OR_ZERO(group);
}
@@ -1805,14 +1810,17 @@ static void arm_smmu_remove_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
struct arm_smmu_master_data *master;
+ struct arm_smmu_device *smmu;
if (!fwspec || fwspec->ops != &arm_smmu_ops)
return;
master = fwspec->iommu_priv;
+ smmu = master->smmu;
if (master && master->ste.valid)
arm_smmu_detach_dev(dev);
iommu_group_remove_device(dev);
+ iommu_device_unlink(&smmu->iommu, dev);
kfree(master);
iommu_fwspec_free(dev);
}
@@ -2613,6 +2621,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
{
int irq, ret;
struct resource *res;
+ resource_size_t ioaddr;
struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
bool bypass;
@@ -2630,6 +2639,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
dev_err(dev, "MMIO region too small (%pr)\n", res);
return -EINVAL;
}
+ ioaddr = res->start;
smmu->base = devm_ioremap_resource(dev, res);
if (IS_ERR(smmu->base))
@@ -2682,6 +2692,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
return ret;
/* And we're up. Go go go! */
+ ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
+ "smmu3.%pa", &ioaddr);
+ if (ret)
+ return ret;
+
+ smmu->iommu.ops = &arm_smmu_ops;
+ ret = iommu_device_register(&smmu->iommu);
+
iommu_register_instance(dev->fwnode, &arm_smmu_ops);
#ifdef CONFIG_PCI
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a60cded..827e778 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -380,6 +380,9 @@ struct arm_smmu_device {
unsigned int *irqs;
u32 cavium_id_base; /* Specific to Cavium */
+
+ /* IOMMU core code handle */
+ struct iommu_device iommu;
};
enum arm_smmu_context_fmt {
@@ -1444,6 +1447,8 @@ static int arm_smmu_add_device(struct device *dev)
if (ret)
goto out_free;
+ iommu_device_link(&smmu->iommu, dev);
+
return 0;
out_free:
@@ -1456,10 +1461,17 @@ static int arm_smmu_add_device(struct device *dev)
static void arm_smmu_remove_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+ struct arm_smmu_master_cfg *cfg;
+ struct arm_smmu_device *smmu;
+
if (!fwspec || fwspec->ops != &arm_smmu_ops)
return;
+ cfg = fwspec->iommu_priv;
+ smmu = cfg->smmu;
+
+ iommu_device_unlink(&smmu->iommu, dev);
arm_smmu_master_free_smes(fwspec);
iommu_group_remove_device(dev);
kfree(fwspec->iommu_priv);
@@ -2011,6 +2023,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
static int arm_smmu_device_probe(struct platform_device *pdev)
{
struct resource *res;
+ resource_size_t ioaddr;
struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
int num_irqs, i, err;
@@ -2031,6 +2044,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
return err;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ioaddr = res->start;
smmu->base = devm_ioremap_resource(dev, res);
if (IS_ERR(smmu->base))
return PTR_ERR(smmu->base);
@@ -2091,6 +2105,21 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
}
}
+ err = iommu_device_sysfs_add(&smmu->iommu, smmu->dev, NULL,
+ "smmu.%pa", &ioaddr);
+ if (err) {
+ dev_err(dev, "Failed to register iommu in sysfs\n");
+ return err;
+ }
+
+ smmu->iommu.ops = &arm_smmu_ops;
+
+ err = iommu_device_register(&smmu->iommu);
+ if (err) {
+ dev_err(dev, "Failed to register iommu\n");
+ return err;
+ }
+
iommu_register_instance(dev->fwnode, &arm_smmu_ops);
platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 03/10] iommu: Introduce new 'struct iommu_device' |
| Message-ID | <t7Ubg-7e3-25@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
This struct represents one hardware iommu in the iommu core
code. For now it only has the iommu-ops associated with it,
but that will be extended soon.
The register/unregister interface is also added, as well as
making use of it in the Intel and AMD IOMMU drivers.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/amd_iommu.c | 4 ++--
drivers/iommu/amd_iommu_init.c | 5 +++++
drivers/iommu/amd_iommu_types.h | 3 +++
drivers/iommu/dmar.c | 9 +++++++++
drivers/iommu/intel-iommu.c | 4 ++--
drivers/iommu/iommu.c | 19 +++++++++++++++++++
include/linux/intel-iommu.h | 2 ++
include/linux/iommu.h | 26 ++++++++++++++++++++------
8 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 3ef0f42..7c11c36 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -112,7 +112,7 @@ struct flush_queue {
* Domain for untranslated devices - only allocated
* if iommu=pt passed on kernel cmd line.
*/
-static const struct iommu_ops amd_iommu_ops;
+const struct iommu_ops amd_iommu_ops;
static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
int amd_iommu_max_glx_val = -1;
@@ -3217,7 +3217,7 @@ static void amd_iommu_apply_dm_region(struct device *dev,
WARN_ON_ONCE(reserve_iova(&dma_dom->iovad, start, end) == NULL);
}
-static const struct iommu_ops amd_iommu_ops = {
+const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
.domain_free = amd_iommu_domain_free,
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6799cf9..02a577b 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -94,6 +94,8 @@
* out of it.
*/
+extern const struct iommu_ops amd_iommu_ops;
+
/*
* structure describing one IOMMU in the ACPI table. Typically followed by one
* or more ivhd_entrys.
@@ -1639,6 +1641,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
amd_iommu_groups, "ivhd%d",
iommu->index);
+ iommu->iommu.ops = &amd_iommu_ops;
+ iommu_device_register(&iommu->iommu);
+
return pci_enable_device(iommu->dev);
}
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 0d91785..0683505 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -538,6 +538,9 @@ struct amd_iommu {
/* IOMMU sysfs device */
struct device *iommu_dev;
+ /* Handle for IOMMU core code */
+ struct iommu_device iommu;
+
/*
* We can't rely on the BIOS to restore all values on reinit, so we
* need to stash them
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 8ccbd70..c55411e 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -74,6 +74,8 @@ struct dmar_res_callback {
static int alloc_iommu(struct dmar_drhd_unit *drhd);
static void free_iommu(struct intel_iommu *iommu);
+extern const struct iommu_ops intel_iommu_ops;
+
static void dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
{
/*
@@ -1086,6 +1088,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
err = PTR_ERR(iommu->iommu_dev);
goto err_unmap;
}
+
+ iommu->iommu.ops = &intel_iommu_ops;
+
+ err = iommu_device_register(&iommu->iommu);
+ if (err)
+ goto err_unmap;
}
drhd->iommu = iommu;
@@ -1104,6 +1112,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
static void free_iommu(struct intel_iommu *iommu)
{
iommu_device_destroy(iommu->iommu_dev);
+ iommu_device_unregister(&iommu->iommu);
if (iommu->irq) {
if (iommu->pr_irq) {
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 8a18525..ca22872 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -547,7 +547,7 @@ static int domain_detach_iommu(struct dmar_domain *domain,
static DEFINE_SPINLOCK(device_domain_lock);
static LIST_HEAD(device_domain_list);
-static const struct iommu_ops intel_iommu_ops;
+const struct iommu_ops intel_iommu_ops;
static bool translation_pre_enabled(struct intel_iommu *iommu)
{
@@ -5332,7 +5332,7 @@ struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
}
#endif /* CONFIG_INTEL_IOMMU_SVM */
-static const struct iommu_ops intel_iommu_ops = {
+const struct iommu_ops intel_iommu_ops = {
.capable = intel_iommu_capable,
.domain_alloc = intel_iommu_domain_alloc,
.domain_free = intel_iommu_domain_free,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index e4e8a93..21061da 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -77,6 +77,25 @@ struct iommu_group_attribute iommu_group_attr_##_name = \
#define to_iommu_group(_kobj) \
container_of(_kobj, struct iommu_group, kobj)
+static LIST_HEAD(iommu_device_list);
+static DEFINE_SPINLOCK(iommu_device_lock);
+
+int iommu_device_register(struct iommu_device *iommu)
+{
+ spin_lock(&iommu_device_lock);
+ list_add_tail(&iommu->list, &iommu_device_list);
+ spin_unlock(&iommu_device_lock);
+
+ return 0;
+}
+
+void iommu_device_unregister(struct iommu_device *iommu)
+{
+ spin_lock(&iommu_device_lock);
+ list_del(&iommu->list);
+ spin_unlock(&iommu_device_lock);
+}
+
static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
unsigned type);
static int __iommu_attach_device(struct iommu_domain *domain,
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index d49e26c..99a65a3 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -29,6 +29,7 @@
#include <linux/dma_remapping.h>
#include <linux/mmu_notifier.h>
#include <linux/list.h>
+#include <linux/iommu.h>
#include <asm/cacheflush.h>
#include <asm/iommu.h>
@@ -440,6 +441,7 @@ struct intel_iommu {
struct irq_domain *ir_msi_domain;
#endif
struct device *iommu_dev; /* IOMMU-sysfs device */
+ struct iommu_device iommu; /* IOMMU core code handle */
int node;
u32 flags; /* Software defined flags */
};
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 085e1f0..4e2d2ca 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -204,6 +204,20 @@ struct iommu_ops {
unsigned long pgsize_bitmap;
};
+/**
+ * struct iommu_device - IOMMU core representation of one IOMMU hardware
+ * instance
+ * @list: Used by the iommu-core to keep a list of registered iommus
+ * @ops: iommu-ops for talking to this iommu
+ */
+struct iommu_device {
+ struct list_head list;
+ const struct iommu_ops *ops;
+};
+
+int iommu_device_register(struct iommu_device *iommu);
+void iommu_device_unregister(struct iommu_device *iommu);
+
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */
@@ -361,6 +375,9 @@ void iommu_register_instance(struct fwnode_handle *fwnode,
struct iommu_ops {};
struct iommu_group {};
struct iommu_fwspec {};
+struct iommu_device {
+ const struct iommu_ops *ops; /* Needed for dmar.c */
+};
static inline bool iommu_present(struct bus_type *bus)
{
@@ -546,15 +563,12 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain,
return -EINVAL;
}
-static inline struct device *iommu_device_create(struct device *parent,
- void *drvdata,
- const struct attribute_group **groups,
- const char *fmt, ...)
+static inline int iommu_device_register(struct iommu_device *iommu)
{
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
}
-static inline void iommu_device_destroy(struct device *dev)
+static inline void iommu_device_unregister(struct iommu_device *iommu)
{
}
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 10/10] iommu: Remove iommu_register_instance interface |
| Message-ID | <t7Ubh-7e3-33@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
And also move its remaining functionality to
iommu_device_register() and 'struct iommu_device'.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/arm-smmu-v3.c | 3 +--
drivers/iommu/arm-smmu.c | 4 ++--
drivers/iommu/exynos-iommu.c | 2 --
drivers/iommu/iommu.c | 37 ++++++-------------------------------
drivers/iommu/msm_iommu.c | 2 --
drivers/iommu/mtk_iommu.c | 1 -
include/linux/iommu.h | 8 +-------
include/linux/of_iommu.h | 6 ------
8 files changed, 10 insertions(+), 53 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 37094b5..3b00a2e 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2698,10 +2698,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
return ret;
smmu->iommu.ops = &arm_smmu_ops;
+ smmu->iommu.fwnode = dev->fwnode;
ret = iommu_device_register(&smmu->iommu);
- iommu_register_instance(dev->fwnode, &arm_smmu_ops);
-
#ifdef CONFIG_PCI
if (pci_bus_type.iommu_ops != &arm_smmu_ops) {
pci_request_acs();
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 827e778..dbbd2f2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2112,7 +2112,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
return err;
}
- smmu->iommu.ops = &arm_smmu_ops;
+ smmu->iommu.ops = &arm_smmu_ops;
+ smmu->iommu.fwnode = dev->fwnode;
err = iommu_device_register(&smmu->iommu);
if (err) {
@@ -2120,7 +2121,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
return err;
}
- iommu_register_instance(dev->fwnode, &arm_smmu_ops);
platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 90f0f52..839f6c1 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -644,8 +644,6 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
- of_iommu_set_ops(dev->of_node, &exynos_iommu_ops);
-
return 0;
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 21061da..a7e14b4 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1647,43 +1647,18 @@ int iommu_request_dm_for_dev(struct device *dev)
return ret;
}
-struct iommu_instance {
- struct list_head list;
- struct fwnode_handle *fwnode;
- const struct iommu_ops *ops;
-};
-static LIST_HEAD(iommu_instance_list);
-static DEFINE_SPINLOCK(iommu_instance_lock);
-
-void iommu_register_instance(struct fwnode_handle *fwnode,
- const struct iommu_ops *ops)
-{
- struct iommu_instance *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
-
- if (WARN_ON(!iommu))
- return;
-
- of_node_get(to_of_node(fwnode));
- INIT_LIST_HEAD(&iommu->list);
- iommu->fwnode = fwnode;
- iommu->ops = ops;
- spin_lock(&iommu_instance_lock);
- list_add_tail(&iommu->list, &iommu_instance_list);
- spin_unlock(&iommu_instance_lock);
-}
-
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
{
- struct iommu_instance *instance;
const struct iommu_ops *ops = NULL;
+ struct iommu_device *iommu;
- spin_lock(&iommu_instance_lock);
- list_for_each_entry(instance, &iommu_instance_list, list)
- if (instance->fwnode == fwnode) {
- ops = instance->ops;
+ spin_lock(&iommu_device_lock);
+ list_for_each_entry(iommu, &iommu_device_list, list)
+ if (iommu->fwnode == fwnode) {
+ ops = iommu->ops;
break;
}
- spin_unlock(&iommu_instance_lock);
+ spin_unlock(&iommu_device_lock);
return ops;
}
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 38d19f9..b89b47e 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -810,8 +810,6 @@ static int msm_iommu_probe(struct platform_device *pdev)
goto fail;
}
- of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops);
-
pr_info("device mapped at %p, irq %d with %d ctx banks\n",
iommu->base, iommu->irq, iommu->ncb);
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 9fb7258..f0612aa 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -681,7 +681,6 @@ static int mtk_iommu_init_fn(struct device_node *np)
return ret;
}
- of_iommu_set_ops(np, &mtk_iommu_ops);
return 0;
}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 7e2ba06..b1d3e3c 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -214,6 +214,7 @@ struct iommu_ops {
struct iommu_device {
struct list_head list;
const struct iommu_ops *ops;
+ struct fwnode_handle *fwnode;
struct device dev;
};
@@ -369,8 +370,6 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
const struct iommu_ops *ops);
void iommu_fwspec_free(struct device *dev);
int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
-void iommu_register_instance(struct fwnode_handle *fwnode,
- const struct iommu_ops *ops);
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
#else /* CONFIG_IOMMU_API */
@@ -613,11 +612,6 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
return -ENODEV;
}
-static inline void iommu_register_instance(struct fwnode_handle *fwnode,
- const struct iommu_ops *ops)
-{
-}
-
static inline
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
{
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 66fcbc9..fc4add3 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -31,12 +31,6 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
#endif /* CONFIG_OF_IOMMU */
-static inline void of_iommu_set_ops(struct device_node *np,
- const struct iommu_ops *ops)
-{
- iommu_register_instance(&np->fwnode, ops);
-}
-
static inline const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
{
return iommu_ops_from_fwnode(&np->fwnode);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 08/10] iommu/mediatek: Make use of iommu_device_register interface |
| Message-ID | <t7Ubh-7e3-39@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
Register individual Mediatek IOMMUs to the iommu core and
add sysfs entries.
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mediatek@lists.infradead.org
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/mtk_iommu.c | 26 ++++++++++++++++++++++++++
drivers/iommu/mtk_iommu.h | 2 ++
2 files changed, 28 insertions(+)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1479c76..9fb7258 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -360,11 +360,15 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
static int mtk_iommu_add_device(struct device *dev)
{
+ struct mtk_iommu_data *data;
struct iommu_group *group;
if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
return -ENODEV; /* Not a iommu client device */
+ data = dev->iommu_fwspec->iommu_priv;
+ iommu_device_link(&data->iommu, dev);
+
group = iommu_group_get_for_dev(dev);
if (IS_ERR(group))
return PTR_ERR(group);
@@ -375,9 +379,14 @@ static int mtk_iommu_add_device(struct device *dev)
static void mtk_iommu_remove_device(struct device *dev)
{
+ struct mtk_iommu_data *data;
+
if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
return;
+ data = dev->iommu_fwspec->iommu_priv;
+ iommu_device_unlink(&data->iommu, dev);
+
iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
@@ -497,6 +506,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
struct mtk_iommu_data *data;
struct device *dev = &pdev->dev;
struct resource *res;
+ resource_size_t ioaddr;
struct component_match *match = NULL;
void *protect;
int i, larb_nr, ret;
@@ -519,6 +529,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
data->base = devm_ioremap_resource(dev, res);
if (IS_ERR(data->base))
return PTR_ERR(data->base);
+ ioaddr = res->start;
data->irq = platform_get_irq(pdev, 0);
if (data->irq < 0)
@@ -567,6 +578,18 @@ static int mtk_iommu_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
+ "mtk-iommu.%pa", &ioaddr);
+ if (ret)
+ return ret;
+
+ data->iommu.ops = &mtk_iommu_ops;
+ data->iommu.fwnode = &pdev->dev.of_node->fwnode;
+
+ ret = iommu_device_register(&data->iommu);
+ if (ret)
+ return ret;
+
if (!iommu_present(&platform_bus_type))
bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
@@ -577,6 +600,9 @@ static int mtk_iommu_remove(struct platform_device *pdev)
{
struct mtk_iommu_data *data = platform_get_drvdata(pdev);
+ iommu_device_sysfs_remove(&data->iommu);
+ iommu_device_unregister(&data->iommu);
+
if (iommu_present(&platform_bus_type))
bus_set_iommu(&platform_bus_type, NULL);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 50177f7..2a28ead 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -47,6 +47,8 @@ struct mtk_iommu_data {
struct iommu_group *m4u_group;
struct mtk_smi_iommu smi_imu; /* SMI larb iommu info */
bool enable_4GB;
+
+ struct iommu_device iommu;
};
static inline int compare_of(struct device *dev, void *data)
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Joerg Roedel <joro@8bytes.org> |
|---|---|
| Date | 2017-02-06 17:20 +0100 |
| Subject | [PATCH 04/10] iommu: Add sysfs bindings for struct iommu_device |
| Message-ID | <t7Ubh-7e3-37@gated-at.bofh.it> |
| In reply to | #1574945 |
From: Joerg Roedel <jroedel@suse.de>
There is currently support for iommu sysfs bindings, but
those need to be implemented in the IOMMU drivers. Add a
more generic version of this by adding a struct device to
struct iommu_device and use that for the sysfs bindings.
Also convert the AMD and Intel IOMMU driver to make use of
it.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
drivers/iommu/amd_iommu.c | 14 ++++++++-----
drivers/iommu/amd_iommu_init.c | 6 ++----
drivers/iommu/amd_iommu_types.h | 3 ---
drivers/iommu/dmar.c | 13 +++++-------
drivers/iommu/intel-iommu.c | 15 ++++++++------
drivers/iommu/iommu-sysfs.c | 45 +++++++++++++++++------------------------
include/linux/intel-iommu.h | 1 -
include/linux/iommu.h | 23 +++++++++++++++++----
8 files changed, 62 insertions(+), 58 deletions(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 7c11c36..a584ac2 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)
static int iommu_init_device(struct device *dev)
{
struct iommu_dev_data *dev_data;
+ struct amd_iommu *iommu;
int devid;
if (dev->archdata.iommu)
@@ -454,6 +455,8 @@ static int iommu_init_device(struct device *dev)
if (devid < 0)
return devid;
+ iommu = amd_iommu_rlookup_table[devid];
+
dev_data = find_dev_data(devid);
if (!dev_data)
return -ENOMEM;
@@ -469,8 +472,7 @@ static int iommu_init_device(struct device *dev)
dev->archdata.iommu = dev_data;
- iommu_device_link(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
- dev);
+ iommu_device_link(&iommu->iommu.dev, dev);
return 0;
}
@@ -495,13 +497,16 @@ static void iommu_ignore_device(struct device *dev)
static void iommu_uninit_device(struct device *dev)
{
- int devid;
struct iommu_dev_data *dev_data;
+ struct amd_iommu *iommu;
+ int devid;
devid = get_device_id(dev);
if (devid < 0)
return;
+ iommu = amd_iommu_rlookup_table[devid];
+
dev_data = search_dev_data(devid);
if (!dev_data)
return;
@@ -509,8 +514,7 @@ static void iommu_uninit_device(struct device *dev)
if (dev_data->domain)
detach_device(dev);
- iommu_device_unlink(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
- dev);
+ iommu_device_unlink(&iommu->iommu.dev, dev);
iommu_group_remove_device(dev);
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 02a577b..88b0070 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)
amd_iommu_erratum_746_workaround(iommu);
amd_iommu_ats_write_check_workaround(iommu);
- iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
- amd_iommu_groups, "ivhd%d",
- iommu->index);
-
+ iommu_device_sysfs_add(&iommu->iommu, &iommu->dev->dev,
+ amd_iommu_groups, "ivhd%d", iommu->index);
iommu->iommu.ops = &amd_iommu_ops;
iommu_device_register(&iommu->iommu);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 0683505..af00f38 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -535,9 +535,6 @@ struct amd_iommu {
/* if one, we need to send a completion wait command */
bool need_sync;
- /* IOMMU sysfs device */
- struct device *iommu_dev;
-
/* Handle for IOMMU core code */
struct iommu_device iommu;
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index c55411e..48264a0 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1080,14 +1080,11 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
raw_spin_lock_init(&iommu->register_lock);
if (intel_iommu_enabled) {
- iommu->iommu_dev = iommu_device_create(NULL, iommu,
- intel_iommu_groups,
- "%s", iommu->name);
-
- if (IS_ERR(iommu->iommu_dev)) {
- err = PTR_ERR(iommu->iommu_dev);
+ err = iommu_device_sysfs_add(&iommu->iommu, NULL,
+ intel_iommu_groups,
+ "%s", iommu->name);
+ if (err)
goto err_unmap;
- }
iommu->iommu.ops = &intel_iommu_ops;
@@ -1111,7 +1108,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
static void free_iommu(struct intel_iommu *iommu)
{
- iommu_device_destroy(iommu->iommu_dev);
+ iommu_device_sysfs_remove(&iommu->iommu);
iommu_device_unregister(&iommu->iommu);
if (iommu->irq) {
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ca22872..3084837 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4853,10 +4853,13 @@ int __init intel_iommu_init(void)
init_iommu_pm_ops();
- for_each_active_iommu(iommu, drhd)
- iommu->iommu_dev = iommu_device_create(NULL, iommu,
- intel_iommu_groups,
- "%s", iommu->name);
+ for_each_active_iommu(iommu, drhd) {
+ iommu_device_sysfs_add(&iommu->iommu, NULL,
+ intel_iommu_groups,
+ "%s", iommu->name);
+ iommu->iommu.ops = &intel_iommu_ops;
+ iommu_device_register(&iommu->iommu);
+ }
bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
bus_register_notifier(&pci_bus_type, &device_nb);
@@ -5178,7 +5181,7 @@ static int intel_iommu_add_device(struct device *dev)
if (!iommu)
return -ENODEV;
- iommu_device_link(iommu->iommu_dev, dev);
+ iommu_device_link(&iommu->iommu.dev, dev);
group = iommu_group_get_for_dev(dev);
@@ -5200,7 +5203,7 @@ static void intel_iommu_remove_device(struct device *dev)
iommu_group_remove_device(dev);
- iommu_device_unlink(iommu->iommu_dev, dev);
+ iommu_device_unlink(&iommu->iommu.dev, dev);
}
#ifdef CONFIG_INTEL_IOMMU_SVM
diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c
index 39b2d91..bb87d35 100644
--- a/drivers/iommu/iommu-sysfs.c
+++ b/drivers/iommu/iommu-sysfs.c
@@ -50,54 +50,45 @@ static int __init iommu_dev_init(void)
postcore_initcall(iommu_dev_init);
/*
- * Create an IOMMU device and return a pointer to it. IOMMU specific
- * attributes can be provided as an attribute group, allowing a unique
- * namespace per IOMMU type.
+ * Init the struct device for the IOMMU. IOMMU specific attributes can
+ * be provided as an attribute group, allowing a unique namespace per
+ * IOMMU type.
*/
-struct device *iommu_device_create(struct device *parent, void *drvdata,
- const struct attribute_group **groups,
- const char *fmt, ...)
+int iommu_device_sysfs_add(struct iommu_device *iommu,
+ struct device *parent,
+ const struct attribute_group **groups,
+ const char *fmt, ...)
{
- struct device *dev;
va_list vargs;
int ret;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return ERR_PTR(-ENOMEM);
+ device_initialize(&iommu->dev);
- device_initialize(dev);
-
- dev->class = &iommu_class;
- dev->parent = parent;
- dev->groups = groups;
- dev_set_drvdata(dev, drvdata);
+ iommu->dev.class = &iommu_class;
+ iommu->dev.parent = parent;
+ iommu->dev.groups = groups;
va_start(vargs, fmt);
- ret = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
+ ret = kobject_set_name_vargs(&iommu->dev.kobj, fmt, vargs);
va_end(vargs);
if (ret)
goto error;
- ret = device_add(dev);
+ ret = device_add(&iommu->dev);
if (ret)
goto error;
- return dev;
+ return 0;
error:
- put_device(dev);
- return ERR_PTR(ret);
+ put_device(&iommu->dev);
+ return ret;
}
-void iommu_device_destroy(struct device *dev)
+void iommu_device_sysfs_remove(struct iommu_device *iommu)
{
- if (!dev || IS_ERR(dev))
- return;
-
- device_unregister(dev);
+ device_unregister(&iommu->dev);
}
-
/*
* IOMMU drivers can indicate a device is managed by a given IOMMU using
* 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 99a65a3..3ba9b53 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -440,7 +440,6 @@ struct intel_iommu {
struct irq_domain *ir_domain;
struct irq_domain *ir_msi_domain;
#endif
- struct device *iommu_dev; /* IOMMU-sysfs device */
struct iommu_device iommu; /* IOMMU core code handle */
int node;
u32 flags; /* Software defined flags */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 4e2d2ca..b6544b6 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -209,14 +209,21 @@ struct iommu_ops {
* instance
* @list: Used by the iommu-core to keep a list of registered iommus
* @ops: iommu-ops for talking to this iommu
+ * @dev: struct device for sysfs handling
*/
struct iommu_device {
struct list_head list;
const struct iommu_ops *ops;
+ struct device dev;
};
int iommu_device_register(struct iommu_device *iommu);
void iommu_device_unregister(struct iommu_device *iommu);
+int iommu_device_sysfs_add(struct iommu_device *iommu,
+ struct device *parent,
+ const struct attribute_group **groups,
+ const char *fmt, ...) __printf(4, 5);
+void iommu_device_sysfs_remove(struct iommu_device *iommu);
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */
@@ -281,10 +288,6 @@ extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,
void *data);
extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,
void *data);
-struct device *iommu_device_create(struct device *parent, void *drvdata,
- const struct attribute_group **groups,
- const char *fmt, ...) __printf(4, 5);
-void iommu_device_destroy(struct device *dev);
int iommu_device_link(struct device *dev, struct device *link);
void iommu_device_unlink(struct device *dev, struct device *link);
@@ -572,6 +575,18 @@ static inline void iommu_device_unregister(struct iommu_device *iommu)
{
}
+static inline int iommu_device_sysfs_add(struct iommu_device *iommu,
+ struct device *parent,
+ const struct attribute_group **groups,
+ const char *fmt, ...)
+{
+ return -ENODEV;
+}
+
+static inline void iommu_device_sysfs_remove(struct iommu_device *iommu)
+{
+}
+
static inline int iommu_device_link(struct device *dev, struct device *link)
{
return -EINVAL;
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web