From: Hosung Kim Date: Sun, 9 Apr 2017 11:06:05 +0000 (+0900) Subject: [COMMON] clocksource: exynos_mct: change H/W control sequence X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=42b9948eac0762125ec27a32226dbf2f21118360;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] clocksource: exynos_mct: change H/W control sequence This commit changes H/W control sequence of a majority in exynos_mct codes. Because changed codes are mass-produced already but mainline code is not so. Change-Id: I168e289b06eddf4a53df66c8c11a4df52d11fd4d Signed-off-by: Hosung Kim --- diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index d828795a612c..fcb850715c5d 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -357,26 +357,25 @@ static int exynos4_clockevent_init(void) static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); /* Clock event handling */ -static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt) +static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt, int force) { unsigned long tmp; - unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START; - unsigned long offset = mevt->base + MCT_L_TCON_OFFSET; - tmp = readl_relaxed(reg_base + offset); - if (tmp & mask) { - tmp &= ~mask; - exynos4_mct_write(tmp, offset); + /* clear MCT local interrupt */ + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); + + if (force || !clockevent_state_periodic(&mevt->evt)) { + tmp = readl_relaxed(reg_base + mevt->base + MCT_L_TCON_OFFSET); + tmp &= ~(MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START | MCT_L_TCON_INTERVAL_MODE); + exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); } } -static void exynos4_mct_tick_start(unsigned long cycles, +static void exynos4_mct_tick_start(unsigned long cycles, int periodic, struct mct_clock_event_device *mevt) { unsigned long tmp; - exynos4_mct_tick_stop(mevt); - tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */ /* update interrupt count buffer */ @@ -385,9 +384,11 @@ static void exynos4_mct_tick_start(unsigned long cycles, /* enable MCT tick interrupt */ exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET); - tmp = readl_relaxed(reg_base + mevt->base + MCT_L_TCON_OFFSET); - tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START | - MCT_L_TCON_INTERVAL_MODE; + tmp = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START; + + if (periodic || clockevent_state_periodic(&mevt->evt)) + tmp |= MCT_L_TCON_INTERVAL_MODE; + exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); } @@ -397,7 +398,7 @@ static int exynos4_tick_set_next_event(unsigned long cycles, struct mct_clock_event_device *mevt; mevt = container_of(evt, struct mct_clock_event_device, evt); - exynos4_mct_tick_start(cycles, mevt); + exynos4_mct_tick_start(cycles, 0, mevt); return 0; } @@ -406,7 +407,7 @@ static int set_state_shutdown(struct clock_event_device *evt) struct mct_clock_event_device *mevt; mevt = container_of(evt, struct mct_clock_event_device, evt); - exynos4_mct_tick_stop(mevt); + exynos4_mct_tick_stop(mevt, 1); return 0; } @@ -418,32 +419,17 @@ static int set_state_periodic(struct clock_event_device *evt) mevt = container_of(evt, struct mct_clock_event_device, evt); cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); - exynos4_mct_tick_stop(mevt); - exynos4_mct_tick_start(cycles_per_jiffy, mevt); + exynos4_mct_tick_stop(mevt, 1); + exynos4_mct_tick_start(cycles_per_jiffy, 1, mevt); return 0; } -static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) -{ - /* - * This is for supporting oneshot mode. - * Mct would generate interrupt periodically - * without explicit stopping. - */ - if (!clockevent_state_periodic(&mevt->evt)) - exynos4_mct_tick_stop(mevt); - - /* Clear the MCT tick interrupt */ - if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) - exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); -} - static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) { struct mct_clock_event_device *mevt = dev_id; struct clock_event_device *evt = &mevt->evt; - exynos4_mct_tick_clear(mevt); + exynos4_mct_tick_stop(mevt, 0); evt->event_handler(evt);