Commit 37c2836c authored by Hiroshi DOYU's avatar Hiroshi DOYU

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: default avatarHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Tested-by: default avatarHari Kanigeri <h-kanigeri2@ti.com>
parent be6d8026
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
#include "iopgtable.h" #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 */ /* accommodate the difference between omap1 and omap2/3 */
static const struct iommu_functions *arch_iommu; static const struct iommu_functions *arch_iommu;
...@@ -211,6 +216,20 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, ...@@ -211,6 +216,20 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
return arch_iommu->dump_cr(obj, cr, buf); 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 * load_iotlb_entry - Set an iommu tlb entry
* @obj: target iommu * @obj: target iommu
...@@ -218,7 +237,6 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, ...@@ -218,7 +237,6 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
**/ **/
int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
{ {
int i;
int err = 0; int err = 0;
struct iotlb_lock l; struct iotlb_lock l;
struct cr_regs *cr; struct cr_regs *cr;
...@@ -235,21 +253,20 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) ...@@ -235,21 +253,20 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
goto out; goto out;
} }
if (!e->prsvd) { if (!e->prsvd) {
for (i = l.base; i < obj->nr_tlb_entries; i++) { int i;
struct cr_regs tmp; struct cr_regs tmp;
iotlb_lock_get(obj, &l); for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp)
l.vict = i;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &tmp);
if (!iotlb_cr_valid(&tmp)) if (!iotlb_cr_valid(&tmp))
break; break;
}
if (i == obj->nr_tlb_entries) { if (i == obj->nr_tlb_entries) {
dev_dbg(obj->dev, "%s: full: no entry\n", __func__); dev_dbg(obj->dev, "%s: full: no entry\n", __func__);
err = -EBUSY; err = -EBUSY;
goto out; goto out;
} }
iotlb_lock_get(obj, &l);
} else { } else {
l.vict = l.base; l.vict = l.base;
iotlb_lock_set(obj, &l); iotlb_lock_set(obj, &l);
...@@ -285,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry); ...@@ -285,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry);
**/ **/
void flush_iotlb_page(struct iommu *obj, u32 da) void flush_iotlb_page(struct iommu *obj, u32 da)
{ {
struct iotlb_lock l;
int i; int i;
struct cr_regs cr;
clk_enable(obj->clk); clk_enable(obj->clk);
for (i = 0; i < obj->nr_tlb_entries; i++) { for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
struct cr_regs cr;
u32 start; u32 start;
size_t bytes; 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)) if (!iotlb_cr_valid(&cr))
continue; continue;
...@@ -308,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da) ...@@ -308,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da)
if ((start <= da) && (da < start + bytes)) { if ((start <= da) && (da < start + bytes)) {
dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
__func__, start, da, bytes); __func__, start, da, bytes);
iotlb_load_cr(obj, &cr);
iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
} }
} }
...@@ -379,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx); ...@@ -379,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx);
static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num) static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num)
{ {
int i; int i;
struct iotlb_lock saved, l; struct iotlb_lock saved;
struct cr_regs tmp;
struct cr_regs *p = crs; struct cr_regs *p = crs;
clk_enable(obj->clk); clk_enable(obj->clk);
iotlb_lock_get(obj, &saved); iotlb_lock_get(obj, &saved);
memcpy(&l, &saved, sizeof(saved));
for (i = 0; i < num; i++) { for_each_iotlb_cr(obj, num, i, tmp) {
struct cr_regs tmp;
iotlb_lock_get(obj, &l);
l.vict = i;
iotlb_lock_set(obj, &l);
iotlb_read_cr(obj, &tmp);
if (!iotlb_cr_valid(&tmp)) if (!iotlb_cr_valid(&tmp))
continue; continue;
*p++ = tmp; *p++ = tmp;
} }
iotlb_lock_set(obj, &saved); iotlb_lock_set(obj, &saved);
clk_disable(obj->clk); clk_disable(obj->clk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment