1 // SPDX-License-Identifier: GPL-2.0
3 #include <kunit/resource.h>
5 #include <linux/device.h>
6 #include <linux/platform_device.h>
8 #define DEVICE_NAME "test"
13 wait_queue_head_t probe_wq
;
14 wait_queue_head_t release_wq
;
18 static int platform_device_devm_init(struct kunit
*test
)
20 struct test_priv
*priv
;
22 priv
= kunit_kzalloc(test
, sizeof(*priv
), GFP_KERNEL
);
23 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, priv
);
24 init_waitqueue_head(&priv
->probe_wq
);
25 init_waitqueue_head(&priv
->release_wq
);
32 static void devm_device_action(void *ptr
)
34 struct test_priv
*priv
= ptr
;
36 priv
->release_done
= true;
37 wake_up_interruptible(&priv
->release_wq
);
40 static void devm_put_device_action(void *ptr
)
42 struct test_priv
*priv
= ptr
;
44 put_device(priv
->dev
);
45 priv
->release_done
= true;
46 wake_up_interruptible(&priv
->release_wq
);
49 #define RELEASE_TIMEOUT_MS 100
52 * Tests that a platform bus, non-probed device will run its
53 * device-managed actions when unregistered.
55 static void platform_device_devm_register_unregister_test(struct kunit
*test
)
57 struct platform_device
*pdev
;
58 struct test_priv
*priv
= test
->priv
;
61 pdev
= platform_device_alloc(DEVICE_NAME
, PLATFORM_DEVID_NONE
);
62 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, pdev
);
64 ret
= platform_device_add(pdev
);
65 KUNIT_ASSERT_EQ(test
, ret
, 0);
67 priv
->dev
= &pdev
->dev
;
69 ret
= devm_add_action_or_reset(priv
->dev
, devm_device_action
, priv
);
70 KUNIT_ASSERT_EQ(test
, ret
, 0);
72 platform_device_unregister(pdev
);
74 ret
= wait_event_interruptible_timeout(priv
->release_wq
, priv
->release_done
,
75 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
76 KUNIT_EXPECT_GT(test
, ret
, 0);
80 * Tests that a platform bus, non-probed device will run its
81 * device-managed actions when unregistered, even if someone still holds
84 static void platform_device_devm_register_get_unregister_with_devm_test(struct kunit
*test
)
86 struct platform_device
*pdev
;
87 struct test_priv
*priv
= test
->priv
;
90 pdev
= platform_device_alloc(DEVICE_NAME
, PLATFORM_DEVID_NONE
);
91 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, pdev
);
93 ret
= platform_device_add(pdev
);
94 KUNIT_ASSERT_EQ(test
, ret
, 0);
96 priv
->dev
= &pdev
->dev
;
98 get_device(priv
->dev
);
100 ret
= devm_add_action_or_reset(priv
->dev
, devm_put_device_action
, priv
);
101 KUNIT_ASSERT_EQ(test
, ret
, 0);
103 platform_device_unregister(pdev
);
105 ret
= wait_event_interruptible_timeout(priv
->release_wq
, priv
->release_done
,
106 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
107 KUNIT_EXPECT_GT(test
, ret
, 0);
110 static int fake_probe(struct platform_device
*pdev
)
112 struct test_priv
*priv
= platform_get_drvdata(pdev
);
114 priv
->probe_done
= true;
115 wake_up_interruptible(&priv
->probe_wq
);
120 static struct platform_driver fake_driver
= {
128 * Tests that a platform bus, probed device will run its device-managed
129 * actions when unregistered.
131 static void probed_platform_device_devm_register_unregister_test(struct kunit
*test
)
133 struct platform_device
*pdev
;
134 struct test_priv
*priv
= test
->priv
;
137 ret
= platform_driver_register(&fake_driver
);
138 KUNIT_ASSERT_EQ(test
, ret
, 0);
140 pdev
= platform_device_alloc(DEVICE_NAME
, PLATFORM_DEVID_NONE
);
141 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, pdev
);
143 priv
->dev
= &pdev
->dev
;
144 platform_set_drvdata(pdev
, priv
);
146 ret
= platform_device_add(pdev
);
147 KUNIT_ASSERT_EQ(test
, ret
, 0);
149 ret
= wait_event_interruptible_timeout(priv
->probe_wq
, priv
->probe_done
,
150 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
151 KUNIT_ASSERT_GT(test
, ret
, 0);
153 ret
= devm_add_action_or_reset(priv
->dev
, devm_device_action
, priv
);
154 KUNIT_ASSERT_EQ(test
, ret
, 0);
156 platform_device_unregister(pdev
);
158 ret
= wait_event_interruptible_timeout(priv
->release_wq
, priv
->release_done
,
159 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
160 KUNIT_EXPECT_GT(test
, ret
, 0);
162 platform_driver_unregister(&fake_driver
);
166 * Tests that a platform bus, probed device will run its device-managed
167 * actions when unregistered, even if someone still holds a reference to
170 static void probed_platform_device_devm_register_get_unregister_with_devm_test(struct kunit
*test
)
172 struct platform_device
*pdev
;
173 struct test_priv
*priv
= test
->priv
;
176 ret
= platform_driver_register(&fake_driver
);
177 KUNIT_ASSERT_EQ(test
, ret
, 0);
179 pdev
= platform_device_alloc(DEVICE_NAME
, PLATFORM_DEVID_NONE
);
180 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, pdev
);
182 priv
->dev
= &pdev
->dev
;
183 platform_set_drvdata(pdev
, priv
);
185 ret
= platform_device_add(pdev
);
186 KUNIT_ASSERT_EQ(test
, ret
, 0);
188 ret
= wait_event_interruptible_timeout(priv
->probe_wq
, priv
->probe_done
,
189 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
190 KUNIT_ASSERT_GT(test
, ret
, 0);
192 get_device(priv
->dev
);
194 ret
= devm_add_action_or_reset(priv
->dev
, devm_put_device_action
, priv
);
195 KUNIT_ASSERT_EQ(test
, ret
, 0);
197 platform_device_unregister(pdev
);
199 ret
= wait_event_interruptible_timeout(priv
->release_wq
, priv
->release_done
,
200 msecs_to_jiffies(RELEASE_TIMEOUT_MS
));
201 KUNIT_EXPECT_GT(test
, ret
, 0);
203 platform_driver_unregister(&fake_driver
);
206 static struct kunit_case platform_device_devm_tests
[] = {
207 KUNIT_CASE(platform_device_devm_register_unregister_test
),
208 KUNIT_CASE(platform_device_devm_register_get_unregister_with_devm_test
),
209 KUNIT_CASE(probed_platform_device_devm_register_unregister_test
),
210 KUNIT_CASE(probed_platform_device_devm_register_get_unregister_with_devm_test
),
214 static struct kunit_suite platform_device_devm_test_suite
= {
215 .name
= "platform-device-devm",
216 .init
= platform_device_devm_init
,
217 .test_cases
= platform_device_devm_tests
,
220 kunit_test_suite(platform_device_devm_test_suite
);
222 MODULE_DESCRIPTION("Test module for platform devices");
223 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
224 MODULE_LICENSE("GPL");