Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clocksource/drivers/kona: Fix get_counter() error handling

I could not figure out why, but GCC cannot prove that the
kona_timer_init() function always initializes its two outputs,
and we get a warning for the use of the 'lsw' variable later,
which is obviously correct.

drivers/clocksource/bcm_kona_timer.c: In function 'kona_timer_init':
drivers/clocksource/bcm_kona_timer.c:119:13: error: 'lsw' may be used uninitialized in this function [-Werror=maybe-uninitialized]

Slightly reordering the loop makes the warning disappear, after
it becomes more obvious to the compiler that the loop is
always entered on the first iteration.

As pointed out by Ray Jui, there is a related problem in the
way we deal with the loop running into the limit, as we just
keep going there with an invalid counter data, so instead we
now propagate a -ETIMEDOUT result to the caller.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Ray Jui <ray.jui@broadcom.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: bcm-kernel-feedback-list@broadcom.com
Link: http://lkml.kernel.org/r/1471429296-9053-2-git-send-email-daniel.lezcano@linaro.org
Link: https://patchwork.kernel.org/patch/9174261/
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Arnd Bergmann and committed by
Ingo Molnar
16c8eba0 0e62fd83

+10 -6
+10 -6
drivers/clocksource/bcm_kona_timer.c
··· 66 66 67 67 } 68 68 69 - static void 69 + static int 70 70 kona_timer_get_counter(void __iomem *timer_base, uint32_t *msw, uint32_t *lsw) 71 71 { 72 - int loop_limit = 4; 72 + int loop_limit = 3; 73 73 74 74 /* 75 75 * Read 64-bit free running counter ··· 83 83 * if new hi-word is equal to previously read hi-word then stop. 84 84 */ 85 85 86 - while (--loop_limit) { 86 + do { 87 87 *msw = readl(timer_base + KONA_GPTIMER_STCHI_OFFSET); 88 88 *lsw = readl(timer_base + KONA_GPTIMER_STCLO_OFFSET); 89 89 if (*msw == readl(timer_base + KONA_GPTIMER_STCHI_OFFSET)) 90 90 break; 91 - } 91 + } while (--loop_limit); 92 92 if (!loop_limit) { 93 93 pr_err("bcm_kona_timer: getting counter failed.\n"); 94 94 pr_err(" Timer will be impacted\n"); 95 + return -ETIMEDOUT; 95 96 } 96 97 97 - return; 98 + return 0; 98 99 } 99 100 100 101 static int kona_timer_set_next_event(unsigned long clc, ··· 113 112 114 113 uint32_t lsw, msw; 115 114 uint32_t reg; 115 + int ret; 116 116 117 - kona_timer_get_counter(timers.tmr_regs, &msw, &lsw); 117 + ret = kona_timer_get_counter(timers.tmr_regs, &msw, &lsw); 118 + if (ret) 119 + return ret; 118 120 119 121 /* Load the "next" event tick value */ 120 122 writel(lsw + clc, timers.tmr_regs + KONA_GPTIMER_STCM0_OFFSET);