diff options
| -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 | ||
