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