Skip to content

Commit

Permalink
drivers: iommu: Add iommu_add_device api
Browse files Browse the repository at this point in the history
The code to call IOMMU driver's add_device is same
for both OF and ACPI cases. So add an api which can
be shared across both the places.

Also, now with probe-deferral the iommu master devices gets
added to the respective iommus during probe time instead
of device creation time. The xlate callbacks of iommu
drivers are also called only at probe time. As a result
the add_iommu_group which gets called when the iommu is
registered to add all devices created before the iommu
becomes dummy. Similar the BUS_NOTIFY_ADD_DEVICE notification
also is not needed. So just cleanup those code.

Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
  • Loading branch information
Sricharan R authored and robclark committed Mar 7, 2017
1 parent 952285a commit e244426
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 74 deletions.
12 changes: 1 addition & 11 deletions drivers/acpi/arm64/iort.c
Expand Up @@ -642,17 +642,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
}
}

/*
* If we have reason to believe the IOMMU driver missed the initial
* add_device callback for dev, replay it to get things in order.
*/
if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
dev->bus && !dev->iommu_group) {
int err = ops->add_device(dev);

if (err)
ops = ERR_PTR(err);
}
ops = iommu_add_device(dev, ops);

return ops;
}
Expand Down
70 changes: 17 additions & 53 deletions drivers/iommu/iommu.c
Expand Up @@ -1034,41 +1034,6 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
return group->default_domain;
}

static int add_iommu_group(struct device *dev, void *data)
{
struct iommu_callback_data *cb = data;
const struct iommu_ops *ops = cb->ops;
int ret;

if (!ops->add_device)
return 0;

WARN_ON(dev->iommu_group);

ret = ops->add_device(dev);

/*
* We ignore -ENODEV errors for now, as they just mean that the
* device is not translated by an IOMMU. We still care about
* other errors and fail to initialize when they happen.
*/
if (ret == -ENODEV)
ret = 0;

return ret;
}

static int remove_iommu_group(struct device *dev, void *data)
{
struct iommu_callback_data *cb = data;
const struct iommu_ops *ops = cb->ops;

if (ops->remove_device && dev->iommu_group)
ops->remove_device(dev);

return 0;
}

static int iommu_bus_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
Expand All @@ -1078,13 +1043,10 @@ static int iommu_bus_notifier(struct notifier_block *nb,
unsigned long group_action = 0;

/*
* ADD/DEL call into iommu driver ops if provided, which may
* DEL call into iommu driver ops if provided, which may
* result in ADD/DEL notifiers to group->notifier
*/
if (action == BUS_NOTIFY_ADD_DEVICE) {
if (ops->add_device)
return ops->add_device(dev);
} else if (action == BUS_NOTIFY_REMOVED_DEVICE) {
if (action == BUS_NOTIFY_REMOVED_DEVICE) {
if (ops->remove_device && dev->iommu_group) {
ops->remove_device(dev);
return 0;
Expand Down Expand Up @@ -1126,9 +1088,6 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
{
int err;
struct notifier_block *nb;
struct iommu_callback_data cb = {
.ops = ops,
};

nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
if (!nb)
Expand All @@ -1140,18 +1099,8 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
if (err)
goto out_free;

err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
if (err)
goto out_err;


return 0;

out_err:
/* Clean up */
bus_for_each_dev(bus, NULL, &cb, remove_iommu_group);
bus_unregister_notifier(bus, nb);

out_free:
kfree(nb);

Expand Down Expand Up @@ -1272,6 +1221,21 @@ static int __iommu_attach_device(struct iommu_domain *domain,
return ret;
}

const struct iommu_ops *iommu_add_device(struct device *dev,
const struct iommu_ops *ops)
{
if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
dev->bus && !dev->iommu_group) {
int err = ops->add_device(dev);

if (err)
ops = ERR_PTR(err);
}

return ops;
}
EXPORT_SYMBOL_GPL(iommu_add_device);

int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
Expand Down
11 changes: 1 addition & 10 deletions drivers/iommu/of_iommu.c
Expand Up @@ -224,17 +224,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
else
ops = of_platform_iommu_init(dev, master_np);
/*
* If we have reason to believe the IOMMU driver missed the initial
* add_device callback for dev, replay it to get things in order.
*/
if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
dev->bus && !dev->iommu_group) {
int err = ops->add_device(dev);

if (err)
ops = ERR_PTR(err);
}
ops = iommu_add_device(dev, ops);

return ops;
}
Expand Down
8 changes: 8 additions & 0 deletions include/linux/iommu.h
Expand Up @@ -268,6 +268,8 @@ extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap);
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
extern struct iommu_group *iommu_group_get_by_id(int id);
extern void iommu_domain_free(struct iommu_domain *domain);
extern const struct iommu_ops *iommu_add_device(struct device *dev,
const struct iommu_ops *ops);
extern int iommu_attach_device(struct iommu_domain *domain,
struct device *dev);
extern void iommu_detach_device(struct iommu_domain *domain,
Expand Down Expand Up @@ -434,6 +436,12 @@ static inline void iommu_domain_free(struct iommu_domain *domain)
{
}

static inline const struct iommu_ops *iommu_add_device(struct device *dev,
const struct iommu_ops *ops)
{
return NULL;
}

static inline int iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
Expand Down

0 comments on commit e244426

Please sign in to comment.