@@ -137,6 +137,30 @@ int iommu_release_dt_devices(struct domain *d)
return 0;
}
+static int iommu_dt_xlate(struct device *dev,
+ const struct dt_phandle_args *iommu_spec,
+ const struct iommu_ops *ops)
+{
+ int rc;
+
+ if ( !ops->dt_xlate )
+ return -EINVAL;
+
+ if ( !dt_device_is_available(iommu_spec->np) )
+ return NO_IOMMU;
+
+ rc = iommu_fwspec_init(dev, &iommu_spec->np->dev);
+ if ( rc )
+ return rc;
+
+ /*
+ * Provide DT IOMMU specifier which describes the IOMMU master
+ * interfaces of that device (device IDs, etc) to the driver.
+ * The driver is responsible to decide how to interpret them.
+ */
+ return ops->dt_xlate(dev, iommu_spec);
+}
+
int iommu_remove_dt_device(struct dt_device_node *np)
{
const struct iommu_ops *ops = iommu_get_ops();
@@ -146,7 +170,7 @@ int iommu_remove_dt_device(struct dt_device_node *np)
ASSERT(rw_is_locked(&dt_host_lock));
if ( !iommu_enabled )
- return 1;
+ return NO_IOMMU;
if ( !ops )
return -EOPNOTSUPP;
@@ -187,12 +211,12 @@ int iommu_add_dt_device(struct dt_device_node *np)
const struct iommu_ops *ops = iommu_get_ops();
struct dt_phandle_args iommu_spec;
struct device *dev = dt_to_dev(np);
- int rc = 1, index = 0;
+ int rc = NO_IOMMU, index = 0;
ASSERT(system_state < SYS_STATE_active || rw_is_locked(&dt_host_lock));
if ( !iommu_enabled )
- return 1;
+ return NO_IOMMU;
if ( !ops )
return -EINVAL;
@@ -215,27 +239,15 @@ int iommu_add_dt_device(struct dt_device_node *np)
{
/*
* The driver which supports generic IOMMU DT bindings must have
- * these callback implemented.
+ * this callback implemented.
*/
- if ( !ops->add_device || !ops->dt_xlate )
+ if ( !ops->add_device )
{
rc = -EINVAL;
goto fail;
}
- if ( !dt_device_is_available(iommu_spec.np) )
- break;
-
- rc = iommu_fwspec_init(dev, &iommu_spec.np->dev);
- if ( rc )
- break;
-
- /*
- * Provide DT IOMMU specifier which describes the IOMMU master
- * interfaces of that device (device IDs, etc) to the driver.
- * The driver is responsible to decide how to interpret them.
- */
- rc = ops->dt_xlate(dev, &iommu_spec);
+ rc = iommu_dt_xlate(dev, &iommu_spec, ops);
if ( rc )
break;
@@ -238,6 +238,9 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
*/
int iommu_remove_dt_device(struct dt_device_node *np);
+/* Error code for reporting no IOMMU is present */
+#define NO_IOMMU 1
+
#endif /* HAS_DEVICE_TREE */
struct page_info;