summaryrefslogtreecommitdiff
path: root/drivers/media/video/tegra/nvavp/nvavp_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tegra/nvavp/nvavp_dev.c')
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c48
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c
index 4627c514622a..012f50b7a5f4 100644
--- a/drivers/media/video/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c
@@ -40,9 +40,8 @@
#include <mach/io.h>
#include <mach/iomap.h>
#include <mach/legacy_irq.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
-#include "../../../../video/tegra/nvmap/nvmap.h"
#include "../../../../video/tegra/host/host1x/host1x_syncpt.h"
#include "../../../../video/tegra/host/dev.h"
#include "../../../../video/tegra/host/nvhost_acm.h"
@@ -118,6 +117,7 @@ struct nvavp_info {
struct nvhost_device *nvhost_dev;
struct miscdevice misc_dev;
+ atomic_t clock_stay_on_refcount;
};
struct nvavp_clientctx {
@@ -127,7 +127,7 @@ struct nvavp_clientctx {
struct nvmap_handle_ref *gather_mem;
int num_relocs;
struct nvavp_info *nvavp;
- u32 clk_reqs;
+ int clock_stay_on;
};
static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
@@ -176,7 +176,8 @@ static void nvavp_clks_disable(struct nvavp_info *nvavp)
static u32 nvavp_check_idle(struct nvavp_info *nvavp)
{
struct nv_e276_control *control = nvavp->os_control;
- return (control->put == control->get) ? 1 : 0;
+ return ((control->put == control->get)
+ && (!atomic_read(&nvavp->clock_stay_on_refcount))) ? 1 : 0;
}
static void clock_disable_handler(struct work_struct *work)
@@ -1061,15 +1062,16 @@ static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
return -EINVAL;
}
- mutex_lock(&nvavp->open_lock);
- if (clock.state) {
- if (clientctx->clk_reqs++ == 0)
- nvavp_clks_enable(nvavp);
- } else {
- if (--clientctx->clk_reqs == 0)
- nvavp_clks_disable(nvavp);
- }
- mutex_unlock(&nvavp->open_lock);
+ if (clientctx->clock_stay_on == clock.state)
+ return 0;
+
+ clientctx->clock_stay_on = clock.state;
+
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_inc(&nvavp->clock_stay_on_refcount);
+ else if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_DISABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
+
return 0;
}
@@ -1098,6 +1100,7 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp)
clientctx->nvmap = nvavp->nvmap;
clientctx->nvavp = nvavp;
+ clientctx->clock_stay_on = NVAVP_CLOCK_STAY_ON_DISABLED;
filp->private_data = clientctx;
@@ -1125,10 +1128,8 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp)
goto out;
}
- /* if this client had any requests, drop our clk ref */
- if (clientctx->clk_reqs)
- nvavp_clks_disable(nvavp);
-
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
if (nvavp->refcount > 0)
nvavp->refcount--;
if (!nvavp->refcount)
@@ -1187,7 +1188,8 @@ static const struct file_operations tegra_nvavp_fops = {
.unlocked_ioctl = tegra_nvavp_ioctl,
};
-static int tegra_nvavp_probe(struct nvhost_device *ndev)
+static int tegra_nvavp_probe(struct nvhost_device *ndev,
+ struct nvhost_device_id *id_table)
{
struct nvavp_info *nvavp;
int irq;
@@ -1234,17 +1236,7 @@ static int tegra_nvavp_probe(struct nvhost_device *ndev)
switch (heap_mask) {
case NVMAP_HEAP_IOVMM:
-#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
- iovmm_addr = 0xeff00000;
-#else
iovmm_addr = 0x0ff00000;
-#endif
-
- /* Tegra3 A01 has different SMMU address */
- if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3
- && tegra_get_revision() == TEGRA_REVISION_A01) {
- iovmm_addr = 0xeff00000;
- }
nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M,
L1_CACHE_BYTES,