diff options
author | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-04-27 01:37:12 -0400 |
---|---|---|
committer | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-05-14 03:23:33 -0400 |
commit | 37c2836c459181cc2ec24827f549a7238e7db39c (patch) | |
tree | c04f74f9f02cbde9406b6fa2e09a7ef81638c653 /arch/arm/plat-omap/iommu.c | |
parent | be6d8026a276e35cce1a2effaf5cd8bf6bd04814 (diff) |
omap iommu: Introduce iteration macro for iotlb entry scan
There are some places to scan iotlb entries. This iteration macro
could make these code a bit simpler with proceeding iotlb entries
transparently.
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Tested-by: Hari Kanigeri <h-kanigeri2@ti.com>
Diffstat (limited to 'arch/arm/plat-omap/iommu.c')
-rw-r--r-- | arch/arm/plat-omap/iommu.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 1e83facb6b77..9598d40e2763 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c | |||
@@ -25,6 +25,11 @@ | |||
25 | 25 | ||
26 | #include "iopgtable.h" | 26 | #include "iopgtable.h" |
27 | 27 | ||
28 | #define for_each_iotlb_cr(obj, n, __i, cr) \ | ||
29 | for (__i = 0; \ | ||
30 | (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ | ||
31 | __i++) | ||
32 | |||
28 | /* accommodate the difference between omap1 and omap2/3 */ | 33 | /* accommodate the difference between omap1 and omap2/3 */ |
29 | static const struct iommu_functions *arch_iommu; | 34 | static const struct iommu_functions *arch_iommu; |
30 | 35 | ||
@@ -211,6 +216,20 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, | |||
211 | return arch_iommu->dump_cr(obj, cr, buf); | 216 | return arch_iommu->dump_cr(obj, cr, buf); |
212 | } | 217 | } |
213 | 218 | ||
219 | /* only used in iotlb iteration for-loop */ | ||
220 | static struct cr_regs __iotlb_read_cr(struct iommu *obj, int n) | ||
221 | { | ||
222 | struct cr_regs cr; | ||
223 | struct iotlb_lock l; | ||
224 | |||
225 | iotlb_lock_get(obj, &l); | ||
226 | l.vict = n; | ||
227 | iotlb_lock_set(obj, &l); | ||
228 | iotlb_read_cr(obj, &cr); | ||
229 | |||
230 | return cr; | ||
231 | } | ||
232 | |||
214 | /** | 233 | /** |
215 | * load_iotlb_entry - Set an iommu tlb entry | 234 | * load_iotlb_entry - Set an iommu tlb entry |
216 | * @obj: target iommu | 235 | * @obj: target iommu |
@@ -218,7 +237,6 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, | |||
218 | **/ | 237 | **/ |
219 | int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) | 238 | int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) |
220 | { | 239 | { |
221 | int i; | ||
222 | int err = 0; | 240 | int err = 0; |
223 | struct iotlb_lock l; | 241 | struct iotlb_lock l; |
224 | struct cr_regs *cr; | 242 | struct cr_regs *cr; |
@@ -235,21 +253,20 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) | |||
235 | goto out; | 253 | goto out; |
236 | } | 254 | } |
237 | if (!e->prsvd) { | 255 | if (!e->prsvd) { |
238 | for (i = l.base; i < obj->nr_tlb_entries; i++) { | 256 | int i; |
239 | struct cr_regs tmp; | 257 | struct cr_regs tmp; |
240 | 258 | ||
241 | iotlb_lock_get(obj, &l); | 259 | for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp) |
242 | l.vict = i; | ||
243 | iotlb_lock_set(obj, &l); | ||
244 | iotlb_read_cr(obj, &tmp); | ||
245 | if (!iotlb_cr_valid(&tmp)) | 260 | if (!iotlb_cr_valid(&tmp)) |
246 | break; | 261 | break; |
247 | } | 262 | |
248 | if (i == obj->nr_tlb_entries) { | 263 | if (i == obj->nr_tlb_entries) { |
249 | dev_dbg(obj->dev, "%s: full: no entry\n", __func__); | 264 | dev_dbg(obj->dev, "%s: full: no entry\n", __func__); |
250 | err = -EBUSY; | 265 | err = -EBUSY; |
251 | goto out; | 266 | goto out; |
252 | } | 267 | } |
268 | |||
269 | iotlb_lock_get(obj, &l); | ||
253 | } else { | 270 | } else { |
254 | l.vict = l.base; | 271 | l.vict = l.base; |
255 | iotlb_lock_set(obj, &l); | 272 | iotlb_lock_set(obj, &l); |
@@ -285,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry); | |||
285 | **/ | 302 | **/ |
286 | void flush_iotlb_page(struct iommu *obj, u32 da) | 303 | void flush_iotlb_page(struct iommu *obj, u32 da) |
287 | { | 304 | { |
288 | struct iotlb_lock l; | ||
289 | int i; | 305 | int i; |
306 | struct cr_regs cr; | ||
290 | 307 | ||
291 | clk_enable(obj->clk); | 308 | clk_enable(obj->clk); |
292 | 309 | ||
293 | for (i = 0; i < obj->nr_tlb_entries; i++) { | 310 | for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) { |
294 | struct cr_regs cr; | ||
295 | u32 start; | 311 | u32 start; |
296 | size_t bytes; | 312 | size_t bytes; |
297 | 313 | ||
298 | iotlb_lock_get(obj, &l); | ||
299 | l.vict = i; | ||
300 | iotlb_lock_set(obj, &l); | ||
301 | iotlb_read_cr(obj, &cr); | ||
302 | if (!iotlb_cr_valid(&cr)) | 314 | if (!iotlb_cr_valid(&cr)) |
303 | continue; | 315 | continue; |
304 | 316 | ||
@@ -308,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da) | |||
308 | if ((start <= da) && (da < start + bytes)) { | 320 | if ((start <= da) && (da < start + bytes)) { |
309 | dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", | 321 | dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", |
310 | __func__, start, da, bytes); | 322 | __func__, start, da, bytes); |
311 | iotlb_load_cr(obj, &cr); | ||
312 | iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); | 323 | iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); |
313 | } | 324 | } |
314 | } | 325 | } |
@@ -379,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx); | |||
379 | static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num) | 390 | static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num) |
380 | { | 391 | { |
381 | int i; | 392 | int i; |
382 | struct iotlb_lock saved, l; | 393 | struct iotlb_lock saved; |
394 | struct cr_regs tmp; | ||
383 | struct cr_regs *p = crs; | 395 | struct cr_regs *p = crs; |
384 | 396 | ||
385 | clk_enable(obj->clk); | 397 | clk_enable(obj->clk); |
386 | |||
387 | iotlb_lock_get(obj, &saved); | 398 | iotlb_lock_get(obj, &saved); |
388 | memcpy(&l, &saved, sizeof(saved)); | ||
389 | 399 | ||
390 | for (i = 0; i < num; i++) { | 400 | for_each_iotlb_cr(obj, num, i, tmp) { |
391 | struct cr_regs tmp; | ||
392 | |||
393 | iotlb_lock_get(obj, &l); | ||
394 | l.vict = i; | ||
395 | iotlb_lock_set(obj, &l); | ||
396 | iotlb_read_cr(obj, &tmp); | ||
397 | if (!iotlb_cr_valid(&tmp)) | 401 | if (!iotlb_cr_valid(&tmp)) |
398 | continue; | 402 | continue; |
399 | |||
400 | *p++ = tmp; | 403 | *p++ = tmp; |
401 | } | 404 | } |
405 | |||
402 | iotlb_lock_set(obj, &saved); | 406 | iotlb_lock_set(obj, &saved); |
403 | clk_disable(obj->clk); | 407 | clk_disable(obj->clk); |
404 | 408 | ||