clk: divider: handle integer overflow when dividing large clock rates
authorBrian Norris <computersforpeace@gmail.com>
Mon, 13 Apr 2015 23:03:21 +0000 (16:03 -0700)
committerStephen Boyd <sboyd@codeaurora.org>
Wed, 16 Sep 2015 22:22:33 +0000 (15:22 -0700)
commit9556f9dad8f57602159825ad19f7a8017eed2089
treef31c8e8b1802e865663df5427088f108fc61b41f
parent051ace1020d44ca7a1eb813ab35b7e769a622aa8
clk: divider: handle integer overflow when dividing large clock rates

On 32-bit architectures, 'unsigned long' (the type used to hold clock
rates, in Hz) is often only 32 bits wide. DIV_ROUND_UP() (as used in,
e.g., commit b11d282dbea2 "clk: divider: fix rate calculation for
fractional rates") can yield an integer overflow on clock rates that are
not (by themselves) too large to fit in 32 bits, because it performs
addition before the division. See for example:

  DIV_ROUND_UP(30000000001500000000) = (3.0G + 1.5G - 1) / 1.5G
                                       = OVERFLOW / 1.5G

This patch fixes such cases by always promoting the dividend to 64-bits
(unsigned long long) before doing the division. While this patch does
not resolve the issue with large clock rates across the common clock
framework nor address the problems with doing full 64-bit arithmetic on
a 32-bit architecture, it does fix some issues seen when using clock
dividers on a 3GHz reference clock to produce a 1.5GHz CPU clock for an
ARMv7 Brahma B15 SoC.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reference: http://lkml.kernel.org/g/20150413201433.GQ32500@ld-irv-0074
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/clk-divider.c