Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0 2 : : /* 3 : : * driver.c - centralized device driver management 4 : : * 5 : : * Copyright (c) 2002-3 Patrick Mochel 6 : : * Copyright (c) 2002-3 Open Source Development Labs 7 : : * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> 8 : : * Copyright (c) 2007 Novell Inc. 9 : : */ 10 : : 11 : : #include <linux/device.h> 12 : : #include <linux/module.h> 13 : : #include <linux/errno.h> 14 : : #include <linux/slab.h> 15 : : #include <linux/string.h> 16 : : #include <linux/sysfs.h> 17 : : #include "base.h" 18 : : 19 : : static struct device *next_device(struct klist_iter *i) 20 : : { 21 : 0 : struct klist_node *n = klist_next(i); 22 : : struct device *dev = NULL; 23 : : struct device_private *dev_prv; 24 : : 25 : 0 : if (n) { 26 : : dev_prv = to_device_private_driver(n); 27 : 0 : dev = dev_prv->device; 28 : : } 29 : : return dev; 30 : : } 31 : : 32 : : /** 33 : : * driver_for_each_device - Iterator for devices bound to a driver. 34 : : * @drv: Driver we're iterating. 35 : : * @start: Device to begin with 36 : : * @data: Data to pass to the callback. 37 : : * @fn: Function to call for each device. 38 : : * 39 : : * Iterate over the @drv's list of devices calling @fn for each one. 40 : : */ 41 : 0 : int driver_for_each_device(struct device_driver *drv, struct device *start, 42 : : void *data, int (*fn)(struct device *, void *)) 43 : : { 44 : : struct klist_iter i; 45 : : struct device *dev; 46 : : int error = 0; 47 : : 48 : 0 : if (!drv) 49 : : return -EINVAL; 50 : : 51 : 0 : klist_iter_init_node(&drv->p->klist_devices, &i, 52 : 0 : start ? &start->p->knode_driver : NULL); 53 : 0 : while (!error && (dev = next_device(&i))) 54 : 0 : error = fn(dev, data); 55 : 0 : klist_iter_exit(&i); 56 : 0 : return error; 57 : : } 58 : : EXPORT_SYMBOL_GPL(driver_for_each_device); 59 : : 60 : : /** 61 : : * driver_find_device - device iterator for locating a particular device. 62 : : * @drv: The device's driver 63 : : * @start: Device to begin with 64 : : * @data: Data to pass to match function 65 : : * @match: Callback function to check device 66 : : * 67 : : * This is similar to the driver_for_each_device() function above, but 68 : : * it returns a reference to a device that is 'found' for later use, as 69 : : * determined by the @match callback. 70 : : * 71 : : * The callback should return 0 if the device doesn't match and non-zero 72 : : * if it does. If the callback returns non-zero, this function will 73 : : * return to the caller and not iterate over any more devices. 74 : : */ 75 : 0 : struct device *driver_find_device(struct device_driver *drv, 76 : : struct device *start, const void *data, 77 : : int (*match)(struct device *dev, const void *data)) 78 : : { 79 : : struct klist_iter i; 80 : : struct device *dev; 81 : : 82 : 0 : if (!drv || !drv->p) 83 : : return NULL; 84 : : 85 : 0 : klist_iter_init_node(&drv->p->klist_devices, &i, 86 : 0 : (start ? &start->p->knode_driver : NULL)); 87 : 0 : while ((dev = next_device(&i))) 88 : 0 : if (match(dev, data) && get_device(dev)) 89 : : break; 90 : 0 : klist_iter_exit(&i); 91 : 0 : return dev; 92 : : } 93 : : EXPORT_SYMBOL_GPL(driver_find_device); 94 : : 95 : : /** 96 : : * driver_create_file - create sysfs file for driver. 97 : : * @drv: driver. 98 : : * @attr: driver attribute descriptor. 99 : : */ 100 : 3 : int driver_create_file(struct device_driver *drv, 101 : : const struct driver_attribute *attr) 102 : : { 103 : : int error; 104 : : 105 : 3 : if (drv) 106 : 3 : error = sysfs_create_file(&drv->p->kobj, &attr->attr); 107 : : else 108 : : error = -EINVAL; 109 : 3 : return error; 110 : : } 111 : : EXPORT_SYMBOL_GPL(driver_create_file); 112 : : 113 : : /** 114 : : * driver_remove_file - remove sysfs file for driver. 115 : : * @drv: driver. 116 : : * @attr: driver attribute descriptor. 117 : : */ 118 : 0 : void driver_remove_file(struct device_driver *drv, 119 : : const struct driver_attribute *attr) 120 : : { 121 : 0 : if (drv) 122 : 0 : sysfs_remove_file(&drv->p->kobj, &attr->attr); 123 : 0 : } 124 : : EXPORT_SYMBOL_GPL(driver_remove_file); 125 : : 126 : 3 : int driver_add_groups(struct device_driver *drv, 127 : : const struct attribute_group **groups) 128 : : { 129 : 3 : return sysfs_create_groups(&drv->p->kobj, groups); 130 : : } 131 : : 132 : 0 : void driver_remove_groups(struct device_driver *drv, 133 : : const struct attribute_group **groups) 134 : : { 135 : 0 : sysfs_remove_groups(&drv->p->kobj, groups); 136 : 0 : } 137 : : 138 : : /** 139 : : * driver_register - register driver with bus 140 : : * @drv: driver to register 141 : : * 142 : : * We pass off most of the work to the bus_add_driver() call, 143 : : * since most of the things we have to do deal with the bus 144 : : * structures. 145 : : */ 146 : 3 : int driver_register(struct device_driver *drv) 147 : : { 148 : : int ret; 149 : : struct device_driver *other; 150 : : 151 : 3 : if (!drv->bus->p) { 152 : 0 : pr_err("Driver '%s' was unable to register with bus_type '%s' because the bus was not initialized.\n", 153 : : drv->name, drv->bus->name); 154 : 0 : return -EINVAL; 155 : : } 156 : : 157 : 3 : if ((drv->bus->probe && drv->probe) || 158 : 3 : (drv->bus->remove && drv->remove) || 159 : 3 : (drv->bus->shutdown && drv->shutdown)) 160 : 0 : printk(KERN_WARNING "Driver '%s' needs updating - please use " 161 : : "bus_type methods\n", drv->name); 162 : : 163 : 3 : other = driver_find(drv->name, drv->bus); 164 : 3 : if (other) { 165 : 0 : printk(KERN_ERR "Error: Driver '%s' is already registered, " 166 : : "aborting...\n", drv->name); 167 : 0 : return -EBUSY; 168 : : } 169 : : 170 : 3 : ret = bus_add_driver(drv); 171 : 3 : if (ret) 172 : : return ret; 173 : 3 : ret = driver_add_groups(drv, drv->groups); 174 : 3 : if (ret) { 175 : 0 : bus_remove_driver(drv); 176 : 0 : return ret; 177 : : } 178 : 3 : kobject_uevent(&drv->p->kobj, KOBJ_ADD); 179 : : 180 : 3 : return ret; 181 : : } 182 : : EXPORT_SYMBOL_GPL(driver_register); 183 : : 184 : : /** 185 : : * driver_unregister - remove driver from system. 186 : : * @drv: driver. 187 : : * 188 : : * Again, we pass off most of the work to the bus-level call. 189 : : */ 190 : 0 : void driver_unregister(struct device_driver *drv) 191 : : { 192 : 0 : if (!drv || !drv->p) { 193 : 0 : WARN(1, "Unexpected driver unregister!\n"); 194 : 0 : return; 195 : : } 196 : 0 : driver_remove_groups(drv, drv->groups); 197 : 0 : bus_remove_driver(drv); 198 : : } 199 : : EXPORT_SYMBOL_GPL(driver_unregister); 200 : : 201 : : /** 202 : : * driver_find - locate driver on a bus by its name. 203 : : * @name: name of the driver. 204 : : * @bus: bus to scan for the driver. 205 : : * 206 : : * Call kset_find_obj() to iterate over list of drivers on 207 : : * a bus to find driver by name. Return driver if found. 208 : : * 209 : : * This routine provides no locking to prevent the driver it returns 210 : : * from being unregistered or unloaded while the caller is using it. 211 : : * The caller is responsible for preventing this. 212 : : */ 213 : 3 : struct device_driver *driver_find(const char *name, struct bus_type *bus) 214 : : { 215 : 3 : struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); 216 : : struct driver_private *priv; 217 : : 218 : 3 : if (k) { 219 : : /* Drop reference added by kset_find_obj() */ 220 : 0 : kobject_put(k); 221 : : priv = to_driver(k); 222 : 0 : return priv->driver; 223 : : } 224 : : return NULL; 225 : : } 226 : : EXPORT_SYMBOL_GPL(driver_find);