Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: hda/cirrus_scodec_test: Modernize creation of dummy devices

Replace the old direct use of platform_device APIs with newer KUnit APIs
and the faux bus.

The dummy codec driver device doesn't need to be a platform device.
It can be a faux bus device.

The dummy GPIO driver still must be a platform_device so that a
software_node can be added to it before it probes. But use the new
KUnit-managed APIs to create the platform_device and platform_driver.
These will cleanup automatically when a test completes or fails.

Also use KUnit resource cleanup to destroy the faux bus driver and the GPIO
software node instead of doing this "manually" in test exit() functions.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20250415105414.471039-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Richard Fitzgerald and committed by
Takashi Iwai
bbf9d313 fd7f3432

+35 -75
+35 -75
sound/pci/hda/cirrus_scodec_test.c
··· 5 5 // Copyright (C) 2023 Cirrus Logic, Inc. and 6 6 // Cirrus Logic International Semiconductor Ltd. 7 7 8 + #include <kunit/platform_device.h> 9 + #include <kunit/resource.h> 8 10 #include <kunit/test.h> 11 + #include <linux/device.h> 12 + #include <linux/device/faux.h> 9 13 #include <linux/gpio/driver.h> 10 14 #include <linux/module.h> 11 15 #include <linux/platform_device.h> 12 16 13 17 #include "cirrus_scodec.h" 18 + 19 + KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy, 20 + struct faux_device *) 21 + KUNIT_DEFINE_ACTION_WRAPPER(device_remove_software_node_wrapper, 22 + device_remove_software_node, 23 + struct device *) 14 24 15 25 struct cirrus_scodec_test_gpio { 16 26 unsigned int pin_state; ··· 28 18 }; 29 19 30 20 struct cirrus_scodec_test_priv { 31 - struct platform_device amp_pdev; 21 + struct faux_device *amp_dev; 32 22 struct platform_device *gpio_pdev; 33 23 struct cirrus_scodec_test_gpio *gpio_priv; 34 24 }; ··· 113 103 114 104 static struct platform_driver cirrus_scodec_test_gpio_driver = { 115 105 .driver.name = "cirrus_scodec_test_gpio_drv", 106 + .driver.owner = THIS_MODULE, 116 107 .probe = cirrus_scodec_test_gpio_probe, 117 108 }; 118 109 ··· 122 111 .name = "cirrus_scodec_test_gpio", 123 112 }; 124 113 125 - static int cirrus_scodec_test_create_gpio(struct kunit *test) 114 + static void cirrus_scodec_test_create_gpio(struct kunit *test) 126 115 { 127 116 struct cirrus_scodec_test_priv *priv = test->priv; 128 - int ret; 129 117 130 - priv->gpio_pdev = platform_device_alloc(cirrus_scodec_test_gpio_driver.driver.name, -1); 131 - if (!priv->gpio_pdev) 132 - return -ENOMEM; 118 + KUNIT_ASSERT_EQ(test, 0, 119 + kunit_platform_driver_register(test, &cirrus_scodec_test_gpio_driver)); 133 120 134 - ret = device_add_software_node(&priv->gpio_pdev->dev, &cirrus_scodec_test_gpio_swnode); 135 - if (ret) { 136 - platform_device_put(priv->gpio_pdev); 137 - KUNIT_FAIL(test, "Failed to add swnode to gpio: %d\n", ret); 138 - return ret; 139 - } 121 + priv->gpio_pdev = kunit_platform_device_alloc(test, 122 + cirrus_scodec_test_gpio_driver.driver.name, 123 + PLATFORM_DEVID_NONE); 124 + KUNIT_ASSERT_NOT_NULL(test, priv->gpio_pdev); 140 125 141 - ret = platform_device_add(priv->gpio_pdev); 142 - if (ret) { 143 - platform_device_put(priv->gpio_pdev); 144 - KUNIT_FAIL(test, "Failed to add gpio platform device: %d\n", ret); 145 - return ret; 146 - } 126 + KUNIT_ASSERT_EQ(test, 0, device_add_software_node(&priv->gpio_pdev->dev, 127 + &cirrus_scodec_test_gpio_swnode)); 128 + KUNIT_ASSERT_EQ(test, 0, kunit_add_action_or_reset(test, 129 + device_remove_software_node_wrapper, 130 + &priv->gpio_pdev->dev)); 131 + 132 + KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, priv->gpio_pdev)); 147 133 148 134 priv->gpio_priv = dev_get_drvdata(&priv->gpio_pdev->dev); 149 - if (!priv->gpio_priv) { 150 - platform_device_put(priv->gpio_pdev); 151 - KUNIT_FAIL(test, "Failed to get gpio private data\n"); 152 - return -EINVAL; 153 - } 154 - 155 - return 0; 135 + KUNIT_ASSERT_NOT_NULL(test, priv->gpio_priv); 156 136 } 157 137 158 138 static void cirrus_scodec_test_set_gpio_ref_arg(struct software_node_ref_args *arg, ··· 193 191 const struct cirrus_scodec_test_spkid_param *param = test->param_value; 194 192 int num_spk_id_refs = param->num_amps * param->gpios_per_amp; 195 193 struct software_node_ref_args *refs; 196 - struct device *dev = &priv->amp_pdev.dev; 194 + struct device *dev = &priv->amp_dev->dev; 197 195 unsigned int v; 198 196 int i, ret; 199 197 ··· 236 234 static void cirrus_scodec_test_no_spkid(struct kunit *test) 237 235 { 238 236 struct cirrus_scodec_test_priv *priv = test->priv; 239 - struct device *dev = &priv->amp_pdev.dev; 237 + struct device *dev = &priv->amp_dev->dev; 240 238 int ret; 241 239 242 240 ret = cirrus_scodec_get_speaker_id(dev, 0, 4, -1); 243 241 KUNIT_EXPECT_EQ(test, ret, -ENOENT); 244 242 } 245 243 246 - static void cirrus_scodec_test_dev_release(struct device *dev) 247 - { 248 - } 249 - 250 244 static int cirrus_scodec_test_case_init(struct kunit *test) 251 245 { 252 246 struct cirrus_scodec_test_priv *priv; 253 - int ret; 254 247 255 248 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 256 249 if (!priv) ··· 254 257 test->priv = priv; 255 258 256 259 /* Create dummy GPIO */ 257 - ret = cirrus_scodec_test_create_gpio(test); 258 - if (ret < 0) 259 - return ret; 260 + cirrus_scodec_test_create_gpio(test); 260 261 261 262 /* Create dummy amp driver dev */ 262 - priv->amp_pdev.name = "cirrus_scodec_test_amp_drv"; 263 - priv->amp_pdev.id = -1; 264 - priv->amp_pdev.dev.release = cirrus_scodec_test_dev_release; 265 - ret = platform_device_register(&priv->amp_pdev); 266 - KUNIT_ASSERT_GE_MSG(test, ret, 0, "Failed to register amp platform device\n"); 263 + priv->amp_dev = faux_device_create("cirrus_scodec_test_amp_drv", NULL, NULL); 264 + KUNIT_ASSERT_NOT_NULL(test, priv->amp_dev); 265 + KUNIT_ASSERT_EQ(test, 0, kunit_add_action_or_reset(test, 266 + faux_device_destroy_wrapper, 267 + priv->amp_dev)); 267 268 268 269 return 0; 269 - } 270 - 271 - static void cirrus_scodec_test_case_exit(struct kunit *test) 272 - { 273 - struct cirrus_scodec_test_priv *priv = test->priv; 274 - 275 - if (priv->amp_pdev.name) 276 - platform_device_unregister(&priv->amp_pdev); 277 - 278 - if (priv->gpio_pdev) { 279 - device_remove_software_node(&priv->gpio_pdev->dev); 280 - platform_device_unregister(priv->gpio_pdev); 281 - } 282 - } 283 - 284 - static int cirrus_scodec_test_suite_init(struct kunit_suite *suite) 285 - { 286 - int ret; 287 - 288 - /* Register mock GPIO driver */ 289 - ret = platform_driver_register(&cirrus_scodec_test_gpio_driver); 290 - if (ret < 0) { 291 - kunit_err(suite, "Failed to register gpio platform driver, %d\n", ret); 292 - return ret; 293 - } 294 - 295 - return 0; 296 - } 297 - 298 - static void cirrus_scodec_test_suite_exit(struct kunit_suite *suite) 299 - { 300 - platform_driver_unregister(&cirrus_scodec_test_gpio_driver); 301 270 } 302 271 303 272 static const struct cirrus_scodec_test_spkid_param cirrus_scodec_test_spkid_param_cases[] = { ··· 319 356 320 357 static struct kunit_suite cirrus_scodec_test_suite = { 321 358 .name = "snd-hda-scodec-cs35l56-test", 322 - .suite_init = cirrus_scodec_test_suite_init, 323 - .suite_exit = cirrus_scodec_test_suite_exit, 324 359 .init = cirrus_scodec_test_case_init, 325 - .exit = cirrus_scodec_test_case_exit, 326 360 .test_cases = cirrus_scodec_test_cases, 327 361 }; 328 362