diff options
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/include/mach/iovmm.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/iovmm.c | 22 |
2 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/iovmm.h b/arch/arm/mach-tegra/include/mach/iovmm.h index 8f111605e065..e30d3dcf2859 100644 --- a/arch/arm/mach-tegra/include/mach/iovmm.h +++ b/arch/arm/mach-tegra/include/mach/iovmm.h @@ -166,6 +166,9 @@ void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm); /* called by clients to return an iovmm_area to the free pool for the domain */ void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm); +/* returns size of largest free iovm block */ +size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client); + /* called by client software to map the page-aligned I/O address vaddr to * a specific physical address pfn. I/O VMA should have been created with * a NULL tegra_iovmm_area_ops structure. */ diff --git a/arch/arm/mach-tegra/iovmm.c b/arch/arm/mach-tegra/iovmm.c index 1f9e49902188..1afdaf3b53cc 100644 --- a/arch/arm/mach-tegra/iovmm.c +++ b/arch/arm/mach-tegra/iovmm.c @@ -90,6 +90,28 @@ static tegra_iovmm_addr_t iovmm_align_down(struct tegra_iovmm_device *dev, #define iovmprint(fmt, arg...) snprintf(page+len, count-len, fmt, ## arg) +size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client) +{ + struct rb_node *n; + struct tegra_iovmm_block *b; + struct tegra_iovmm_domain *domain = client->domain; + + spin_lock(&domain->block_lock); + n = rb_first(&domain->all_blocks); + tegra_iovmm_addr_t max_free = 0; + while (n) { + b = rb_entry(n, struct tegra_iovmm_block, all_node); + n = rb_next(n); + if (test_bit(BK_free, &b->flags)) { + max_free = max_t(tegra_iovmm_addr_t, + max_free, iovmm_length(b)); + } + } + spin_unlock(&domain->block_lock); + return max_free; +} + + static void tegra_iovmm_block_stats(struct tegra_iovmm_domain *domain, unsigned int *num_blocks, unsigned int *num_free, tegra_iovmm_addr_t *total, tegra_iovmm_addr_t *total_free, |