android_kernel_motorola_sm6375/drivers/clocksource
Repository files (latest commit first)
Filename Latest commit message Latest commit date
David Woodhouse 9f89d4ad21 clockevents/drivers/i8253: Fix stop sequence for timer 0
commit 531b2ca0a940ac9db03f246c8b77c4201de72b00 upstream.

According to the data sheet, writing the MODE register should stop the
counter (and thus the interrupts). This appears to work on real hardware,
at least modern Intel and AMD systems. It should also work on Hyper-V.

However, on some buggy virtual machines the mode change doesn't have any
effect until the counter is subsequently loaded (or perhaps when the IRQ
next fires).

So, set MODE 0 and then load the counter, to ensure that those buggy VMs
do the right thing and the interrupts stop. And then write MODE 0 *again*
to stop the counter on compliant implementations too.

Apparently, Hyper-V keeps firing the IRQ *repeatedly* even in mode zero
when it should only happen once, but the second MODE write stops that too.

Userspace test program (mostly written by tglx):
=====
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/io.h>

static __always_inline void __out##bwl(type value, uint16_t port)	\
{									\
	asm volatile("out" #bwl " %" #bw "0, %w1"			\
		     : : "a"(value), "Nd"(port));			\
}									\
									\
static __always_inline type __in##bwl(uint16_t port)			\
{									\
	type value;							\
	asm volatile("in" #bwl " %w1, %" #bw "0"			\
		     : "=a"(value) : "Nd"(port));			\
	return value;							\
}

BUILDIO(b, b, uint8_t)

 #define inb __inb
 #define outb __outb

 #define PIT_MODE	0x43
 #define PIT_CH0	0x40
 #define PIT_CH2	0x42

static int is8254;

static void dump_pit(void)
{
	if (is8254) {
		// Latch and output counter and status
		outb(0xC2, PIT_MODE);
		printf("%02x %02x %02x\n", inb(PIT_CH0), inb(PIT_CH0), inb(PIT_CH0));
	} else {
		// Latch and output counter
		outb(0x0, PIT_MODE);
		printf("%02x %02x\n", inb(PIT_CH0), inb(PIT_CH0));
	}
}

int main(int argc, char* argv[])
{
	int nr_counts = 2;

	if (argc > 1)
		nr_counts = atoi(argv[1]);

	if (argc > 2)
		is8254 = 1;

	if (ioperm(0x40, 4, 1) != 0)
		return 1;

	dump_pit();

	printf("Set oneshot\n");
	outb(0x38, PIT_MODE);
	outb(0x00, PIT_CH0);
	outb(0x0F, PIT_CH0);

	dump_pit();
	usleep(1000);
	dump_pit();

	printf("Set periodic\n");
	outb(0x34, PIT_MODE);
	outb(0x00, PIT_CH0);
	outb(0x0F, PIT_CH0);

	dump_pit();
	usleep(1000);
	dump_pit();
	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	printf("Set stop (%d counter writes)\n", nr_counts);
	outb(0x30, PIT_MODE);
	while (nr_counts--)
		outb(0xFF, PIT_CH0);

	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	printf("Set MODE 0\n");
	outb(0x30, PIT_MODE);

	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	return 0;
}
=====

Suggested-by: Sean Christopherson <seanjc@google.com>
Co-developed-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Michael Kelley <mhkelley@outlook.com>
Link: https://lore.kernel.org/all/20240802135555.564941-2-dwmw2@infradead.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-04-10 14:29:34 +02:00
..
acpi_pm.c clocksource: acpi_pm: fix return value of __setup handler 2022-04-15 14:18:05 +02:00
arc_timer.c Merge branch 'timers/vdso' into timers/core 2019-07-03 10:50:21 +02:00
arm_arch_timer.c clocksource/arm_arch_timer: Improve Allwinner A64 timer workaround 2021-07-19 08:53:15 +02:00
arm_global_timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
armv7m_systick.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 194 2019-05-30 11:29:22 -07:00
asm9260_timer.c clocksource/drivers/asm9260: Add a check for of_clk_get 2020-01-04 19:17:07 +01:00
bcm2835_timer.c clocksource/drivers/bcm2835_timer: Fix memory leak of timer 2020-02-24 08:36:28 +01:00
bcm_kona_timer.c
clksrc-dbx500-prcmu.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 197 2019-05-30 11:29:22 -07:00
clksrc_st_lpc.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
clps711x-timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
dummy_timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
dw_apb_timer.c clocksource: dw_apb_timer: Make CPU-affiliation being optional 2020-06-22 09:30:55 +02:00
dw_apb_timer_of.c clocksource: dw_apb_timer_of: Fix missing clockevent timers 2020-06-22 09:30:55 +02:00
em_sti.c clocksource: Remove dev_err() usage after platform_get_irq() 2019-08-27 00:31:39 +02:00
exynos_mct.c Merge branch 'timers/vdso' into timers/core 2019-07-03 10:50:21 +02:00
h8300_timer8.c clocksource/drivers/h8300_timer8: Fix wrong return value in h8300_8timer_init() 2020-10-01 13:18:16 +02:00
h8300_timer16.c
h8300_tpu.c
hyperv_timer.c clocksource: hyper-v: unexport __init-annotated hv_init_clocksource() 2022-06-22 14:11:21 +02:00
i8253.c clockevents/drivers/i8253: Fix stop sequence for timer 0 2025-04-10 14:29:34 +02:00
ingenic-timer.c clocksource: Add a new timer-ingenic driver 2019-08-08 15:30:08 -07:00
jcore-pit.c
Kconfig clocksource/drivers/timer-ti-dm: Select TIMER_OF 2021-11-17 09:48:39 +01:00
Makefile clocksource: Add a new timer-ingenic driver 2019-08-08 15:30:08 -07:00
mips-gic-timer.c
mmio.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
mps2-timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
mxs_timer.c clocksource/drivers/mxs_timer: Add missing semicolon when DEBUG is defined 2021-03-04 10:26:29 +01:00
nomadik-mtu.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
numachip.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
renesas-ostm.c clocksource/drivers/renesas-ostm: Use DIV_ROUND_CLOSEST() helper 2019-08-27 00:31:39 +02:00
samsung_pwm_timer.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
scx200_hrt.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
sh_cmt.c clocksource/drivers/sh_cmt: Address race condition for clock events 2024-08-19 05:33:46 +02:00
sh_mtu2.c clocksource/drivers/sh_mtu2: Do not loop using platform_get_irq_by_name() 2019-10-18 07:55:16 +02:00
sh_tmu.c clocksource: Remove dev_err() usage after platform_get_irq() 2019-08-27 00:31:39 +02:00
timer-armada-370-xp.c
timer-atcpit100.c
timer-atlas7.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 4 2019-05-21 11:28:40 +02:00
timer-atmel-pit.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
timer-atmel-st.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
timer-atmel-tcb.c clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 hardware 2023-11-28 16:50:13 +00:00
timer-cadence-ttc.c clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe 2023-07-27 08:37:05 +02:00
timer-cs5535.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 206 2019-05-30 11:29:53 -07:00
timer-davinci.c clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when init fails 2023-05-17 11:35:53 +02:00
timer-digicolor.c
timer-efm32.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
timer-fsl-ftm.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
timer-fttmr010.c
timer-gx6605s.c clocksource/drivers/timer-gx6605s: Fixup counter reload 2020-10-07 08:01:25 +02:00
timer-imx-gpt.c clocksource/drivers/timer-imx-gpt: Fix potential memory leak 2023-11-28 16:50:13 +00:00
timer-imx-sysctr.c clocksource/drivers/imx-sysctr: Add internal clock divider handle 2019-08-27 00:31:39 +02:00
timer-imx-tpm.c clocksource/drivers/imx-tpm: Fix next event not taking effect sometime 2024-09-12 11:03:56 +02:00
timer-integrator-ap.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
timer-ixp4xx.c clocksource/drivers/ixp4xx: remove EXPORT_SYMBOL_GPL from ixp4xx_timer_setup() 2022-07-07 17:36:53 +02:00
timer-keystone.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
timer-lpc32xx.c
timer-mediatek.c clocksource/drivers/mediatek: Fix error handling 2019-10-16 17:04:50 +02:00
timer-meson6.c clocksource/drivers/timer-meson6: Update with SPDX Licence identifier 2019-06-25 19:49:18 +02:00
timer-milbeaut.c
timer-mp-csky.c
timer-npcm7xx.c clocksource/drivers/npcm: Fix GENMASK and timer operation 2019-08-27 00:31:39 +02:00
timer-nps.c
timer-of.c clocksource/drivers/timer-of: Remove percpu irq related code 2024-09-12 11:03:56 +02:00
timer-of.h clocksource/drivers/timer-of: Remove percpu irq related code 2024-09-12 11:03:56 +02:00
timer-orion.c clocksource/drivers/orion: Add missing clk_disable_unprepare() on error path 2020-12-30 11:51:17 +01:00
timer-owl.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
timer-oxnas-rps.c clocksource/drivers/oxnas-rps: Fix irq_of_parse_and_map() return value 2022-06-14 18:11:54 +02:00
timer-pistachio.c
timer-prima2.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 4 2019-05-21 11:28:40 +02:00
timer-probe.c clocksource/drivers: Do not warn on probe defer 2019-08-27 00:31:39 +02:00
timer-pxa.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
timer-qcom.c clocksource/drivers/qcom: Add missing iounmap() on errors in msm_dt_timer_init() 2024-11-08 16:20:28 +01:00
timer-rda.c
timer-riscv.c Revert "clocksource/drivers/riscv: Events are stopped during CPU suspend" 2022-12-08 11:23:06 +01:00
timer-rockchip.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
timer-sp.h
timer-sp804.c clocksource/drivers/sp804: Avoid error on multiple instances 2022-06-14 18:12:00 +02:00
timer-sprd.c
timer-stm32.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 194 2019-05-30 11:29:22 -07:00
timer-sun4i.c clocksource: sun4i: Add missing compatibles 2019-08-27 00:31:39 +02:00
timer-sun5i.c
timer-tango-xtal.c
timer-tegra.c clocksource/drivers/tegra: Set up maximum-ticks limit properly 2019-06-25 19:49:18 +02:00
timer-ti-32k.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 341 2019-06-05 17:37:07 +02:00
timer-ti-dm.c clocksource/drivers/timer-ti-dm: Change to new style declaration 2019-05-24 15:51:30 +02:00
timer-u300.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 194 2019-05-30 11:29:22 -07:00
timer-versatile.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
timer-vf-pit.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
timer-vt8500.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
timer-zevio.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00