1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * KUnit-managed device implementation 4 * 5 * Implementation of struct kunit_device helpers for fake devices whose 6 * lifecycle is managed by KUnit. 7 * 8 * Copyright (C) 2023, Google LLC. 9 * Author: David Gow <davidgow@google.com> 10 */ 11 12 #include <linux/device.h> 13 14 #include <kunit/test.h> 15 #include <kunit/device.h> 16 #include <kunit/resource.h> 17 18 #include "device-impl.h" 19 20 /* Wrappers for use with kunit_add_action() */ 21 KUNIT_DEFINE_ACTION_WRAPPER(device_unregister_wrapper, device_unregister, struct device *); 22 KUNIT_DEFINE_ACTION_WRAPPER(driver_unregister_wrapper, driver_unregister, struct device_driver *); 23 24 /* The root device for the KUnit bus, parent of all kunit_devices. */ 25 static struct device *kunit_bus_device; 26 27 /* A device owned by a KUnit test. */ 28 struct kunit_device { 29 struct device dev; 30 /* The KUnit test which owns this device. */ 31 struct kunit *owner; 32 /* If the driver is managed by KUnit and unique to this device. */ 33 const struct device_driver *driver; 34 }; 35 36 #define to_kunit_device(d) container_of_const(d, struct kunit_device, dev) 37 38 static struct bus_type kunit_bus_type = { 39 .name = "kunit", 40 }; 41 42 /* Register the 'kunit_bus' used for fake devices. */ 43 int kunit_bus_init(void) 44 { 45 int error; 46 47 kunit_bus_device = root_device_register("kunit"); 48 if (!kunit_bus_device) 49 return -ENOMEM; 50 51 error = bus_register(&kunit_bus_type); 52 if (error) 53 bus_unregister(&kunit_bus_type); 54 return error; 55 } 56 57 /* Release a 'fake' KUnit device. */ 58 static void kunit_device_release(struct device *d) 59 { 60 kfree(to_kunit_device(d)); 61 } 62 63 /* 64 * Create and register a KUnit-managed struct device_driver on the kunit_bus. 65 * Returns an error pointer on failure. 66 */ 67 struct device_driver *kunit_driver_create(struct kunit *test, const char *name) 68 { 69 struct device_driver *driver; 70 int err = -ENOMEM; 71 72 driver = kunit_kzalloc(test, sizeof(*driver), GFP_KERNEL); 73 74 if (!driver) 75 return ERR_PTR(err); 76 77 driver->name = name; 78 driver->bus = &kunit_bus_type; 79 driver->owner = THIS_MODULE; 80 81 err = driver_register(driver); 82 if (err) { 83 kunit_kfree(test, driver); 84 return ERR_PTR(err); 85 } 86 87 kunit_add_action(test, driver_unregister_wrapper, driver); 88 return driver; 89 } 90 EXPORT_SYMBOL_GPL(kunit_driver_create); 91 92 /* Helper which creates a kunit_device, attaches it to the kunit_bus*/ 93 static struct kunit_device *kunit_device_register_internal(struct kunit *test, 94 const char *name, 95 const struct device_driver *drv) 96 { 97 struct kunit_device *kunit_dev; 98 int err = -ENOMEM; 99 100 kunit_dev = kzalloc(sizeof(*kunit_dev), GFP_KERNEL); 101 if (!kunit_dev) 102 return ERR_PTR(err); 103 104 kunit_dev->owner = test; 105 106 err = dev_set_name(&kunit_dev->dev, "%s.%s", test->name, name); 107 if (err) { 108 kfree(kunit_dev); 109 return ERR_PTR(err); 110 } 111 112 kunit_dev->dev.release = kunit_device_release; 113 kunit_dev->dev.bus = &kunit_bus_type; 114 kunit_dev->dev.parent = kunit_bus_device; 115 116 err = device_register(&kunit_dev->dev); 117 if (err) { 118 put_device(&kunit_dev->dev); 119 return ERR_PTR(err); 120 } 121 122 kunit_add_action(test, device_unregister_wrapper, &kunit_dev->dev); 123 124 return kunit_dev; 125 } 126 127 /* 128 * Create and register a new KUnit-managed device, using the user-supplied device_driver. 129 * On failure, returns an error pointer. 130 */ 131 struct device *kunit_device_register_with_driver(struct kunit *test, 132 const char *name, 133 const struct device_driver *drv) 134 { 135 struct kunit_device *kunit_dev = kunit_device_register_internal(test, name, drv); 136 137 if (IS_ERR_OR_NULL(kunit_dev)) 138 return ERR_CAST(kunit_dev); 139 140 return &kunit_dev->dev; 141 } 142 EXPORT_SYMBOL_GPL(kunit_device_register_with_driver); 143 144 /* 145 * Create and register a new KUnit-managed device, including a matching device_driver. 146 * On failure, returns an error pointer. 147 */ 148 struct device *kunit_device_register(struct kunit *test, const char *name) 149 { 150 struct device_driver *drv; 151 struct kunit_device *dev; 152 153 drv = kunit_driver_create(test, name); 154 if (IS_ERR(drv)) 155 return ERR_CAST(drv); 156 157 dev = kunit_device_register_internal(test, name, drv); 158 if (IS_ERR(dev)) { 159 kunit_release_action(test, driver_unregister_wrapper, (void *)drv); 160 return ERR_CAST(dev); 161 } 162 163 /* Request the driver be freed. */ 164 dev->driver = drv; 165 166 167 return &dev->dev; 168 } 169 EXPORT_SYMBOL_GPL(kunit_device_register); 170 171 /* Unregisters a KUnit-managed device early (including the driver, if automatically created). */ 172 void kunit_device_unregister(struct kunit *test, struct device *dev) 173 { 174 const struct device_driver *driver = to_kunit_device(dev)->driver; 175 176 kunit_release_action(test, device_unregister_wrapper, dev); 177 if (driver) 178 kunit_release_action(test, driver_unregister_wrapper, (void *)driver); 179 } 180 EXPORT_SYMBOL_GPL(kunit_device_unregister); 181 182