lkml.org 
[lkml]   [2019]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v4 03/21] x86/hpet: Calculate ticks-per-second in a separate function
    Date
    It is easier to compute the expiration times of an HPET timer by using
    its frequency (i.e., the number of times it ticks in a second) than its
    period, as given in the capabilities register.

    In addition to the HPET char driver, the HPET-based hardlockup detector
    will also need to know the timer's frequency. Thus, create a common
    function that both can use.

    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: Ashok Raj <ashok.raj@intel.com>
    Cc: Andi Kleen <andi.kleen@intel.com>
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: Clemens Ladisch <clemens@ladisch.de>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Philippe Ombredanne <pombredanne@nexb.com>
    Cc: Kate Stewart <kstewart@linuxfoundation.org>
    Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
    Cc: Stephane Eranian <eranian@google.com>
    Cc: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
    Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
    Cc: x86@kernel.org
    Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
    ---
    drivers/char/hpet.c | 31 ++++++++++++++++++++++++-------
    include/linux/hpet.h | 1 +
    2 files changed, 25 insertions(+), 7 deletions(-)

    diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
    index 3a1e6b3ccd10..747255f552a9 100644
    --- a/drivers/char/hpet.c
    +++ b/drivers/char/hpet.c
    @@ -836,6 +836,29 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
    return ret;
    }

    +u64 hpet_get_ticks_per_sec(u64 hpet_caps)
    +{
    + u64 ticks_per_sec, period;
    +
    + period = (hpet_caps & HPET_COUNTER_CLK_PERIOD_MASK) >>
    + HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
    +
    + /*
    + * The frequency is the reciprocal of the period. The period is given
    + * in femtoseconds per second. Thus, prepare a dividend to obtain the
    + * frequency in ticks per second.
    + */
    +
    + /* 10^15 femtoseconds per second */
    + ticks_per_sec = 1000000000000000ULL;
    + ticks_per_sec += period >> 1; /* round */
    +
    + /* The quotient is put in the dividend. We drop the remainder. */
    + do_div(ticks_per_sec, period);
    +
    + return ticks_per_sec;
    +}
    +
    int hpet_alloc(struct hpet_data *hdp)
    {
    u64 cap, mcfg;
    @@ -844,7 +867,6 @@ int hpet_alloc(struct hpet_data *hdp)
    struct hpets *hpetp;
    struct hpet __iomem *hpet;
    static struct hpets *last;
    - unsigned long period;
    unsigned long long temp;
    u32 remainder;

    @@ -894,12 +916,7 @@ int hpet_alloc(struct hpet_data *hdp)

    last = hpetp;

    - period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
    - HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
    - temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
    - temp += period >> 1; /* round */
    - do_div(temp, period);
    - hpetp->hp_tick_freq = temp; /* ticks per second */
    + hpetp->hp_tick_freq = hpet_get_ticks_per_sec(cap);

    printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
    hpetp->hp_which, hdp->hd_phys_address,
    diff --git a/include/linux/hpet.h b/include/linux/hpet.h
    index 8604564b985d..e7b36bcf4699 100644
    --- a/include/linux/hpet.h
    +++ b/include/linux/hpet.h
    @@ -107,5 +107,6 @@ static inline void hpet_reserve_timer(struct hpet_data *hd, int timer)
    }

    int hpet_alloc(struct hpet_data *);
    +u64 hpet_get_ticks_per_sec(u64 hpet_caps);

    #endif /* !__HPET__ */
    --
    2.17.1
    \
     
     \ /
      Last update: 2019-05-24 03:17    [W:4.143 / U:0.224 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site