From 7db34102e08116d24fa2a6e3c9b55bf79da8f014 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 26 Aug 2011 16:48:26 +0200 Subject: [PATCH] --- yaml --- r: 271579 b: refs/heads/master c: ff21776d12ff7993a6b236b8273ef62777d25dfb h: refs/heads/master i: 271577: 3acdbc78ce6c380bcadf04b4b77f9eb22a45f655 271575: 111f4e469f59c90539ca3b97eae757965435c983 v: v3 --- [refs] | 2 +- trunk/drivers/iommu/iommu.c | 31 +++++++++++++++++++++++++++++++ trunk/include/linux/device.h | 6 ++++++ trunk/include/linux/iommu.h | 2 ++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 45856f6765b2..f6a778e0df84 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 39d4ebb95925046863dc0ef2698dfcf2c1f1dcbe +refs/heads/master: ff21776d12ff7993a6b236b8273ef62777d25dfb diff --git a/trunk/drivers/iommu/iommu.c b/trunk/drivers/iommu/iommu.c index 30b064497486..3343264f5105 100644 --- a/trunk/drivers/iommu/iommu.c +++ b/trunk/drivers/iommu/iommu.c @@ -34,6 +34,37 @@ void register_iommu(struct iommu_ops *ops) iommu_ops = ops; } +static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops) +{ +} + +/** + * bus_set_iommu - set iommu-callbacks for the bus + * @bus: bus. + * @ops: the callbacks provided by the iommu-driver + * + * This function is called by an iommu driver to set the iommu methods + * used for a particular bus. Drivers for devices on that bus can use + * the iommu-api after these ops are registered. + * This special function is needed because IOMMUs are usually devices on + * the bus itself, so the iommu drivers are not initialized when the bus + * is set up. With this function the iommu-driver can set the iommu-ops + * afterwards. + */ +int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops) +{ + if (bus->iommu_ops != NULL) + return -EBUSY; + + bus->iommu_ops = ops; + + /* Do IOMMU specific setup for this bus-type */ + iommu_bus_init(bus, ops); + + return 0; +} +EXPORT_SYMBOL_GPL(bus_set_iommu); + bool iommu_found(void) { return iommu_ops != NULL; diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index c20dfbfc49b4..e838e143baa7 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -33,6 +33,7 @@ struct class; struct subsys_private; struct bus_type; struct device_node; +struct iommu_ops; struct bus_attribute { struct attribute attr; @@ -67,6 +68,9 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * @resume: Called to bring a device on this bus out of sleep mode. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. + * @iommu_ops IOMMU specific operations for this bus, used to attach IOMMU + * driver implementations to a bus and allow the driver to do + * bus-specific setup * @p: The private data of the driver core, only the driver core can * touch this. * @@ -96,6 +100,8 @@ struct bus_type { const struct dev_pm_ops *pm; + struct iommu_ops *iommu_ops; + struct subsys_private *p; }; diff --git a/trunk/include/linux/iommu.h b/trunk/include/linux/iommu.h index 6470cd87b4ea..dca83d3405b1 100644 --- a/trunk/include/linux/iommu.h +++ b/trunk/include/linux/iommu.h @@ -25,6 +25,7 @@ #define IOMMU_WRITE (2) #define IOMMU_CACHE (4) /* DMA cache coherency */ +struct bus_type; struct device; struct iommu_domain { @@ -52,6 +53,7 @@ struct iommu_ops { }; extern void register_iommu(struct iommu_ops *ops); +extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); extern bool iommu_found(void); extern struct iommu_domain *iommu_domain_alloc(void); extern void iommu_domain_free(struct iommu_domain *domain);