summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2012-08-22 15:03:07 +0300
committerSimone Willett <swillett@nvidia.com>2012-08-23 14:45:51 -0700
commit255b6f0b8936112beed3dcd403b2a57a163aa215 (patch)
treedaace2a95d970540fb20dbe0579349fcbe944ad7 /drivers
parent13694b6bf1dc4572752e13d42f278aa9b624f043 (diff)
video: tegra: host: Clear intr list at intr_put
Process wait list when removing a waiter. This clears the interrupt once it is no longer needed. Bug 1031724 Change-Id: Ifb46672f70c8bbd6359d0a8aeaac0d718a5394b2 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/125230 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/chip_support.h1
-rw-r--r--drivers/video/tegra/host/host1x/host1x_channel.c5
-rw-r--r--drivers/video/tegra/host/host1x/host1x_intr.c11
-rw-r--r--drivers/video/tegra/host/nvhost_intr.c12
-rw-r--r--drivers/video/tegra/host/nvhost_intr.h2
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c2
6 files changed, 27 insertions, 6 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index f5d2811f143f..412ce8b65466 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -125,6 +125,7 @@ struct nvhost_intr_ops {
void (*set_syncpt_threshold)(
struct nvhost_intr *, u32 id, u32 thresh);
void (*enable_syncpt_intr)(struct nvhost_intr *, u32 id);
+ void (*disable_syncpt_intr)(struct nvhost_intr *, u32 id);
void (*disable_all_syncpt_intrs)(struct nvhost_intr *);
int (*request_host_general_irq)(struct nvhost_intr *);
void (*free_host_general_irq)(struct nvhost_intr *);
diff --git a/drivers/video/tegra/host/host1x/host1x_channel.c b/drivers/video/tegra/host/host1x/host1x_channel.c
index 3c074604b675..0274413ff698 100644
--- a/drivers/video/tegra/host/host1x/host1x_channel.c
+++ b/drivers/video/tegra/host/host1x/host1x_channel.c
@@ -470,7 +470,8 @@ static int host1x_channel_read_3d_reg(
wait_event(wq,
nvhost_syncpt_is_expired(&nvhost_get_host(channel->dev)->syncpt,
p->syncpt, syncval - 2));
- nvhost_intr_put_ref(&nvhost_get_host(channel->dev)->intr, ref);
+ nvhost_intr_put_ref(&nvhost_get_host(channel->dev)->intr, p->syncpt,
+ ref);
/* Read the register value from FIFO */
err = host1x_drain_read_fifo(channel, value, 1, &pending);
@@ -622,7 +623,7 @@ static int host1x_save_context(struct nvhost_channel *ch)
nvhost_syncpt_is_expired(&nvhost_get_host(ch->dev)->syncpt,
syncpt_id, syncpt_val));
- nvhost_intr_put_ref(&nvhost_get_host(ch->dev)->intr, ref);
+ nvhost_intr_put_ref(&nvhost_get_host(ch->dev)->intr, syncpt_id, ref);
nvhost_cdma_update(&ch->cdma);
diff --git a/drivers/video/tegra/host/host1x/host1x_intr.c b/drivers/video/tegra/host/host1x/host1x_intr.c
index 2afbcbfa6393..facb818a0c24 100644
--- a/drivers/video/tegra/host/host1x/host1x_intr.c
+++ b/drivers/video/tegra/host/host1x/host1x_intr.c
@@ -131,6 +131,16 @@ static void t20_intr_enable_syncpt_intr(struct nvhost_intr *intr, u32 id)
BIT_WORD(id) * REGISTER_STRIDE);
}
+static void t20_intr_disable_syncpt_intr(struct nvhost_intr *intr, u32 id)
+{
+ struct nvhost_master *dev = intr_to_dev(intr);
+ void __iomem *sync_regs = dev->sync_aperture;
+
+ writel(BIT_MASK(id), sync_regs +
+ host1x_sync_syncpt_thresh_int_disable_r() +
+ BIT_WORD(id) * REGISTER_STRIDE);
+}
+
static void t20_intr_disable_all_syncpt_intrs(struct nvhost_intr *intr)
{
struct nvhost_master *dev = intr_to_dev(intr);
@@ -276,6 +286,7 @@ static const struct nvhost_intr_ops host1x_intr_ops = {
.set_host_clocks_per_usec = t20_intr_set_host_clocks_per_usec,
.set_syncpt_threshold = t20_intr_set_syncpt_threshold,
.enable_syncpt_intr = t20_intr_enable_syncpt_intr,
+ .disable_syncpt_intr = t20_intr_disable_syncpt_intr,
.disable_all_syncpt_intrs = t20_intr_disable_all_syncpt_intrs,
.request_host_general_irq = t20_intr_request_host_general_irq,
.free_host_general_irq = t20_intr_free_host_general_irq,
diff --git a/drivers/video/tegra/host/nvhost_intr.c b/drivers/video/tegra/host/nvhost_intr.c
index 38a04f151e87..9788d32bd4a9 100644
--- a/drivers/video/tegra/host/nvhost_intr.c
+++ b/drivers/video/tegra/host/nvhost_intr.c
@@ -210,7 +210,9 @@ static int process_wait_list(struct nvhost_intr *intr,
remove_completed_waiters(&syncpt->wait_head, threshold, completed);
empty = list_empty(&syncpt->wait_head);
- if (!empty)
+ if (empty)
+ intr_op().disable_syncpt_intr(intr, syncpt->id);
+ else
reset_threshold_interrupt(intr, &syncpt->wait_head,
syncpt->id);
@@ -327,14 +329,20 @@ void *nvhost_intr_alloc_waiter()
GFP_KERNEL|__GFP_REPEAT);
}
-void nvhost_intr_put_ref(struct nvhost_intr *intr, void *ref)
+void nvhost_intr_put_ref(struct nvhost_intr *intr, u32 id, void *ref)
{
struct nvhost_waitlist *waiter = ref;
+ struct nvhost_intr_syncpt *syncpt;
+ struct nvhost_master *host = intr_to_dev(intr);
while (atomic_cmpxchg(&waiter->state,
WLS_PENDING, WLS_CANCELLED) == WLS_REMOVED)
schedule();
+ syncpt = intr->syncpt + id;
+ (void)process_wait_list(intr, syncpt,
+ nvhost_syncpt_update_min(&host->syncpt, id));
+
kref_put(&waiter->refcount, waiter_release);
}
diff --git a/drivers/video/tegra/host/nvhost_intr.h b/drivers/video/tegra/host/nvhost_intr.h
index cf0b6b9e8934..d4a6157eced1 100644
--- a/drivers/video/tegra/host/nvhost_intr.h
+++ b/drivers/video/tegra/host/nvhost_intr.h
@@ -104,7 +104,7 @@ void *nvhost_intr_alloc_waiter(void);
* You must call this if you passed non-NULL as ref.
* @ref the ref returned from nvhost_intr_add_action()
*/
-void nvhost_intr_put_ref(struct nvhost_intr *intr, void *ref);
+void nvhost_intr_put_ref(struct nvhost_intr *intr, u32 id, void *ref);
int nvhost_intr_init(struct nvhost_intr *intr, u32 irq_gen, u32 irq_sync);
void nvhost_intr_deinit(struct nvhost_intr *intr);
diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c
index 9fa7d0652c1f..d30028b0c7a4 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.c
+++ b/drivers/video/tegra/host/nvhost_syncpt.c
@@ -235,7 +235,7 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
check_count++;
}
}
- nvhost_intr_put_ref(&(syncpt_to_dev(sp)->intr), ref);
+ nvhost_intr_put_ref(&(syncpt_to_dev(sp)->intr), id, ref);
done:
nvhost_module_idle(syncpt_to_dev(sp)->dev);