diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 11:49:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 11:49:28 -0400 |
commit | 2f83766d4b18774c856329a8fca4c9338dfeda39 (patch) | |
tree | a19ea2165755f5700d7f37a61ece7edce231744f | |
parent | 4523e1458566a0e8ecfaff90f380dd23acc44d27 (diff) | |
parent | 28f8571e1e84782244cc7bf1b129baf6cdc0832e (diff) |
Merge tag 'iommu-updates-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU updates from Joerg Roedel:
"Not much stuff this time. The only change to the IOMMU core code is
the addition of a handle to the fault handling code. A few updates to
the AMD IOMMU driver to work around new errata. The other patches are
mostly fixes and enhancements to the existing ARM IOMMU drivers and
documentation updates.
A new IOMMU driver for the Exynos platform was also underway but got
merged via the Samsung tree and is not part of this tree."
* tag 'iommu-updates-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
Documentation: kernel-parameters.txt Add amd_iommu_dump
iommu/core: pass a user-provided token to fault handlers
iommu/tegra: gart: Fix register offset correctly
iommu: OMAP: device detach on domain destroy
iommu: tegra/gart: Add device tree support
iommu: tegra/gart: use correct gart_device
iommu/tegra: smmu: Print device name correctly
iommu/amd: Add workaround for event log erratum
iommu/amd: Check for the right TLP prefix bit
dma-debug: release free_entries_lock before saving stack trace
-rw-r--r-- | Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt | 14 | ||||
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu.c | 37 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 5 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 32 | ||||
-rw-r--r-- | drivers/iommu/tegra-gart.c | 20 | ||||
-rw-r--r-- | drivers/iommu/tegra-smmu.c | 2 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 4 | ||||
-rw-r--r-- | include/linux/iommu.h | 10 | ||||
-rw-r--r-- | lib/dma-debug.c | 10 |
10 files changed, 104 insertions, 36 deletions
diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt new file mode 100644 index 000000000000..099d9362ebc1 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | NVIDIA Tegra 20 GART | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "nvidia,tegra20-gart" | ||
5 | - reg: Two pairs of cells specifying the physical address and size of | ||
6 | the memory controller registers and the GART aperture respectively. | ||
7 | |||
8 | Example: | ||
9 | |||
10 | gart { | ||
11 | compatible = "nvidia,tegra20-gart"; | ||
12 | reg = <0x7000f024 0x00000018 /* controller registers */ | ||
13 | 0x58000000 0x02000000>; /* GART aperture */ | ||
14 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b40b413db88e..c45513d806ab 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -335,6 +335,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
335 | requirements as needed. This option | 335 | requirements as needed. This option |
336 | does not override iommu=pt | 336 | does not override iommu=pt |
337 | 337 | ||
338 | amd_iommu_dump= [HW,X86-64] | ||
339 | Enable AMD IOMMU driver option to dump the ACPI table | ||
340 | for AMD IOMMU. With this option enabled, AMD IOMMU | ||
341 | driver will print ACPI tables for AMD IOMMU during | ||
342 | IOMMU initialization. | ||
343 | |||
338 | amijoy.map= [HW,JOY] Amiga joystick support | 344 | amijoy.map= [HW,JOY] Amiga joystick support |
339 | Map of devices attached to JOY0DAT and JOY1DAT | 345 | Map of devices attached to JOY0DAT and JOY1DAT |
340 | Format: <a>,<b> | 346 | Format: <a>,<b> |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a5bee8e2dfce..d90a421e9cac 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -450,12 +450,27 @@ static void dump_command(unsigned long phys_addr) | |||
450 | 450 | ||
451 | static void iommu_print_event(struct amd_iommu *iommu, void *__evt) | 451 | static void iommu_print_event(struct amd_iommu *iommu, void *__evt) |
452 | { | 452 | { |
453 | u32 *event = __evt; | 453 | int type, devid, domid, flags; |
454 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | 454 | volatile u32 *event = __evt; |
455 | int devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; | 455 | int count = 0; |
456 | int domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK; | 456 | u64 address; |
457 | int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; | 457 | |
458 | u64 address = (u64)(((u64)event[3]) << 32) | event[2]; | 458 | retry: |
459 | type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | ||
460 | devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; | ||
461 | domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK; | ||
462 | flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; | ||
463 | address = (u64)(((u64)event[3]) << 32) | event[2]; | ||
464 | |||
465 | if (type == 0) { | ||
466 | /* Did we hit the erratum? */ | ||
467 | if (++count == LOOP_TIMEOUT) { | ||
468 | pr_err("AMD-Vi: No event written to event log\n"); | ||
469 | return; | ||
470 | } | ||
471 | udelay(1); | ||
472 | goto retry; | ||
473 | } | ||
459 | 474 | ||
460 | printk(KERN_ERR "AMD-Vi: Event logged ["); | 475 | printk(KERN_ERR "AMD-Vi: Event logged ["); |
461 | 476 | ||
@@ -508,6 +523,8 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) | |||
508 | default: | 523 | default: |
509 | printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type); | 524 | printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type); |
510 | } | 525 | } |
526 | |||
527 | memset(__evt, 0, 4 * sizeof(u32)); | ||
511 | } | 528 | } |
512 | 529 | ||
513 | static void iommu_poll_events(struct amd_iommu *iommu) | 530 | static void iommu_poll_events(struct amd_iommu *iommu) |
@@ -2035,20 +2052,20 @@ out_err: | |||
2035 | } | 2052 | } |
2036 | 2053 | ||
2037 | /* FIXME: Move this to PCI code */ | 2054 | /* FIXME: Move this to PCI code */ |
2038 | #define PCI_PRI_TLP_OFF (1 << 2) | 2055 | #define PCI_PRI_TLP_OFF (1 << 15) |
2039 | 2056 | ||
2040 | bool pci_pri_tlp_required(struct pci_dev *pdev) | 2057 | bool pci_pri_tlp_required(struct pci_dev *pdev) |
2041 | { | 2058 | { |
2042 | u16 control; | 2059 | u16 status; |
2043 | int pos; | 2060 | int pos; |
2044 | 2061 | ||
2045 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); | 2062 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); |
2046 | if (!pos) | 2063 | if (!pos) |
2047 | return false; | 2064 | return false; |
2048 | 2065 | ||
2049 | pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); | 2066 | pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); |
2050 | 2067 | ||
2051 | return (control & PCI_PRI_TLP_OFF) ? true : false; | 2068 | return (status & PCI_PRI_TLP_OFF) ? true : false; |
2052 | } | 2069 | } |
2053 | 2070 | ||
2054 | /* | 2071 | /* |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 2198b2dbbcd3..8b9ded88e6f5 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -119,6 +119,7 @@ EXPORT_SYMBOL_GPL(iommu_present); | |||
119 | * iommu_set_fault_handler() - set a fault handler for an iommu domain | 119 | * iommu_set_fault_handler() - set a fault handler for an iommu domain |
120 | * @domain: iommu domain | 120 | * @domain: iommu domain |
121 | * @handler: fault handler | 121 | * @handler: fault handler |
122 | * @token: user data, will be passed back to the fault handler | ||
122 | * | 123 | * |
123 | * This function should be used by IOMMU users which want to be notified | 124 | * This function should be used by IOMMU users which want to be notified |
124 | * whenever an IOMMU fault happens. | 125 | * whenever an IOMMU fault happens. |
@@ -127,11 +128,13 @@ EXPORT_SYMBOL_GPL(iommu_present); | |||
127 | * error code otherwise. | 128 | * error code otherwise. |
128 | */ | 129 | */ |
129 | void iommu_set_fault_handler(struct iommu_domain *domain, | 130 | void iommu_set_fault_handler(struct iommu_domain *domain, |
130 | iommu_fault_handler_t handler) | 131 | iommu_fault_handler_t handler, |
132 | void *token) | ||
131 | { | 133 | { |
132 | BUG_ON(!domain); | 134 | BUG_ON(!domain); |
133 | 135 | ||
134 | domain->handler = handler; | 136 | domain->handler = handler; |
137 | domain->handler_token = token; | ||
135 | } | 138 | } |
136 | EXPORT_SYMBOL_GPL(iommu_set_fault_handler); | 139 | EXPORT_SYMBOL_GPL(iommu_set_fault_handler); |
137 | 140 | ||
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 6899dcd02dfa..e70ee2b59df9 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -41,11 +41,13 @@ | |||
41 | * @pgtable: the page table | 41 | * @pgtable: the page table |
42 | * @iommu_dev: an omap iommu device attached to this domain. only a single | 42 | * @iommu_dev: an omap iommu device attached to this domain. only a single |
43 | * iommu device can be attached for now. | 43 | * iommu device can be attached for now. |
44 | * @dev: Device using this domain. | ||
44 | * @lock: domain lock, should be taken when attaching/detaching | 45 | * @lock: domain lock, should be taken when attaching/detaching |
45 | */ | 46 | */ |
46 | struct omap_iommu_domain { | 47 | struct omap_iommu_domain { |
47 | u32 *pgtable; | 48 | u32 *pgtable; |
48 | struct omap_iommu *iommu_dev; | 49 | struct omap_iommu *iommu_dev; |
50 | struct device *dev; | ||
49 | spinlock_t lock; | 51 | spinlock_t lock; |
50 | }; | 52 | }; |
51 | 53 | ||
@@ -1081,6 +1083,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1081 | } | 1083 | } |
1082 | 1084 | ||
1083 | omap_domain->iommu_dev = arch_data->iommu_dev = oiommu; | 1085 | omap_domain->iommu_dev = arch_data->iommu_dev = oiommu; |
1086 | omap_domain->dev = dev; | ||
1084 | oiommu->domain = domain; | 1087 | oiommu->domain = domain; |
1085 | 1088 | ||
1086 | out: | 1089 | out: |
@@ -1088,19 +1091,16 @@ out: | |||
1088 | return ret; | 1091 | return ret; |
1089 | } | 1092 | } |
1090 | 1093 | ||
1091 | static void omap_iommu_detach_dev(struct iommu_domain *domain, | 1094 | static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain, |
1092 | struct device *dev) | 1095 | struct device *dev) |
1093 | { | 1096 | { |
1094 | struct omap_iommu_domain *omap_domain = domain->priv; | ||
1095 | struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; | ||
1096 | struct omap_iommu *oiommu = dev_to_omap_iommu(dev); | 1097 | struct omap_iommu *oiommu = dev_to_omap_iommu(dev); |
1097 | 1098 | struct omap_iommu_arch_data *arch_data = dev->archdata.iommu; | |
1098 | spin_lock(&omap_domain->lock); | ||
1099 | 1099 | ||
1100 | /* only a single device is supported per domain for now */ | 1100 | /* only a single device is supported per domain for now */ |
1101 | if (omap_domain->iommu_dev != oiommu) { | 1101 | if (omap_domain->iommu_dev != oiommu) { |
1102 | dev_err(dev, "invalid iommu device\n"); | 1102 | dev_err(dev, "invalid iommu device\n"); |
1103 | goto out; | 1103 | return; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | iopgtable_clear_entry_all(oiommu); | 1106 | iopgtable_clear_entry_all(oiommu); |
@@ -1108,8 +1108,16 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain, | |||
1108 | omap_iommu_detach(oiommu); | 1108 | omap_iommu_detach(oiommu); |
1109 | 1109 | ||
1110 | omap_domain->iommu_dev = arch_data->iommu_dev = NULL; | 1110 | omap_domain->iommu_dev = arch_data->iommu_dev = NULL; |
1111 | omap_domain->dev = NULL; | ||
1112 | } | ||
1111 | 1113 | ||
1112 | out: | 1114 | static void omap_iommu_detach_dev(struct iommu_domain *domain, |
1115 | struct device *dev) | ||
1116 | { | ||
1117 | struct omap_iommu_domain *omap_domain = domain->priv; | ||
1118 | |||
1119 | spin_lock(&omap_domain->lock); | ||
1120 | _omap_iommu_detach_dev(omap_domain, dev); | ||
1113 | spin_unlock(&omap_domain->lock); | 1121 | spin_unlock(&omap_domain->lock); |
1114 | } | 1122 | } |
1115 | 1123 | ||
@@ -1148,13 +1156,19 @@ out: | |||
1148 | return -ENOMEM; | 1156 | return -ENOMEM; |
1149 | } | 1157 | } |
1150 | 1158 | ||
1151 | /* assume device was already detached */ | ||
1152 | static void omap_iommu_domain_destroy(struct iommu_domain *domain) | 1159 | static void omap_iommu_domain_destroy(struct iommu_domain *domain) |
1153 | { | 1160 | { |
1154 | struct omap_iommu_domain *omap_domain = domain->priv; | 1161 | struct omap_iommu_domain *omap_domain = domain->priv; |
1155 | 1162 | ||
1156 | domain->priv = NULL; | 1163 | domain->priv = NULL; |
1157 | 1164 | ||
1165 | /* | ||
1166 | * An iommu device is still attached | ||
1167 | * (currently, only one device can be attached) ? | ||
1168 | */ | ||
1169 | if (omap_domain->iommu_dev) | ||
1170 | _omap_iommu_detach_dev(omap_domain, omap_domain->dev); | ||
1171 | |||
1158 | kfree(omap_domain->pgtable); | 1172 | kfree(omap_domain->pgtable); |
1159 | kfree(omap_domain); | 1173 | kfree(omap_domain); |
1160 | } | 1174 | } |
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index 779306ee7b16..0c0a37792218 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c | |||
@@ -29,15 +29,17 @@ | |||
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/iommu.h> | 31 | #include <linux/iommu.h> |
32 | #include <linux/of.h> | ||
32 | 33 | ||
33 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
34 | 35 | ||
35 | /* bitmap of the page sizes currently supported */ | 36 | /* bitmap of the page sizes currently supported */ |
36 | #define GART_IOMMU_PGSIZES (SZ_4K) | 37 | #define GART_IOMMU_PGSIZES (SZ_4K) |
37 | 38 | ||
38 | #define GART_CONFIG 0x24 | 39 | #define GART_REG_BASE 0x24 |
39 | #define GART_ENTRY_ADDR 0x28 | 40 | #define GART_CONFIG (0x24 - GART_REG_BASE) |
40 | #define GART_ENTRY_DATA 0x2c | 41 | #define GART_ENTRY_ADDR (0x28 - GART_REG_BASE) |
42 | #define GART_ENTRY_DATA (0x2c - GART_REG_BASE) | ||
41 | #define GART_ENTRY_PHYS_ADDR_VALID (1 << 31) | 43 | #define GART_ENTRY_PHYS_ADDR_VALID (1 << 31) |
42 | 44 | ||
43 | #define GART_PAGE_SHIFT 12 | 45 | #define GART_PAGE_SHIFT 12 |
@@ -158,7 +160,7 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain, | |||
158 | struct gart_client *client, *c; | 160 | struct gart_client *client, *c; |
159 | int err = 0; | 161 | int err = 0; |
160 | 162 | ||
161 | gart = dev_get_drvdata(dev->parent); | 163 | gart = gart_handle; |
162 | if (!gart) | 164 | if (!gart) |
163 | return -EINVAL; | 165 | return -EINVAL; |
164 | domain->priv = gart; | 166 | domain->priv = gart; |
@@ -422,6 +424,14 @@ const struct dev_pm_ops tegra_gart_pm_ops = { | |||
422 | .resume = tegra_gart_resume, | 424 | .resume = tegra_gart_resume, |
423 | }; | 425 | }; |
424 | 426 | ||
427 | #ifdef CONFIG_OF | ||
428 | static struct of_device_id tegra_gart_of_match[] __devinitdata = { | ||
429 | { .compatible = "nvidia,tegra20-gart", }, | ||
430 | { }, | ||
431 | }; | ||
432 | MODULE_DEVICE_TABLE(of, tegra_gart_of_match); | ||
433 | #endif | ||
434 | |||
425 | static struct platform_driver tegra_gart_driver = { | 435 | static struct platform_driver tegra_gart_driver = { |
426 | .probe = tegra_gart_probe, | 436 | .probe = tegra_gart_probe, |
427 | .remove = tegra_gart_remove, | 437 | .remove = tegra_gart_remove, |
@@ -429,6 +439,7 @@ static struct platform_driver tegra_gart_driver = { | |||
429 | .owner = THIS_MODULE, | 439 | .owner = THIS_MODULE, |
430 | .name = "tegra-gart", | 440 | .name = "tegra-gart", |
431 | .pm = &tegra_gart_pm_ops, | 441 | .pm = &tegra_gart_pm_ops, |
442 | .of_match_table = of_match_ptr(tegra_gart_of_match), | ||
432 | }, | 443 | }, |
433 | }; | 444 | }; |
434 | 445 | ||
@@ -448,4 +459,5 @@ module_exit(tegra_gart_exit); | |||
448 | 459 | ||
449 | MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); | 460 | MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); |
450 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | 461 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); |
462 | MODULE_ALIAS("platform:tegra-gart"); | ||
451 | MODULE_LICENSE("GPL v2"); | 463 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index eb93c821f592..ecd679043d77 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -733,7 +733,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain, | |||
733 | pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n"); | 733 | pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n"); |
734 | } | 734 | } |
735 | 735 | ||
736 | dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev)); | 736 | dev_dbg(smmu->dev, "%s is attached\n", dev_name(dev)); |
737 | return 0; | 737 | return 0; |
738 | 738 | ||
739 | err_client: | 739 | err_client: |
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index d6f8adaa26ef..8ea7bccc7100 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -78,7 +78,7 @@ typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail); | |||
78 | * the recovery of the remote processor. | 78 | * the recovery of the remote processor. |
79 | */ | 79 | */ |
80 | static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, | 80 | static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev, |
81 | unsigned long iova, int flags) | 81 | unsigned long iova, int flags, void *token) |
82 | { | 82 | { |
83 | dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags); | 83 | dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags); |
84 | 84 | ||
@@ -117,7 +117,7 @@ static int rproc_enable_iommu(struct rproc *rproc) | |||
117 | return -ENOMEM; | 117 | return -ENOMEM; |
118 | } | 118 | } |
119 | 119 | ||
120 | iommu_set_fault_handler(domain, rproc_iommu_fault); | 120 | iommu_set_fault_handler(domain, rproc_iommu_fault, rproc); |
121 | 121 | ||
122 | ret = iommu_attach_device(domain, dev); | 122 | ret = iommu_attach_device(domain, dev); |
123 | if (ret) { | 123 | if (ret) { |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d937580417ba..450293f6d68b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -35,12 +35,13 @@ struct iommu_domain; | |||
35 | #define IOMMU_FAULT_WRITE 0x1 | 35 | #define IOMMU_FAULT_WRITE 0x1 |
36 | 36 | ||
37 | typedef int (*iommu_fault_handler_t)(struct iommu_domain *, | 37 | typedef int (*iommu_fault_handler_t)(struct iommu_domain *, |
38 | struct device *, unsigned long, int); | 38 | struct device *, unsigned long, int, void *); |
39 | 39 | ||
40 | struct iommu_domain { | 40 | struct iommu_domain { |
41 | struct iommu_ops *ops; | 41 | struct iommu_ops *ops; |
42 | void *priv; | 42 | void *priv; |
43 | iommu_fault_handler_t handler; | 43 | iommu_fault_handler_t handler; |
44 | void *handler_token; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | #define IOMMU_CAP_CACHE_COHERENCY 0x1 | 47 | #define IOMMU_CAP_CACHE_COHERENCY 0x1 |
@@ -95,7 +96,7 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | |||
95 | extern int iommu_domain_has_cap(struct iommu_domain *domain, | 96 | extern int iommu_domain_has_cap(struct iommu_domain *domain, |
96 | unsigned long cap); | 97 | unsigned long cap); |
97 | extern void iommu_set_fault_handler(struct iommu_domain *domain, | 98 | extern void iommu_set_fault_handler(struct iommu_domain *domain, |
98 | iommu_fault_handler_t handler); | 99 | iommu_fault_handler_t handler, void *token); |
99 | extern int iommu_device_group(struct device *dev, unsigned int *groupid); | 100 | extern int iommu_device_group(struct device *dev, unsigned int *groupid); |
100 | 101 | ||
101 | /** | 102 | /** |
@@ -132,7 +133,8 @@ static inline int report_iommu_fault(struct iommu_domain *domain, | |||
132 | * invoke it. | 133 | * invoke it. |
133 | */ | 134 | */ |
134 | if (domain->handler) | 135 | if (domain->handler) |
135 | ret = domain->handler(domain, dev, iova, flags); | 136 | ret = domain->handler(domain, dev, iova, flags, |
137 | domain->handler_token); | ||
136 | 138 | ||
137 | return ret; | 139 | return ret; |
138 | } | 140 | } |
@@ -191,7 +193,7 @@ static inline int domain_has_cap(struct iommu_domain *domain, | |||
191 | } | 193 | } |
192 | 194 | ||
193 | static inline void iommu_set_fault_handler(struct iommu_domain *domain, | 195 | static inline void iommu_set_fault_handler(struct iommu_domain *domain, |
194 | iommu_fault_handler_t handler) | 196 | iommu_fault_handler_t handler, void *token) |
195 | { | 197 | { |
196 | } | 198 | } |
197 | 199 | ||
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 13ef2338be41..518aea714d21 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -430,7 +430,7 @@ static struct dma_debug_entry *__dma_entry_alloc(void) | |||
430 | */ | 430 | */ |
431 | static struct dma_debug_entry *dma_entry_alloc(void) | 431 | static struct dma_debug_entry *dma_entry_alloc(void) |
432 | { | 432 | { |
433 | struct dma_debug_entry *entry = NULL; | 433 | struct dma_debug_entry *entry; |
434 | unsigned long flags; | 434 | unsigned long flags; |
435 | 435 | ||
436 | spin_lock_irqsave(&free_entries_lock, flags); | 436 | spin_lock_irqsave(&free_entries_lock, flags); |
@@ -438,11 +438,14 @@ static struct dma_debug_entry *dma_entry_alloc(void) | |||
438 | if (list_empty(&free_entries)) { | 438 | if (list_empty(&free_entries)) { |
439 | pr_err("DMA-API: debugging out of memory - disabling\n"); | 439 | pr_err("DMA-API: debugging out of memory - disabling\n"); |
440 | global_disable = true; | 440 | global_disable = true; |
441 | goto out; | 441 | spin_unlock_irqrestore(&free_entries_lock, flags); |
442 | return NULL; | ||
442 | } | 443 | } |
443 | 444 | ||
444 | entry = __dma_entry_alloc(); | 445 | entry = __dma_entry_alloc(); |
445 | 446 | ||
447 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
448 | |||
446 | #ifdef CONFIG_STACKTRACE | 449 | #ifdef CONFIG_STACKTRACE |
447 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; | 450 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; |
448 | entry->stacktrace.entries = entry->st_entries; | 451 | entry->stacktrace.entries = entry->st_entries; |
@@ -450,9 +453,6 @@ static struct dma_debug_entry *dma_entry_alloc(void) | |||
450 | save_stack_trace(&entry->stacktrace); | 453 | save_stack_trace(&entry->stacktrace); |
451 | #endif | 454 | #endif |
452 | 455 | ||
453 | out: | ||
454 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
455 | |||
456 | return entry; | 456 | return entry; |
457 | } | 457 | } |
458 | 458 | ||