xref: /linux/kernel/irq/refcount_interrupt_test.c (revision dfa35434d7f20142fedd7120277b1044a0a2bb64)
1*07a88e2bSLyude Paul // SPDX-License-Identifier: GPL-2.0
2*07a88e2bSLyude Paul /*
3*07a88e2bSLyude Paul  * KUnit test for refcounted interrupt enable/disables.
4*07a88e2bSLyude Paul  */
5*07a88e2bSLyude Paul 
6*07a88e2bSLyude Paul #include <kunit/test.h>
7*07a88e2bSLyude Paul #include <linux/interrupt_rc.h>
8*07a88e2bSLyude Paul 
9*07a88e2bSLyude Paul #define TEST_IRQ_ON() KUNIT_EXPECT_FALSE(test, irqs_disabled())
10*07a88e2bSLyude Paul #define TEST_IRQ_OFF() KUNIT_EXPECT_TRUE(test, irqs_disabled())
11*07a88e2bSLyude Paul 
12*07a88e2bSLyude Paul /* ===== Test cases ===== */
13*07a88e2bSLyude Paul static void test_single_irq_change(struct kunit *test)
14*07a88e2bSLyude Paul {
15*07a88e2bSLyude Paul 	local_interrupt_disable();
16*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
17*07a88e2bSLyude Paul 	local_interrupt_enable();
18*07a88e2bSLyude Paul }
19*07a88e2bSLyude Paul 
20*07a88e2bSLyude Paul static void test_nested_irq_change(struct kunit *test)
21*07a88e2bSLyude Paul {
22*07a88e2bSLyude Paul 	local_interrupt_disable();
23*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
24*07a88e2bSLyude Paul 	local_interrupt_disable();
25*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
26*07a88e2bSLyude Paul 	local_interrupt_disable();
27*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
28*07a88e2bSLyude Paul 
29*07a88e2bSLyude Paul 	local_interrupt_enable();
30*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
31*07a88e2bSLyude Paul 	local_interrupt_enable();
32*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
33*07a88e2bSLyude Paul 	local_interrupt_enable();
34*07a88e2bSLyude Paul 	TEST_IRQ_ON();
35*07a88e2bSLyude Paul }
36*07a88e2bSLyude Paul 
37*07a88e2bSLyude Paul static void test_multiple_irq_change(struct kunit *test)
38*07a88e2bSLyude Paul {
39*07a88e2bSLyude Paul 	local_interrupt_disable();
40*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
41*07a88e2bSLyude Paul 	local_interrupt_disable();
42*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
43*07a88e2bSLyude Paul 
44*07a88e2bSLyude Paul 	local_interrupt_enable();
45*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
46*07a88e2bSLyude Paul 	local_interrupt_enable();
47*07a88e2bSLyude Paul 	TEST_IRQ_ON();
48*07a88e2bSLyude Paul 
49*07a88e2bSLyude Paul 	local_interrupt_disable();
50*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
51*07a88e2bSLyude Paul 	local_interrupt_enable();
52*07a88e2bSLyude Paul 	TEST_IRQ_ON();
53*07a88e2bSLyude Paul }
54*07a88e2bSLyude Paul 
55*07a88e2bSLyude Paul static void test_irq_save(struct kunit *test)
56*07a88e2bSLyude Paul {
57*07a88e2bSLyude Paul 	unsigned long flags;
58*07a88e2bSLyude Paul 
59*07a88e2bSLyude Paul 	local_irq_save(flags);
60*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
61*07a88e2bSLyude Paul 	local_interrupt_disable();
62*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
63*07a88e2bSLyude Paul 	local_interrupt_enable();
64*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
65*07a88e2bSLyude Paul 	local_irq_restore(flags);
66*07a88e2bSLyude Paul 	TEST_IRQ_ON();
67*07a88e2bSLyude Paul 
68*07a88e2bSLyude Paul 	local_interrupt_disable();
69*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
70*07a88e2bSLyude Paul 	local_irq_save(flags);
71*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
72*07a88e2bSLyude Paul 	local_irq_restore(flags);
73*07a88e2bSLyude Paul 	TEST_IRQ_OFF();
74*07a88e2bSLyude Paul 	local_interrupt_enable();
75*07a88e2bSLyude Paul 	TEST_IRQ_ON();
76*07a88e2bSLyude Paul }
77*07a88e2bSLyude Paul 
78*07a88e2bSLyude Paul static struct kunit_case test_cases[] = {
79*07a88e2bSLyude Paul 	KUNIT_CASE(test_single_irq_change),
80*07a88e2bSLyude Paul 	KUNIT_CASE(test_nested_irq_change),
81*07a88e2bSLyude Paul 	KUNIT_CASE(test_multiple_irq_change),
82*07a88e2bSLyude Paul 	KUNIT_CASE(test_irq_save),
83*07a88e2bSLyude Paul 	{},
84*07a88e2bSLyude Paul };
85*07a88e2bSLyude Paul 
86*07a88e2bSLyude Paul /* init and exit are the same. */
87*07a88e2bSLyude Paul static int test_init(struct kunit *test)
88*07a88e2bSLyude Paul {
89*07a88e2bSLyude Paul 	TEST_IRQ_ON();
90*07a88e2bSLyude Paul 
91*07a88e2bSLyude Paul 	return 0;
92*07a88e2bSLyude Paul }
93*07a88e2bSLyude Paul 
94*07a88e2bSLyude Paul static void test_exit(struct kunit *test)
95*07a88e2bSLyude Paul {
96*07a88e2bSLyude Paul 	TEST_IRQ_ON();
97*07a88e2bSLyude Paul }
98*07a88e2bSLyude Paul 
99*07a88e2bSLyude Paul static struct kunit_suite refcount_interrupt_test_suite = {
100*07a88e2bSLyude Paul 	.name = "refcount_interrupt",
101*07a88e2bSLyude Paul 	.test_cases = test_cases,
102*07a88e2bSLyude Paul 	.init = test_init,
103*07a88e2bSLyude Paul 	.exit = test_exit,
104*07a88e2bSLyude Paul };
105*07a88e2bSLyude Paul 
106*07a88e2bSLyude Paul kunit_test_suite(refcount_interrupt_test_suite);
107*07a88e2bSLyude Paul MODULE_AUTHOR("Lyude Paul <lyude@redhat.com>");
108*07a88e2bSLyude Paul MODULE_DESCRIPTION("Refcounted interrupt unit test suite");
109*07a88e2bSLyude Paul MODULE_LICENSE("GPL");
110