1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2019-2020 Intel Corporation 4 * 5 * Please see Documentation/driver-api/auxiliary_bus.rst for more information. 6 */ 7 8 #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ 9 10 #include <linux/device.h> 11 #include <linux/init.h> 12 #include <linux/slab.h> 13 #include <linux/module.h> 14 #include <linux/pm_domain.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/string.h> 17 #include <linux/auxiliary_bus.h> 18 #include "base.h" 19 20 static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, 21 const struct auxiliary_device *auxdev) 22 { 23 for (; id->name[0]; id++) { 24 const char *p = strrchr(dev_name(&auxdev->dev), '.'); 25 int match_size; 26 27 if (!p) 28 continue; 29 match_size = p - dev_name(&auxdev->dev); 30 31 /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ 32 if (strlen(id->name) == match_size && 33 !strncmp(dev_name(&auxdev->dev), id->name, match_size)) 34 return id; 35 } 36 return NULL; 37 } 38 39 static int auxiliary_match(struct device *dev, struct device_driver *drv) 40 { 41 struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 42 struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); 43 44 return !!auxiliary_match_id(auxdrv->id_table, auxdev); 45 } 46 47 static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) 48 { 49 const char *name, *p; 50 51 name = dev_name(dev); 52 p = strrchr(name, '.'); 53 54 return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, 55 (int)(p - name), name); 56 } 57 58 static const struct dev_pm_ops auxiliary_dev_pm_ops = { 59 SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) 60 SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) 61 }; 62 63 static int auxiliary_bus_probe(struct device *dev) 64 { 65 struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); 66 struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 67 int ret; 68 69 ret = dev_pm_domain_attach(dev, true); 70 if (ret) { 71 dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret); 72 return ret; 73 } 74 75 ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev)); 76 if (ret) 77 dev_pm_domain_detach(dev, true); 78 79 return ret; 80 } 81 82 static void auxiliary_bus_remove(struct device *dev) 83 { 84 struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); 85 struct auxiliary_device *auxdev = to_auxiliary_dev(dev); 86 87 if (auxdrv->remove) 88 auxdrv->remove(auxdev); 89 dev_pm_domain_detach(dev, true); 90 } 91 92 static void auxiliary_bus_shutdown(struct device *dev) 93 { 94 struct auxiliary_driver *auxdrv = NULL; 95 struct auxiliary_device *auxdev; 96 97 if (dev->driver) { 98 auxdrv = to_auxiliary_drv(dev->driver); 99 auxdev = to_auxiliary_dev(dev); 100 } 101 102 if (auxdrv && auxdrv->shutdown) 103 auxdrv->shutdown(auxdev); 104 } 105 106 static struct bus_type auxiliary_bus_type = { 107 .name = "auxiliary", 108 .probe = auxiliary_bus_probe, 109 .remove = auxiliary_bus_remove, 110 .shutdown = auxiliary_bus_shutdown, 111 .match = auxiliary_match, 112 .uevent = auxiliary_uevent, 113 .pm = &auxiliary_dev_pm_ops, 114 }; 115 116 /** 117 * auxiliary_device_init - check auxiliary_device and initialize 118 * @auxdev: auxiliary device struct 119 * 120 * This is the first step in the two-step process to register an 121 * auxiliary_device. 122 * 123 * When this function returns an error code, then the device_initialize will 124 * *not* have been performed, and the caller will be responsible to free any 125 * memory allocated for the auxiliary_device in the error path directly. 126 * 127 * It returns 0 on success. On success, the device_initialize has been 128 * performed. After this point any error unwinding will need to include a call 129 * to auxiliary_device_uninit(). In this post-initialize error scenario, a call 130 * to the device's .release callback will be triggered, and all memory clean-up 131 * is expected to be handled there. 132 */ 133 int auxiliary_device_init(struct auxiliary_device *auxdev) 134 { 135 struct device *dev = &auxdev->dev; 136 137 if (!dev->parent) { 138 pr_err("auxiliary_device has a NULL dev->parent\n"); 139 return -EINVAL; 140 } 141 142 if (!auxdev->name) { 143 pr_err("auxiliary_device has a NULL name\n"); 144 return -EINVAL; 145 } 146 147 dev->bus = &auxiliary_bus_type; 148 device_initialize(&auxdev->dev); 149 return 0; 150 } 151 EXPORT_SYMBOL_GPL(auxiliary_device_init); 152 153 /** 154 * __auxiliary_device_add - add an auxiliary bus device 155 * @auxdev: auxiliary bus device to add to the bus 156 * @modname: name of the parent device's driver module 157 * 158 * This is the second step in the two-step process to register an 159 * auxiliary_device. 160 * 161 * This function must be called after a successful call to 162 * auxiliary_device_init(), which will perform the device_initialize. This 163 * means that if this returns an error code, then a call to 164 * auxiliary_device_uninit() must be performed so that the .release callback 165 * will be triggered to free the memory associated with the auxiliary_device. 166 * 167 * The expectation is that users will call the "auxiliary_device_add" macro so 168 * that the caller's KBUILD_MODNAME is automatically inserted for the modname 169 * parameter. Only if a user requires a custom name would this version be 170 * called directly. 171 */ 172 int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) 173 { 174 struct device *dev = &auxdev->dev; 175 int ret; 176 177 if (!modname) { 178 dev_err(dev, "auxiliary device modname is NULL\n"); 179 return -EINVAL; 180 } 181 182 ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); 183 if (ret) { 184 dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret); 185 return ret; 186 } 187 188 ret = device_add(dev); 189 if (ret) 190 dev_err(dev, "adding auxiliary device failed!: %d\n", ret); 191 192 return ret; 193 } 194 EXPORT_SYMBOL_GPL(__auxiliary_device_add); 195 196 /** 197 * auxiliary_find_device - auxiliary device iterator for locating a particular device. 198 * @start: Device to begin with 199 * @data: Data to pass to match function 200 * @match: Callback function to check device 201 * 202 * This function returns a reference to a device that is 'found' 203 * for later use, as determined by the @match callback. 204 * 205 * The callback should return 0 if the device doesn't match and non-zero 206 * if it does. If the callback returns non-zero, this function will 207 * return to the caller and not iterate over any more devices. 208 */ 209 struct auxiliary_device *auxiliary_find_device(struct device *start, 210 const void *data, 211 int (*match)(struct device *dev, const void *data)) 212 { 213 struct device *dev; 214 215 dev = bus_find_device(&auxiliary_bus_type, start, data, match); 216 if (!dev) 217 return NULL; 218 219 return to_auxiliary_dev(dev); 220 } 221 EXPORT_SYMBOL_GPL(auxiliary_find_device); 222 223 /** 224 * __auxiliary_driver_register - register a driver for auxiliary bus devices 225 * @auxdrv: auxiliary_driver structure 226 * @owner: owning module/driver 227 * @modname: KBUILD_MODNAME for parent driver 228 */ 229 int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, 230 struct module *owner, const char *modname) 231 { 232 int ret; 233 234 if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) 235 return -EINVAL; 236 237 if (auxdrv->name) 238 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, 239 auxdrv->name); 240 else 241 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); 242 if (!auxdrv->driver.name) 243 return -ENOMEM; 244 245 auxdrv->driver.owner = owner; 246 auxdrv->driver.bus = &auxiliary_bus_type; 247 auxdrv->driver.mod_name = modname; 248 249 ret = driver_register(&auxdrv->driver); 250 if (ret) 251 kfree(auxdrv->driver.name); 252 253 return ret; 254 } 255 EXPORT_SYMBOL_GPL(__auxiliary_driver_register); 256 257 /** 258 * auxiliary_driver_unregister - unregister a driver 259 * @auxdrv: auxiliary_driver structure 260 */ 261 void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) 262 { 263 driver_unregister(&auxdrv->driver); 264 kfree(auxdrv->driver.name); 265 } 266 EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); 267 268 void __init auxiliary_bus_init(void) 269 { 270 WARN_ON(bus_register(&auxiliary_bus_type)); 271 } 272