| From 22bbd5d949dc7fdd72a4e78e767fa09d8e54b446 Mon Sep 17 00:00:00 2001 |
| From: Stephen Warren <swarren@nvidia.com> |
| Date: Fri, 4 Apr 2014 16:31:05 -0600 |
| Subject: gpu: host1x: handle the correct # of syncpt regs |
| |
| From: Stephen Warren <swarren@nvidia.com> |
| |
| commit 22bbd5d949dc7fdd72a4e78e767fa09d8e54b446 upstream. |
| |
| BIT_WORD() truncates rather than rounds, so the loops in |
| syncpt_thresh_isr() and _host1x_intr_disable_all_syncpt_intrs() use <= |
| rather than < in an attempt to process the correct number of registers |
| when rounding of the conversion of count of bits to count of words is |
| necessary. However, when rounding isn't necessary because the value is |
| already a multiple of the divisor (as is the case for all values of |
| nb_pts the code actually sees), this causes one too many registers to |
| be processed. |
| |
| Solve this by using and explicit DIV_ROUND_UP() call, rather than |
| BIT_WORD(), and comparing with < rather than <=. |
| |
| Fixes: 7ede0b0bf3e2 ("gpu: host1x: Add syncpoint wait and interrupts") |
| Signed-off-by: Stephen Warren <swarren@nvidia.com> |
| Acked-By: Terje Bergstrom <tbergstrom@nvidia.com> |
| Signed-off-by: Thierry Reding <treding@nvidia.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/host1x/hw/intr_hw.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/gpu/host1x/hw/intr_hw.c |
| +++ b/drivers/gpu/host1x/hw/intr_hw.c |
| @@ -48,7 +48,7 @@ static irqreturn_t syncpt_thresh_isr(int |
| unsigned long reg; |
| int i, id; |
| |
| - for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) { |
| + for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) { |
| reg = host1x_sync_readl(host, |
| HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i)); |
| for_each_set_bit(id, ®, BITS_PER_LONG) { |
| @@ -65,7 +65,7 @@ static void _host1x_intr_disable_all_syn |
| { |
| u32 i; |
| |
| - for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) { |
| + for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) { |
| host1x_sync_writel(host, 0xffffffffu, |
| HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i)); |
| host1x_sync_writel(host, 0xffffffffu, |