1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * KUnit test for KUnit platform driver infras 3 * KUnit test for KUnit platform driver infrastructure. 4 */ 4 */ 5 5 6 #include <linux/platform_device.h> 6 #include <linux/platform_device.h> 7 7 8 #include <kunit/platform_device.h> 8 #include <kunit/platform_device.h> 9 #include <kunit/test.h> 9 #include <kunit/test.h> 10 10 11 /* 11 /* 12 * Test that kunit_platform_device_alloc() cre 12 * Test that kunit_platform_device_alloc() creates a platform device. 13 */ 13 */ 14 static void kunit_platform_device_alloc_test(s 14 static void kunit_platform_device_alloc_test(struct kunit *test) 15 { 15 { 16 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 16 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 17 kunit_platform_device_ 17 kunit_platform_device_alloc(test, "kunit-platform", 1)); 18 } 18 } 19 19 20 /* 20 /* 21 * Test that kunit_platform_device_add() regis 21 * Test that kunit_platform_device_add() registers a platform device on the 22 * platform bus with the proper name and id. 22 * platform bus with the proper name and id. 23 */ 23 */ 24 static void kunit_platform_device_add_test(str 24 static void kunit_platform_device_add_test(struct kunit *test) 25 { 25 { 26 struct platform_device *pdev; 26 struct platform_device *pdev; 27 const char *name = "kunit-platform-add 27 const char *name = "kunit-platform-add"; 28 const int id = -1; 28 const int id = -1; 29 29 30 pdev = kunit_platform_device_alloc(tes 30 pdev = kunit_platform_device_alloc(test, name, id); 31 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 31 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 32 32 33 KUNIT_EXPECT_EQ(test, 0, kunit_platfor 33 KUNIT_EXPECT_EQ(test, 0, kunit_platform_device_add(test, pdev)); 34 KUNIT_EXPECT_TRUE(test, dev_is_platfor 34 KUNIT_EXPECT_TRUE(test, dev_is_platform(&pdev->dev)); 35 KUNIT_EXPECT_STREQ(test, pdev->name, n 35 KUNIT_EXPECT_STREQ(test, pdev->name, name); 36 KUNIT_EXPECT_EQ(test, pdev->id, id); 36 KUNIT_EXPECT_EQ(test, pdev->id, id); 37 } 37 } 38 38 39 /* 39 /* 40 * Test that kunit_platform_device_add() calle 40 * Test that kunit_platform_device_add() called twice with the same device name 41 * and id fails the second time and properly c 41 * and id fails the second time and properly cleans up. 42 */ 42 */ 43 static void kunit_platform_device_add_twice_fa 43 static void kunit_platform_device_add_twice_fails_test(struct kunit *test) 44 { 44 { 45 struct platform_device *pdev; 45 struct platform_device *pdev; 46 const char *name = "kunit-platform-add 46 const char *name = "kunit-platform-add-2"; 47 const int id = -1; 47 const int id = -1; 48 48 49 pdev = kunit_platform_device_alloc(tes 49 pdev = kunit_platform_device_alloc(test, name, id); 50 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 50 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 51 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 51 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev)); 52 52 53 pdev = kunit_platform_device_alloc(tes 53 pdev = kunit_platform_device_alloc(test, name, id); 54 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 54 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 55 55 56 KUNIT_EXPECT_NE(test, 0, kunit_platfor 56 KUNIT_EXPECT_NE(test, 0, kunit_platform_device_add(test, pdev)); 57 } 57 } 58 58 59 static int kunit_platform_device_find_by_name( 59 static int kunit_platform_device_find_by_name(struct device *dev, const void *data) 60 { 60 { 61 return strcmp(dev_name(dev), data) == 61 return strcmp(dev_name(dev), data) == 0; 62 } 62 } 63 63 64 /* 64 /* 65 * Test that kunit_platform_device_add() clean 65 * Test that kunit_platform_device_add() cleans up by removing the platform 66 * device when the test finishes. */ 66 * device when the test finishes. */ 67 static void kunit_platform_device_add_cleans_u 67 static void kunit_platform_device_add_cleans_up(struct kunit *test) 68 { 68 { 69 struct platform_device *pdev; 69 struct platform_device *pdev; 70 const char *name = "kunit-platform-cle 70 const char *name = "kunit-platform-clean"; 71 const int id = -1; 71 const int id = -1; 72 struct kunit fake; 72 struct kunit fake; 73 struct device *dev; 73 struct device *dev; 74 74 75 kunit_init_test(&fake, "kunit_platform 75 kunit_init_test(&fake, "kunit_platform_device_add_fake_test", NULL); 76 KUNIT_ASSERT_EQ(test, fake.status, KUN 76 KUNIT_ASSERT_EQ(test, fake.status, KUNIT_SUCCESS); 77 77 78 pdev = kunit_platform_device_alloc(&fa 78 pdev = kunit_platform_device_alloc(&fake, name, id); 79 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 79 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 80 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 80 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(&fake, pdev)); 81 dev = bus_find_device(&platform_bus_ty 81 dev = bus_find_device(&platform_bus_type, NULL, name, 82 kunit_platform_d 82 kunit_platform_device_find_by_name); 83 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev 83 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 84 put_device(dev); 84 put_device(dev); 85 85 86 /* Remove pdev */ 86 /* Remove pdev */ 87 kunit_cleanup(&fake); 87 kunit_cleanup(&fake); 88 88 89 /* 89 /* 90 * Failing to migrate the kunit_resour 90 * Failing to migrate the kunit_resource would lead to an extra 91 * put_device() call on the platform d 91 * put_device() call on the platform device. The best we can do here is 92 * make sure the device no longer exis 92 * make sure the device no longer exists on the bus, but if something 93 * is wrong we'll see a refcount under 93 * is wrong we'll see a refcount underflow here. We can't test for a 94 * refcount underflow because the kref 94 * refcount underflow because the kref matches the lifetime of the 95 * device which should already be free 95 * device which should already be freed and could be used by something 96 * else. 96 * else. 97 */ 97 */ 98 dev = bus_find_device(&platform_bus_ty 98 dev = bus_find_device(&platform_bus_type, NULL, name, 99 kunit_platform_d 99 kunit_platform_device_find_by_name); 100 KUNIT_EXPECT_PTR_EQ(test, NULL, dev); 100 KUNIT_EXPECT_PTR_EQ(test, NULL, dev); 101 put_device(dev); 101 put_device(dev); 102 } 102 } 103 103 104 /* 104 /* 105 * Test suite for struct platform_device kunit 105 * Test suite for struct platform_device kunit APIs 106 */ 106 */ 107 static struct kunit_case kunit_platform_device 107 static struct kunit_case kunit_platform_device_test_cases[] = { 108 KUNIT_CASE(kunit_platform_device_alloc 108 KUNIT_CASE(kunit_platform_device_alloc_test), 109 KUNIT_CASE(kunit_platform_device_add_t 109 KUNIT_CASE(kunit_platform_device_add_test), 110 KUNIT_CASE(kunit_platform_device_add_t 110 KUNIT_CASE(kunit_platform_device_add_twice_fails_test), 111 KUNIT_CASE(kunit_platform_device_add_c 111 KUNIT_CASE(kunit_platform_device_add_cleans_up), 112 {} 112 {} 113 }; 113 }; 114 114 115 static struct kunit_suite kunit_platform_devic 115 static struct kunit_suite kunit_platform_device_suite = { 116 .name = "kunit_platform_device", 116 .name = "kunit_platform_device", 117 .test_cases = kunit_platform_device_te 117 .test_cases = kunit_platform_device_test_cases, 118 }; 118 }; 119 119 120 struct kunit_platform_driver_test_context { 120 struct kunit_platform_driver_test_context { 121 struct platform_driver pdrv; 121 struct platform_driver pdrv; 122 const char *data; 122 const char *data; 123 }; 123 }; 124 124 125 static const char * const test_data = "test da 125 static const char * const test_data = "test data"; 126 126 127 static inline struct kunit_platform_driver_tes 127 static inline struct kunit_platform_driver_test_context * 128 to_test_context(struct platform_device *pdev) 128 to_test_context(struct platform_device *pdev) 129 { 129 { 130 return container_of(to_platform_driver 130 return container_of(to_platform_driver(pdev->dev.driver), 131 struct kunit_platf 131 struct kunit_platform_driver_test_context, 132 pdrv); 132 pdrv); 133 } 133 } 134 134 135 static int kunit_platform_driver_probe(struct 135 static int kunit_platform_driver_probe(struct platform_device *pdev) 136 { 136 { 137 struct kunit_platform_driver_test_cont 137 struct kunit_platform_driver_test_context *ctx; 138 138 139 ctx = to_test_context(pdev); 139 ctx = to_test_context(pdev); 140 ctx->data = test_data; 140 ctx->data = test_data; 141 141 142 return 0; 142 return 0; 143 } 143 } 144 144 145 /* Test that kunit_platform_driver_register() 145 /* Test that kunit_platform_driver_register() registers a driver that probes. */ 146 static void kunit_platform_driver_register_tes 146 static void kunit_platform_driver_register_test(struct kunit *test) 147 { 147 { 148 struct platform_device *pdev; 148 struct platform_device *pdev; 149 struct kunit_platform_driver_test_cont 149 struct kunit_platform_driver_test_context *ctx; 150 DECLARE_COMPLETION_ONSTACK(comp); 150 DECLARE_COMPLETION_ONSTACK(comp); 151 const char *name = "kunit-platform-reg 151 const char *name = "kunit-platform-register"; 152 152 153 ctx = kunit_kzalloc(test, sizeof(*ctx) 153 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); 154 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx 154 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 155 155 156 pdev = kunit_platform_device_alloc(tes 156 pdev = kunit_platform_device_alloc(test, name, -1); 157 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 157 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 158 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 158 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev)); 159 159 160 ctx->pdrv.probe = kunit_platform_drive 160 ctx->pdrv.probe = kunit_platform_driver_probe; 161 ctx->pdrv.driver.name = name; 161 ctx->pdrv.driver.name = name; 162 ctx->pdrv.driver.owner = THIS_MODULE; 162 ctx->pdrv.driver.owner = THIS_MODULE; 163 163 164 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 164 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp)); 165 165 166 KUNIT_EXPECT_EQ(test, 0, kunit_platfor 166 KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv)); 167 KUNIT_EXPECT_NE(test, 0, wait_for_comp 167 KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ)); 168 KUNIT_EXPECT_STREQ(test, ctx->data, te 168 KUNIT_EXPECT_STREQ(test, ctx->data, test_data); 169 } 169 } 170 170 171 /* 171 /* 172 * Test that kunit_platform_device_prepare_wai 172 * Test that kunit_platform_device_prepare_wait_for_probe() completes the completion 173 * when the device is already probed. 173 * when the device is already probed. 174 */ 174 */ 175 static void kunit_platform_device_prepare_wait 175 static void kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed(struct kunit *test) 176 { 176 { 177 struct platform_device *pdev; 177 struct platform_device *pdev; 178 struct kunit_platform_driver_test_cont 178 struct kunit_platform_driver_test_context *ctx; 179 DECLARE_COMPLETION_ONSTACK(comp); 179 DECLARE_COMPLETION_ONSTACK(comp); 180 const char *name = "kunit-platform-wai 180 const char *name = "kunit-platform-wait"; 181 181 182 ctx = kunit_kzalloc(test, sizeof(*ctx) 182 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); 183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx 183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 184 184 185 pdev = kunit_platform_device_alloc(tes 185 pdev = kunit_platform_device_alloc(test, name, -1); 186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pde 186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 187 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 187 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev)); 188 188 189 ctx->pdrv.probe = kunit_platform_drive 189 ctx->pdrv.probe = kunit_platform_driver_probe; 190 ctx->pdrv.driver.name = name; 190 ctx->pdrv.driver.name = name; 191 ctx->pdrv.driver.owner = THIS_MODULE; 191 ctx->pdrv.driver.owner = THIS_MODULE; 192 192 193 /* Make sure driver has actually probe 193 /* Make sure driver has actually probed */ 194 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 194 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp)); 195 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 195 KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv)); 196 KUNIT_ASSERT_NE(test, 0, wait_for_comp 196 KUNIT_ASSERT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ)); 197 197 198 reinit_completion(&comp); 198 reinit_completion(&comp); 199 KUNIT_ASSERT_EQ(test, 0, kunit_platfor 199 KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp)); 200 200 201 KUNIT_EXPECT_NE(test, 0, wait_for_comp 201 KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, HZ)); 202 } 202 } 203 203 204 static struct kunit_case kunit_platform_driver 204 static struct kunit_case kunit_platform_driver_test_cases[] = { 205 KUNIT_CASE(kunit_platform_driver_regis 205 KUNIT_CASE(kunit_platform_driver_register_test), 206 KUNIT_CASE(kunit_platform_device_prepa 206 KUNIT_CASE(kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed), 207 {} 207 {} 208 }; 208 }; 209 209 210 /* 210 /* 211 * Test suite for struct platform_driver kunit 211 * Test suite for struct platform_driver kunit APIs 212 */ 212 */ 213 static struct kunit_suite kunit_platform_drive 213 static struct kunit_suite kunit_platform_driver_suite = { 214 .name = "kunit_platform_driver", 214 .name = "kunit_platform_driver", 215 .test_cases = kunit_platform_driver_te 215 .test_cases = kunit_platform_driver_test_cases, 216 }; 216 }; 217 217 218 kunit_test_suites( 218 kunit_test_suites( 219 &kunit_platform_device_suite, 219 &kunit_platform_device_suite, 220 &kunit_platform_driver_suite, 220 &kunit_platform_driver_suite, 221 ); 221 ); 222 222 223 MODULE_LICENSE("GPL"); 223 MODULE_LICENSE("GPL"); 224 MODULE_DESCRIPTION("KUnit test for KUnit platf 224 MODULE_DESCRIPTION("KUnit test for KUnit platform driver infrastructure"); 225 225
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.