diff options
author | Kaz Fukuoka <kfukuoka@nvidia.com> | 2011-05-25 18:21:32 -0700 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2011-05-31 18:17:49 -0700 |
commit | d2182d4d60fac6df3626656ba9f2870eb73d7e4b (patch) | |
tree | 0f67a2948f41354f3c6f5803f15c218a7923dab9 | |
parent | ed146c6249f762419e59c5d6c15be709f9adbe67 (diff) |
media: tegra: avp: Clear interrupt registers when AVP starts
There was no code to clear interrupt registers for AVP. First run
of AVP was OK because those registers start from reset value.
But because those registers were not cleared, when the second
time AVP was started, some interrupts were enabled too early.
That caused interrupts coming before handlers were ready.
This change also removes the workaroud for the bug.
bug 827353
bug 826234
Change-Id: I51546400f0bace67dfcdb23f667c051c060d3983
Reviewed-on: http://git-master/r/33083
Reviewed-by: Niket Sirsi <nsirsi@nvidia.com>
Tested-by: Niket Sirsi <nsirsi@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/include/mach/legacy_irq.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/legacy_irq.c | 11 | ||||
-rw-r--r-- | drivers/media/video/tegra/avp/avp.c | 6 |
3 files changed, 15 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/include/mach/legacy_irq.h b/arch/arm/mach-tegra/include/mach/legacy_irq.h index 3a2bfab9e54f..82d1a226fa1c 100644 --- a/arch/arm/mach-tegra/include/mach/legacy_irq.h +++ b/arch/arm/mach-tegra/include/mach/legacy_irq.h @@ -31,6 +31,7 @@ int tegra_legacy_irq_set_wake(int irq, int enable); void tegra_legacy_irq_set_lp1_wake_mask(void); void tegra_legacy_irq_restore_mask(void); void tegra_init_legacy_irq(void); +void tegra_init_legacy_irq_cop(void); void tegra_legacy_irq_suspend(void); void tegra_legacy_irq_resume(void); #endif diff --git a/arch/arm/mach-tegra/legacy_irq.c b/arch/arm/mach-tegra/legacy_irq.c index ece56370e56c..e05a4aadd867 100644 --- a/arch/arm/mach-tegra/legacy_irq.c +++ b/arch/arm/mach-tegra/legacy_irq.c @@ -177,6 +177,17 @@ void tegra_init_legacy_irq(void) } } +void tegra_init_legacy_irq_cop(void) +{ + int i; + + for (i = 0; i < NUM_ICTLRS; i++) { + void __iomem *ictlr = ictlr_reg_base[i]; + writel(~0, ictlr + ICTLR_COP_IER_CLR); + writel(0, ictlr + ICTLR_COP_IEP_CLASS); + } +} + #ifdef CONFIG_PM static u32 cop_ier[NUM_ICTLRS]; static u32 cpu_ier[NUM_ICTLRS]; diff --git a/drivers/media/video/tegra/avp/avp.c b/drivers/media/video/tegra/avp/avp.c index 34f7ccdfcac4..759c89ae3d9d 100644 --- a/drivers/media/video/tegra/avp/avp.c +++ b/drivers/media/video/tegra/avp/avp.c @@ -43,6 +43,7 @@ #include <mach/io.h> #include <mach/iomap.h> #include <mach/nvmap.h> +#include <mach/legacy_irq.h> #include "../../../../video/tegra/nvmap/nvmap.h" @@ -1015,6 +1016,8 @@ static int avp_init(struct tegra_avp_info *avp) wmb(); release_firmware(avp_fw); + tegra_init_legacy_irq_cop(); + ret = avp_reset(avp, avp->reset_addr); if (ret) { pr_err("%s: cannot reset the AVP.. aborting..\n", __func__); @@ -1412,9 +1415,6 @@ int tegra_avp_release(struct tegra_avp_info *avp) { int ret = 0; - pr_info("%s: WORKAROUND: ignoring AVP release\n", __func__); - return 0; - pr_debug("%s: close\n", __func__); mutex_lock(&avp->open_lock); if (!avp->refcount) { |