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