diff options
author | Jisheng Zhang <jszhang@marvell.com> | 2015-11-25 19:01:53 +0300 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2015-12-15 23:41:28 +0300 |
commit | 39d3611f2d8ff5dcba523c9081e6f5e51f066c86 (patch) | |
tree | 5c4d95695e85298df18776abb05774cc021a08a1 /drivers/clocksource/dw_apb_timer.c | |
parent | 9f4165dc4e9e6dd10627b7b4d4e09c09fc01410c (diff) | |
download | linux-39d3611f2d8ff5dcba523c9081e6f5e51f066c86.tar.xz |
clocksource/drivers/dw_apb_timer: Use {readl|writel}_relaxed in critical path
It's safe to use the relaxed version. From another side, the relaxed io
accessor macros are available on all architectures now, so we can use
the relaxed versions to get a trivial system performance improvement,
we measured time the following functions spent on Marvell BG4CT:
4096 rounds of __apbt_read_clocksource() call:
before the patch: 1263240ns on average
after the patch: 1250080ns on average
improved by 1%
4096 rounds of apbt_eoi() call:
before the patch: 1290960ns on average
after the patch: 1248240ns on average
4096 rounds of apbt_next_event() call:
before the patch: 3333660ns on average
after the patch: 1322040ns on average
improved by 60%!
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/clocksource/dw_apb_timer.c')
-rw-r--r-- | drivers/clocksource/dw_apb_timer.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index 3a6d9dbe315d..7f95b5347a9a 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -60,6 +60,17 @@ static void apbt_writel(struct dw_apb_timer *timer, u32 val, writel(val, timer->base + offs); } +static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs) +{ + return readl_relaxed(timer->base + offs); +} + +static inline void apbt_writel_relaxed(struct dw_apb_timer *timer, u32 val, + unsigned long offs) +{ + writel_relaxed(val, timer->base + offs); +} + static void apbt_disable_int(struct dw_apb_timer *timer) { u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL); @@ -81,7 +92,7 @@ void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced) static void apbt_eoi(struct dw_apb_timer *timer) { - apbt_readl(timer, APBTMR_N_EOI); + apbt_readl_relaxed(timer, APBTMR_N_EOI); } static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) @@ -200,13 +211,13 @@ static int apbt_next_event(unsigned long delta, struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); /* Disable timer */ - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); + ctrl = apbt_readl_relaxed(&dw_ced->timer, APBTMR_N_CONTROL); ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); + apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); /* write new count */ - apbt_writel(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); + apbt_writel_relaxed(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); + apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); return 0; } @@ -342,7 +353,8 @@ static cycle_t __apbt_read_clocksource(struct clocksource *cs) struct dw_apb_clocksource *dw_cs = clocksource_to_dw_apb_clocksource(cs); - current_count = apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); + current_count = apbt_readl_relaxed(&dw_cs->timer, + APBTMR_N_CURRENT_VALUE); return (cycle_t)~current_count; } |