Skip to content

Commit

Permalink
omap iommu: Introduce iteration macro for iotlb entry scan
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Hiroshi DOYU authored and Hiroshi DOYU committed May 14, 2010
1 parent be6d802 commit 37c2836
Showing 1 changed file with 31 additions and 27 deletions.
58 changes: 31 additions & 27 deletions arch/arm/plat-omap/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@

#include "iopgtable.h"

#define for_each_iotlb_cr(obj, n, __i, cr) \
for (__i = 0; \
(__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \
__i++)

/* accommodate the difference between omap1 and omap2/3 */
static const struct iommu_functions *arch_iommu;

Expand Down Expand Up @@ -211,14 +216,27 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
return arch_iommu->dump_cr(obj, cr, buf);
}

/* only used in iotlb iteration for-loop */
static struct cr_regs __iotlb_read_cr(struct iommu *obj, int n)
{
struct cr_regs cr;
struct iotlb_lock l;

iotlb_lock_get(obj, &l);
l.vict = n;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &cr);

return cr;
}

/**
* load_iotlb_entry - Set an iommu tlb entry
* @obj: target iommu
* @e: an iommu tlb entry info
**/
int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
{
int i;
int err = 0;
struct iotlb_lock l;
struct cr_regs *cr;
Expand All @@ -235,21 +253,20 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
goto out;
}
if (!e->prsvd) {
for (i = l.base; i < obj->nr_tlb_entries; i++) {
struct cr_regs tmp;
int i;
struct cr_regs tmp;

iotlb_lock_get(obj, &l);
l.vict = i;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &tmp);
for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp)
if (!iotlb_cr_valid(&tmp))
break;
}

if (i == obj->nr_tlb_entries) {
dev_dbg(obj->dev, "%s: full: no entry\n", __func__);
err = -EBUSY;
goto out;
}

iotlb_lock_get(obj, &l);
} else {
l.vict = l.base;
iotlb_lock_set(obj, &l);
Expand Down Expand Up @@ -285,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry);
**/
void flush_iotlb_page(struct iommu *obj, u32 da)
{
struct iotlb_lock l;
int i;
struct cr_regs cr;

clk_enable(obj->clk);

for (i = 0; i < obj->nr_tlb_entries; i++) {
struct cr_regs cr;
for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
u32 start;
size_t bytes;

iotlb_lock_get(obj, &l);
l.vict = i;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &cr);
if (!iotlb_cr_valid(&cr))
continue;

Expand All @@ -308,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da)
if ((start <= da) && (da < start + bytes)) {
dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
__func__, start, da, bytes);
iotlb_load_cr(obj, &cr);
iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
}
}
Expand Down Expand Up @@ -379,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx);
static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num)
{
int i;
struct iotlb_lock saved, l;
struct iotlb_lock saved;
struct cr_regs tmp;
struct cr_regs *p = crs;

clk_enable(obj->clk);

iotlb_lock_get(obj, &saved);
memcpy(&l, &saved, sizeof(saved));

for (i = 0; i < num; i++) {
struct cr_regs tmp;

iotlb_lock_get(obj, &l);
l.vict = i;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &tmp);
for_each_iotlb_cr(obj, num, i, tmp) {
if (!iotlb_cr_valid(&tmp))
continue;

*p++ = tmp;
}

iotlb_lock_set(obj, &saved);
clk_disable(obj->clk);

Expand Down

0 comments on commit 37c2836

Please sign in to comment.