• Brian Norris's avatar
    clk: divider: handle integer overflow when dividing large clock rates · 9556f9da
    Brian Norris authored
    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 b11d282d "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(3000000000, 1500000000) = (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: default avatarBrian Norris <computersforpeace@gmail.com>
    Reference: http://lkml.kernel.org/g/20150413201433.GQ32500@ld-irv-0074Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
    9556f9da
clk-divider.c 13.7 KB