diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 12:16:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 12:16:56 -0500 |
commit | a26be149facb22d30cd92cadb26f651d6fe802c9 (patch) | |
tree | c467bd0cae818ef793e9a694b4cd2bdc88d9ff6b /include/linux | |
parent | cdd305454ebd181fa35b648c0921fe7df27d6f3b (diff) | |
parent | a20cc76b9efae10c20123049df361adcd7f0e0b3 (diff) |
Merge tag 'iommu-updates-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU updates from Joerg Roedel:
"This time with:
- Generic page-table framework for ARM IOMMUs using the LPAE
page-table format, ARM-SMMU and Renesas IPMMU make use of it
already.
- Break out the IO virtual address allocator from the Intel IOMMU so
that it can be used by other DMA-API implementations too. The
first user will be the ARM64 common DMA-API implementation for
IOMMUs
- Device tree support for Renesas IPMMU
- Various fixes and cleanups all over the place"
* tag 'iommu-updates-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (36 commits)
iommu/amd: Convert non-returned local variable to boolean when relevant
iommu: Update my email address
iommu/amd: Use wait_event in put_pasid_state_wait
iommu/amd: Fix amd_iommu_free_device()
iommu/arm-smmu: Avoid build warning
iommu/fsl: Various cleanups
iommu/fsl: Use %pa to print phys_addr_t
iommu/omap: Print phys_addr_t using %pa
iommu: Make more drivers depend on COMPILE_TEST
iommu/ipmmu-vmsa: Fix IOMMU lookup when multiple IOMMUs are registered
iommu: Disable on !MMU builds
iommu/fsl: Remove unused fsl_of_pamu_ids[]
iommu/fsl: Fix section mismatch
iommu/ipmmu-vmsa: Use the ARM LPAE page table allocator
iommu: Fix trace_map() to report original iova and original size
iommu/arm-smmu: add support for iova_to_phys through ATS1PR
iopoll: Introduce memory-mapped IO polling macros
iommu/arm-smmu: don't touch the secure STLBIALL register
iommu/arm-smmu: make use of generic LPAE allocator
iommu: io-pgtable-arm: add non-secure quirk
...
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/iopoll.h | 144 | ||||
-rw-r--r-- | include/linux/iova.h | 41 | ||||
-rw-r--r-- | include/linux/platform_data/ipmmu-vmsa.h | 24 |
3 files changed, 181 insertions, 28 deletions
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h new file mode 100644 index 000000000000..1c30014ed176 --- /dev/null +++ b/include/linux/iopoll.h | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef _LINUX_IOPOLL_H | ||
16 | #define _LINUX_IOPOLL_H | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/hrtimer.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/io.h> | ||
24 | |||
25 | /** | ||
26 | * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs | ||
27 | * @op: accessor function (takes @addr as its only argument) | ||
28 | * @addr: Address to poll | ||
29 | * @val: Variable to read the value into | ||
30 | * @cond: Break condition (usually involving @val) | ||
31 | * @sleep_us: Maximum time to sleep between reads in us (0 | ||
32 | * tight-loops). Should be less than ~20ms since usleep_range | ||
33 | * is used (see Documentation/timers/timers-howto.txt). | ||
34 | * @timeout_us: Timeout in us, 0 means never timeout | ||
35 | * | ||
36 | * Returns 0 on success and -ETIMEDOUT upon a timeout. In either | ||
37 | * case, the last read value at @addr is stored in @val. Must not | ||
38 | * be called from atomic context if sleep_us or timeout_us are used. | ||
39 | * | ||
40 | * When available, you'll probably want to use one of the specialized | ||
41 | * macros defined below rather than this macro directly. | ||
42 | */ | ||
43 | #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ | ||
44 | ({ \ | ||
45 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | ||
46 | might_sleep_if(sleep_us); \ | ||
47 | for (;;) { \ | ||
48 | (val) = op(addr); \ | ||
49 | if (cond) \ | ||
50 | break; \ | ||
51 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | ||
52 | (val) = op(addr); \ | ||
53 | break; \ | ||
54 | } \ | ||
55 | if (sleep_us) \ | ||
56 | usleep_range((sleep_us >> 2) + 1, sleep_us); \ | ||
57 | } \ | ||
58 | (cond) ? 0 : -ETIMEDOUT; \ | ||
59 | }) | ||
60 | |||
61 | /** | ||
62 | * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs | ||
63 | * @op: accessor function (takes @addr as its only argument) | ||
64 | * @addr: Address to poll | ||
65 | * @val: Variable to read the value into | ||
66 | * @cond: Break condition (usually involving @val) | ||
67 | * @delay_us: Time to udelay between reads in us (0 tight-loops). Should | ||
68 | * be less than ~10us since udelay is used (see | ||
69 | * Documentation/timers/timers-howto.txt). | ||
70 | * @timeout_us: Timeout in us, 0 means never timeout | ||
71 | * | ||
72 | * Returns 0 on success and -ETIMEDOUT upon a timeout. In either | ||
73 | * case, the last read value at @addr is stored in @val. | ||
74 | * | ||
75 | * When available, you'll probably want to use one of the specialized | ||
76 | * macros defined below rather than this macro directly. | ||
77 | */ | ||
78 | #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \ | ||
79 | ({ \ | ||
80 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | ||
81 | for (;;) { \ | ||
82 | (val) = op(addr); \ | ||
83 | if (cond) \ | ||
84 | break; \ | ||
85 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | ||
86 | (val) = op(addr); \ | ||
87 | break; \ | ||
88 | } \ | ||
89 | if (delay_us) \ | ||
90 | udelay(delay_us); \ | ||
91 | } \ | ||
92 | (cond) ? 0 : -ETIMEDOUT; \ | ||
93 | }) | ||
94 | |||
95 | |||
96 | #define readb_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
97 | readx_poll_timeout(readb, addr, val, cond, delay_us, timeout_us) | ||
98 | |||
99 | #define readb_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
100 | readx_poll_timeout_atomic(readb, addr, val, cond, delay_us, timeout_us) | ||
101 | |||
102 | #define readw_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
103 | readx_poll_timeout(readw, addr, val, cond, delay_us, timeout_us) | ||
104 | |||
105 | #define readw_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
106 | readx_poll_timeout_atomic(readw, addr, val, cond, delay_us, timeout_us) | ||
107 | |||
108 | #define readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
109 | readx_poll_timeout(readl, addr, val, cond, delay_us, timeout_us) | ||
110 | |||
111 | #define readl_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
112 | readx_poll_timeout_atomic(readl, addr, val, cond, delay_us, timeout_us) | ||
113 | |||
114 | #define readq_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
115 | readx_poll_timeout(readq, addr, val, cond, delay_us, timeout_us) | ||
116 | |||
117 | #define readq_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
118 | readx_poll_timeout_atomic(readq, addr, val, cond, delay_us, timeout_us) | ||
119 | |||
120 | #define readb_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
121 | readx_poll_timeout(readb_relaxed, addr, val, cond, delay_us, timeout_us) | ||
122 | |||
123 | #define readb_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
124 | readx_poll_timeout_atomic(readb_relaxed, addr, val, cond, delay_us, timeout_us) | ||
125 | |||
126 | #define readw_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
127 | readx_poll_timeout(readw_relaxed, addr, val, cond, delay_us, timeout_us) | ||
128 | |||
129 | #define readw_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
130 | readx_poll_timeout_atomic(readw_relaxed, addr, val, cond, delay_us, timeout_us) | ||
131 | |||
132 | #define readl_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
133 | readx_poll_timeout(readl_relaxed, addr, val, cond, delay_us, timeout_us) | ||
134 | |||
135 | #define readl_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
136 | readx_poll_timeout_atomic(readl_relaxed, addr, val, cond, delay_us, timeout_us) | ||
137 | |||
138 | #define readq_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | ||
139 | readx_poll_timeout(readq_relaxed, addr, val, cond, delay_us, timeout_us) | ||
140 | |||
141 | #define readq_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | ||
142 | readx_poll_timeout_atomic(readq_relaxed, addr, val, cond, delay_us, timeout_us) | ||
143 | |||
144 | #endif /* _LINUX_IOPOLL_H */ | ||
diff --git a/include/linux/iova.h b/include/linux/iova.h index 19e81d5ccb6d..3920a19d8194 100644 --- a/include/linux/iova.h +++ b/include/linux/iova.h | |||
@@ -16,9 +16,6 @@ | |||
16 | #include <linux/rbtree.h> | 16 | #include <linux/rbtree.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | 18 | ||
19 | /* IO virtual address start page frame number */ | ||
20 | #define IOVA_START_PFN (1) | ||
21 | |||
22 | /* iova structure */ | 19 | /* iova structure */ |
23 | struct iova { | 20 | struct iova { |
24 | struct rb_node node; | 21 | struct rb_node node; |
@@ -31,6 +28,8 @@ struct iova_domain { | |||
31 | spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ | 28 | spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ |
32 | struct rb_root rbroot; /* iova domain rbtree root */ | 29 | struct rb_root rbroot; /* iova domain rbtree root */ |
33 | struct rb_node *cached32_node; /* Save last alloced node */ | 30 | struct rb_node *cached32_node; /* Save last alloced node */ |
31 | unsigned long granule; /* pfn granularity for this domain */ | ||
32 | unsigned long start_pfn; /* Lower limit for this domain */ | ||
34 | unsigned long dma_32bit_pfn; | 33 | unsigned long dma_32bit_pfn; |
35 | }; | 34 | }; |
36 | 35 | ||
@@ -39,6 +38,39 @@ static inline unsigned long iova_size(struct iova *iova) | |||
39 | return iova->pfn_hi - iova->pfn_lo + 1; | 38 | return iova->pfn_hi - iova->pfn_lo + 1; |
40 | } | 39 | } |
41 | 40 | ||
41 | static inline unsigned long iova_shift(struct iova_domain *iovad) | ||
42 | { | ||
43 | return __ffs(iovad->granule); | ||
44 | } | ||
45 | |||
46 | static inline unsigned long iova_mask(struct iova_domain *iovad) | ||
47 | { | ||
48 | return iovad->granule - 1; | ||
49 | } | ||
50 | |||
51 | static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova) | ||
52 | { | ||
53 | return iova & iova_mask(iovad); | ||
54 | } | ||
55 | |||
56 | static inline size_t iova_align(struct iova_domain *iovad, size_t size) | ||
57 | { | ||
58 | return ALIGN(size, iovad->granule); | ||
59 | } | ||
60 | |||
61 | static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova) | ||
62 | { | ||
63 | return (dma_addr_t)iova->pfn_lo << iova_shift(iovad); | ||
64 | } | ||
65 | |||
66 | static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova) | ||
67 | { | ||
68 | return iova >> iova_shift(iovad); | ||
69 | } | ||
70 | |||
71 | int iommu_iova_cache_init(void); | ||
72 | void iommu_iova_cache_destroy(void); | ||
73 | |||
42 | struct iova *alloc_iova_mem(void); | 74 | struct iova *alloc_iova_mem(void); |
43 | void free_iova_mem(struct iova *iova); | 75 | void free_iova_mem(struct iova *iova); |
44 | void free_iova(struct iova_domain *iovad, unsigned long pfn); | 76 | void free_iova(struct iova_domain *iovad, unsigned long pfn); |
@@ -49,7 +81,8 @@ struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size, | |||
49 | struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, | 81 | struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, |
50 | unsigned long pfn_hi); | 82 | unsigned long pfn_hi); |
51 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); | 83 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); |
52 | void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); | 84 | void init_iova_domain(struct iova_domain *iovad, unsigned long granule, |
85 | unsigned long start_pfn, unsigned long pfn_32bit); | ||
53 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); | 86 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); |
54 | void put_iova_domain(struct iova_domain *iovad); | 87 | void put_iova_domain(struct iova_domain *iovad); |
55 | struct iova *split_and_remove_iova(struct iova_domain *iovad, | 88 | struct iova *split_and_remove_iova(struct iova_domain *iovad, |
diff --git a/include/linux/platform_data/ipmmu-vmsa.h b/include/linux/platform_data/ipmmu-vmsa.h deleted file mode 100644 index 5275b3ac6d37..000000000000 --- a/include/linux/platform_data/ipmmu-vmsa.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * IPMMU VMSA Platform Data | ||
3 | * | ||
4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | */ | ||
10 | |||
11 | #ifndef __IPMMU_VMSA_H__ | ||
12 | #define __IPMMU_VMSA_H__ | ||
13 | |||
14 | struct ipmmu_vmsa_master { | ||
15 | const char *name; | ||
16 | unsigned int utlb; | ||
17 | }; | ||
18 | |||
19 | struct ipmmu_vmsa_platform_data { | ||
20 | const struct ipmmu_vmsa_master *masters; | ||
21 | unsigned int num_masters; | ||
22 | }; | ||
23 | |||
24 | #endif /* __IPMMU_VMSA_H__ */ | ||