cregit-Linux how code gets into the kernel

Release 4.7 drivers/base/core.c

Directory: drivers/base
/*
 * drivers/base/core.c - core driver model code (device registration, etc)
 *
 * Copyright (c) 2002-3 Patrick Mochel
 * Copyright (c) 2002-3 Open Source Development Labs
 * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
 * Copyright (c) 2006 Novell, Inc.
 *
 * This file is released under the GPLv2
 *
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/fwnode.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/genhd.h>
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/netdevice.h>
#include <linux/sysfs.h>

#include "base.h"
#include "power/power.h"

#ifdef CONFIG_SYSFS_DEPRECATED
#ifdef CONFIG_SYSFS_DEPRECATED_V2

long sysfs_deprecated = 1;
#else

long sysfs_deprecated = 0;
#endif

static int __init sysfs_deprecated_setup(char *arg) { return kstrtol(arg, 10, &sysfs_deprecated); }

Contributors

PersonTokensPropCommitsCommitProp
andi kleenandi kleen2090.91%133.33%
hanjun guohanjun guo14.55%133.33%
jingoo hanjingoo han14.55%133.33%
Total22100.00%3100.00%

early_param("sysfs.deprecated", sysfs_deprecated_setup); #endif int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL; static struct kobject *dev_kobj; struct kobject *sysfs_dev_char_kobj; struct kobject *sysfs_dev_block_kobj; static DEFINE_MUTEX(device_hotplug_lock);
void lock_device_hotplug(void) { mutex_lock(&device_hotplug_lock); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki13100.00%1100.00%
Total13100.00%1100.00%


void unlock_device_hotplug(void) { mutex_unlock(&device_hotplug_lock); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki13100.00%1100.00%
Total13100.00%1100.00%


int lock_device_hotplug_sysfs(void) { if (mutex_trylock(&device_hotplug_lock)) return 0; /* Avoid busy looping (5 ms of sleep should do). */ msleep(5); return restart_syscall(); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki28100.00%1100.00%
Total28100.00%1100.00%

#ifdef CONFIG_BLOCK
static inline int device_is_not_partition(struct device *dev) { return !(dev->type == &part_type); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman23100.00%1100.00%
Total23100.00%1100.00%

#else
static inline int device_is_not_partition(struct device *dev) { return 1; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman15100.00%1100.00%
Total15100.00%1100.00%

#endif /** * dev_driver_string - Return a device's driver name, if at all possible * @dev: struct device to get the name of * * Will return the device's driver's name if it is bound to a device. If * the device is not bound to a driver, it will return the name of the bus * it is attached to. If it is not attached to a bus either, an empty * string will be returned. */
const char *dev_driver_string(const struct device *dev) { struct device_driver *drv; /* dev->driver can change to NULL underneath us because of unbinding, * so be careful about accessing it. dev->bus and dev->class should * never change once they are set, so they don't need special care. */ drv = ACCESS_ONCE(dev->driver); return drv ? drv->name : (dev->bus ? dev->bus->name : (dev->class ? dev->class->name : "")); }

Contributors

PersonTokensPropCommitsCommitProp
alan sternalan stern4878.69%250.00%
jean delvarejean delvare1321.31%250.00%
Total61100.00%4100.00%

EXPORT_SYMBOL(dev_driver_string); #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct device_attribute *dev_attr = to_dev_attr(attr); struct device *dev = kobj_to_dev(kobj); ssize_t ret = -EIO; if (dev_attr->show) ret = dev_attr->show(dev, dev_attr, buf); if (ret >= (ssize_t)PAGE_SIZE) { print_symbol("dev_attr_show: %s returned bad count\n", (unsigned long)dev_attr->show); } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel6368.48%116.67%
andrew mortonandrew morton1819.57%116.67%
greg kroah-hartmangreg kroah-hartman66.52%116.67%
yani ioannouyani ioannou22.17%116.67%
dmitry torokhovdmitry torokhov22.17%116.67%
lars-peter clausenlars-peter clausen11.09%116.67%
Total92100.00%6100.00%


static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct device_attribute *dev_attr = to_dev_attr(attr); struct device *dev = kobj_to_dev(kobj); ssize_t ret = -EIO; if (dev_attr->store) ret = dev_attr->store(dev, dev_attr, buf, count); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel6993.24%240.00%
dmitry torokhovdmitry torokhov22.70%120.00%
yani ioannouyani ioannou22.70%120.00%
lars-peter clausenlars-peter clausen11.35%120.00%
Total74100.00%5100.00%

static const struct sysfs_ops dev_sysfs_ops = { .show = dev_attr_show, .store = dev_attr_store, }; #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct dev_ext_attribute *ea = to_ext_attr(attr); char *end; unsigned long new = simple_strtoul(buf, &end, 0); if (end == buf) return -EINVAL; *(unsigned long *)(ea->var) = new; /* Always return full write size even if we didn't consume all */ return size; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers79100.00%1100.00%
Total79100.00%1100.00%

EXPORT_SYMBOL_GPL(device_store_ulong);
ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *ea = to_ext_attr(attr); return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers51100.00%1100.00%
Total51100.00%1100.00%

EXPORT_SYMBOL_GPL(device_show_ulong);
ssize_t device_store_int(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct dev_ext_attribute *ea = to_ext_attr(attr); char *end; long new = simple_strtol(buf, &end, 0); if (end == buf || new > INT_MAX || new < INT_MIN) return -EINVAL; *(int *)(ea->var) = new; /* Always return full write size even if we didn't consume all */ return size; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers85100.00%1100.00%
Total85100.00%1100.00%

EXPORT_SYMBOL_GPL(device_store_int);
ssize_t device_show_int(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *ea = to_ext_attr(attr); return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers50100.00%1100.00%
Total50100.00%1100.00%

EXPORT_SYMBOL_GPL(device_show_int);
ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct dev_ext_attribute *ea = to_ext_attr(attr); if (strtobool(buf, ea->var) < 0) return -EINVAL; return size; }

Contributors

PersonTokensPropCommitsCommitProp
borislav petkovborislav petkov53100.00%1100.00%
Total53100.00%1100.00%

EXPORT_SYMBOL_GPL(device_store_bool);
ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *ea = to_ext_attr(attr); return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); }

Contributors

PersonTokensPropCommitsCommitProp
borislav petkovborislav petkov50100.00%1100.00%
Total50100.00%1100.00%

EXPORT_SYMBOL_GPL(device_show_bool); /** * device_release - free device structure. * @kobj: device's kobject. * * This is called once the reference count for the object * reaches 0. We forward the call to the device's release * method, which should handle actually freeing the structure. */
static void device_release(struct kobject *kobj) { struct device *dev = kobj_to_dev(kobj); struct device_private *p = dev->p; /* * Some platform devices are driven without driver attached * and managed resources may have been acquired. Make sure * all resources are released. * * Drivers still can add resources into device after device * is deleted but alive, so release devres here to avoid * possible memory leak. */ devres_release_all(dev); if (dev->release) dev->release(dev); else if (dev->type && dev->type->release) dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); else WARN(1, KERN_ERR "Device '%s' does not have a release() " "function, it is broken and must be fixed.\n", dev_name(dev)); kfree(p); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman4539.82%440.00%
patrick mochelpatrick mochel3329.20%110.00%
kay sieverskay sievers2522.12%220.00%
lei minglei ming65.31%110.00%
arjan van de venarjan van de ven32.65%110.00%
lars-peter clausenlars-peter clausen10.88%110.00%
Total113100.00%10100.00%


static const void *device_namespace(struct kobject *kobj) { struct device *dev = kobj_to_dev(kobj); const void *ns = NULL; if (dev->class && dev->class->ns_type) ns = dev->class->namespace(dev); return ns; }

Contributors

PersonTokensPropCommitsCommitProp
eric w. biedermaneric w. biederman5598.21%150.00%
lars-peter clausenlars-peter clausen11.79%150.00%
Total56100.00%2100.00%

static struct kobj_type device_ktype = { .release = device_release, .sysfs_ops = &dev_sysfs_ops, .namespace = device_namespace, };
static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) { struct kobj_type *ktype = get_ktype(kobj); if (ktype == &device_ktype) { struct device *dev = kobj_to_dev(kobj); if (dev->bus) return 1; if (dev->class) return 1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman6496.97%360.00%
lars-peter clausenlars-peter clausen11.52%120.00%
kay sieverskay sievers11.52%120.00%
Total66100.00%5100.00%


static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) { struct device *dev = kobj_to_dev(kobj); if (dev->bus) return dev->bus->name; if (dev->class) return dev->class->name; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman5494.74%240.00%
dmitry torokhovdmitry torokhov11.75%120.00%
kay sieverskay sievers11.75%120.00%
lars-peter clausenlars-peter clausen11.75%120.00%
Total57100.00%5100.00%


static int dev_uevent(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env) { struct device *dev = kobj_to_dev(kobj); int retval = 0; /* add device node properties if present */ if (MAJOR(dev->devt)) { const char *tmp; const char *name; umode_t mode = 0; kuid_t uid = GLOBAL_ROOT_UID; kgid_t gid = GLOBAL_ROOT_GID; add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); if (name) { add_uevent_var(env, "DEVNAME=%s", name); if (mode) add_uevent_var(env, "DEVMODE=%#o", mode & 0777); if (!uid_eq(uid, GLOBAL_ROOT_UID)) add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); if (!gid_eq(gid, GLOBAL_ROOT_GID)) add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); kfree(tmp); } } if (dev->type && dev->type->name) add_uevent_var(env, "DEVTYPE=%s", dev->type->name); if (dev->driver) add_uevent_var(env, "DRIVER=%s", dev->driver->name); /* Add common DT information about the device */ of_device_uevent(dev, env); /* have the bus specific function add its stuff */ if (dev->bus && dev->bus->uevent) { retval = dev->bus->uevent(dev, env); if (retval) pr_debug("device: '%s': %s: bus uevent() returned %d\n", dev_name(dev), __func__, retval); } /* have the class specific function add its stuff */ if (dev->class && dev->class->dev_uevent) { retval = dev->class->dev_uevent(dev, env); if (retval) pr_debug("device: '%s': %s: class uevent() " "returned %d\n", dev_name(dev), __func__, retval); } /* have the device type specific function add its stuff */ if (dev->type && dev->type->uevent) { retval = dev->type->uevent(dev, env); if (retval) pr_debug("device: '%s': %s: dev_type uevent() " "returned %d\n", dev_name(dev), __func__, retval); } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers20350.75%945.00%
greg kroah-hartmangreg kroah-hartman17944.75%525.00%
grant likelygrant likely82.00%15.00%
alexander nybergalexander nyberg41.00%15.00%
harvey harrisonharvey harrison30.75%15.00%
al viroal viro10.25%15.00%
stefan weilstefan weil10.25%15.00%
lars-peter clausenlars-peter clausen10.25%15.00%
Total400100.00%20100.00%

static const struct kset_uevent_ops device_uevent_ops = { .filter = dev_uevent_filter, .name = dev_uevent_name, .uevent = dev_uevent, };
static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, char *buf) { struct kobject *top_kobj; struct kset *kset; struct kobj_uevent_env *env = NULL; int i; size_t count = 0; int retval; /* search the kset, the device belongs to */ top_kobj = &dev->kobj; while (!top_kobj->kset && top_kobj->parent) top_kobj = top_kobj->parent; if (!top_kobj->kset) goto out; kset = top_kobj->kset; if (!kset->uevent_ops || !kset->uevent_ops->uevent) goto out; /* respect filter */ if (kset->uevent_ops && kset->uevent_ops->filter) if (!kset->uevent_ops->filter(kset, &dev->kobj)) goto out; env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); if (!env) return -ENOMEM; /* let the kset specific function add its keys */ retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); if (retval) goto out; /* copy keys to file */ for (i = 0; i < env->envp_idx; i++) count += sprintf(&buf[count], "%s\n", env->envp[i]); out: kfree(env); return count; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers21391.42%360.00%
greg kroah-hartmangreg kroah-hartman208.58%240.00%
Total233100.00%5100.00%


static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { enum kobject_action action; if (kobject_action_type(buf, count, &action) == 0) kobject_uevent(&dev->kobj, action); else dev_err(dev, "uevent: unknown action-string\n"); return count; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers6298.41%583.33%
greg kroah-hartmangreg kroah-hartman11.59%116.67%
Total63100.00%6100.00%

static DEVICE_ATTR_RW(uevent);
static ssize_t online_show(struct device *dev, struct device_attribute *attr, char *buf) { bool val; device_lock(dev); val = !dev->offline; device_unlock(dev); return sprintf(buf, "%u\n", val); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki4998.00%266.67%
greg kroah-hartmangreg kroah-hartman12.00%133.33%
Total50100.00%3100.00%


static ssize_t online_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { bool val; int ret; ret = strtobool(buf, &val); if (ret < 0) return ret; ret = lock_device_hotplug_sysfs(); if (ret) return ret; ret = val ? device_online(dev) : device_offline(dev); unlock_device_hotplug(); return ret < 0 ? ret : count; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki8698.85%266.67%
greg kroah-hartmangreg kroah-hartman11.15%133.33%
Total87100.00%3100.00%

static DEVICE_ATTR_RW(online);
int device_add_groups(struct device *dev, const struct attribute_group **groups) { return sysfs_create_groups(&dev->kobj, groups); }

Contributors

PersonTokensPropCommitsCommitProp
dmitry torokhovdmitry torokhov1553.57%125.00%
greg kroah-hartmangreg kroah-hartman1242.86%250.00%
david brownelldavid brownell13.57%125.00%
Total28100.00%4100.00%


void device_remove_groups(struct device *dev, const struct attribute_group **groups) { sysfs_remove_groups(&dev->kobj, groups); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman2074.07%250.00%
dmitry torokhovdmitry torokhov622.22%125.00%
david brownelldavid brownell13.70%125.00%
Total27100.00%4100.00%


static int device_add_attrs(struct device *dev) { struct class *class = dev->class; const struct device_type *type = dev->type; int error; if (class) { error = device_add_groups(dev, class->dev_groups); if (error) return error; } if (type) { error = device_add_groups(dev, type->groups); if (error) goto err_remove_class_groups; } error = device_add_groups(dev, dev->groups); if (error) goto err_remove_type_groups; if (device_supports_offline(dev) && !dev->offline_disabled) { error = device_create_file(dev, &dev_attr_online); if (error) goto err_remove_dev_groups; } return 0; err_remove_dev_groups: device_remove_groups(dev, dev->groups); err_remove_type_groups: if (type) device_remove_groups(dev, type->groups); err_remove_class_groups: if (class) device_remove_groups(dev, class->dev_groups); return error; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman7341.24%444.44%
rafael j. wysockirafael j. wysocki4123.16%222.22%
dmitry torokhovdmitry torokhov3519.77%111.11%
kay sieverskay sievers2715.25%111.11%
stephen hemmingerstephen hemminger10.56%111.11%
Total177100.00%9100.00%


static void device_remove_attrs(struct device *dev) { struct class *class = dev->class; const struct device_type *type = dev->type; device_remove_file(dev, &dev_attr_online); device_remove_groups(dev, dev->groups); if (type) device_remove_groups(dev, type->groups); if (class) device_remove_groups(dev, class->dev_groups); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3547.95%337.50%
kay sieverskay sievers1723.29%112.50%
dmitry torokhovdmitry torokhov1216.44%112.50%
rafael j. wysockirafael j. wysocki79.59%112.50%
stephen hemmingerstephen hemminger11.37%112.50%
stefan achatzstefan achatz11.37%112.50%
Total73100.00%8100.00%


static ssize_t dev_show(struct device *dev, struct device_attribute *attr, char *buf) { return print_dev_t(buf, dev->devt); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman30100.00%2100.00%
Total30100.00%2100.00%

static DEVICE_ATTR_RO(dev); /* /sys/devices/ */ struct kset *devices_kset; /** * devices_kset_move_before - Move device in the devices_kset's list. * @deva: Device to move. * @devb: Device @deva should come before. */
static void devices_kset_move_before(struct device *deva, struct device *devb) { if (!devices_kset) return; pr_debug("devices_kset: Moving %s before %s\n", dev_name(deva), dev_name(devb)); spin_lock(&devices_kset->list_lock); list_move_tail(&deva->kobj.entry, &devb->kobj.entry); spin_unlock(&devices_kset->list_lock); }

Contributors

PersonTokensPropCommitsCommitProp
grygorii strashkogrygorii strashko70100.00%1100.00%
Total70100.00%1100.00%

/** * devices_kset_move_after - Move device in the devices_kset's list. * @deva: Device to move * @devb: Device @deva should come after. */
static void devices_kset_move_after(struct device *deva, struct device *devb) { if (!devices_kset) return; pr_debug("devices_kset: Moving %s after %s\n", dev_name(deva), dev_name(devb)); spin_lock(&devices_kset->list_lock); list_move(&deva->kobj.entry, &devb->kobj.entry); spin_unlock(&devices_kset->list_lock); }

Contributors

PersonTokensPropCommitsCommitProp
grygorii strashkogrygorii strashko70100.00%1100.00%
Total70100.00%1100.00%

/** * devices_kset_move_last - move the device to the end of devices_kset's list. * @dev: device to move */
void devices_kset_move_last(struct device *dev) { if (!devices_kset) return; pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); spin_lock(&devices_kset->list_lock); list_move_tail(&dev->kobj.entry, &devices_kset->list); spin_unlock(&devices_kset->list_lock); }

Contributors

PersonTokensPropCommitsCommitProp
grygorii strashkogrygorii strashko57100.00%1100.00%
Total57100.00%1100.00%

/** * device_create_file - create sysfs attribute file for device. * @dev: device. * @attr: device attribute descriptor. */
int device_create_file(struct device *dev, const struct device_attribute *attr) { int error = 0; if (dev) { WARN(((attr->attr.mode & S_IWUGO) && !attr->store), "Attribute %s: write permission without 'store'\n", attr->attr.name); WARN(((attr->attr.mode & S_IRUGO) && !attr->show), "Attribute %s: read permission without 'show'\n", attr->attr.name); error = sysfs_create_file(&dev->kobj, &attr->attr); } return error; }

Contributors

PersonTokensPropCommitsCommitProp
felipe balbifelipe balbi4443.56%125.00%
patrick mochelpatrick mochel4241.58%125.00%
dave youngdave young1413.86%125.00%
phil carmodyphil carmody10.99%125.00%
Total101100.00%4100.00%

EXPORT_SYMBOL_GPL(device_create_file); /** * device_remove_file - remove sysfs attribute file. * @dev: device. * @attr: device attribute descriptor. */
void device_remove_file(struct device *dev, const struct device_attribute *attr) { if (dev) sysfs_remove_file(&dev->kobj, &attr->attr); }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel3296.97%150.00%
phil carmodyphil carmody13.03%150.00%
Total33100.00%2100.00%

EXPORT_SYMBOL_GPL(device_remove_file); /** * device_remove_file_self - remove sysfs attribute file from its own method. * @dev: device. * @attr: device attribute descriptor. * * See kernfs_remove_self() for details. */
bool device_remove_file_self(struct device *dev, const struct device_attribute *attr) { if (dev) return sysfs_remove_file_self(&dev->kobj, &attr->attr); else return false; }

Contributors

PersonTokensPropCommitsCommitProp
tejun heotejun heo38100.00%1100.00%
Total38100.00%1100.00%

EXPORT_SYMBOL_GPL(device_remove_file_self); /** * device_create_bin_file - create sysfs binary attribute file for device. * @dev: device. * @attr: device binary attribute descriptor. */
int device_create_bin_file(struct device *dev, const struct bin_attribute *attr) { int error = -EINVAL; if (dev) error = sysfs_create_bin_file(&dev->kobj, attr); return error; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman4097.56%150.00%
phil carmodyphil carmody12.44%150.00%
Total41100.00%2100.00%

EXPORT_SYMBOL_GPL(device_create_bin_file); /** * device_remove_bin_file - remove sysfs binary attribute file * @dev: device. * @attr: device binary attribute descriptor. */
void device_remove_bin_file(struct device *dev, const struct bin_attribute *attr) { if (dev) sysfs_remove_bin_file(&dev->kobj, attr); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman2996.67%150.00%
phil carmodyphil carmody13.33%150.00%
Total30100.00%2100.00%

EXPORT_SYMBOL_GPL(device_remove_bin_file);
static void klist_children_get(struct klist_node *n) { struct device_private *p = to_device_private_parent(n); struct device *dev = p->device; get_device(dev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman1851.43%375.00%
james bottomleyjames bottomley1748.57%125.00%
Total35100.00%4100.00%


static void klist_children_put(struct klist_node *n) { struct device_private *p = to_device_private_parent(n); struct device *dev = p->device; put_device(dev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman1851.43%375.00%
james bottomleyjames bottomley1748.57%125.00%
Total35100.00%4100.00%

/** * device_initialize - init device structure. * @dev: device. * * This prepares the device for use by other layers by initializing * its fields. * It is the first half of device_register(), if called by * that function, though it can also be called separately, so one * may use @dev's fields. In particular, get_device()/put_device() * may be used for reference counting of @dev after calling this * function. * * All fields in @dev must be initialized by the caller to 0, except * for those explicitly set to some other value. The simplest * approach is to use kzalloc() to allocate the structure containing * @dev. * * NOTE: Use put_device() to give up your reference instead of freeing * @dev directly once you have called this function. */
void device_initialize(struct device *dev) { dev->kobj.kset = devices_kset; kobject_init(&dev->kobj, &device_ktype); INIT_LIST_HEAD(&dev->dma_pools); mutex_init(&dev->mutex); lockdep_set_novalidate_class(&dev->mutex); spin_lock_init(&dev->devres_lock); INIT_LIST_HEAD(&dev->devres_head); device_pm_init(dev); set_dev_node(dev, -1); #ifdef CONFIG_GENERIC_MSI_IRQ INIT_LIST_HEAD(&dev->msi_list); #endif }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel1818.95%529.41%
tejun heotejun heo1616.84%15.88%
jiang liujiang liu1313.68%15.88%
linus torvaldslinus torvalds1111.58%15.88%
greg kroah-hartmangreg kroah-hartman1111.58%423.53%
christoph hellwigchristoph hellwig88.42%15.88%
peter zijlstrapeter zijlstra88.42%15.88%
alan sternalan stern55.26%15.88%
deepak saxenadeepak saxena33.16%15.88%
thomas gleixnerthomas gleixner22.11%15.88%
Total95100.00%17100.00%

EXPORT_SYMBOL_GPL(device_initialize);
struct kobject *virtual_device_parent(struct device *dev) { static struct kobject *virtual_dir = NULL; if (!virtual_dir) virtual_dir = kobject_create_and_add("virtual", &devices_kset->kobj); return virtual_dir; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3690.00%375.00%
cornelia huckcornelia huck410.00%125.00%
Total40100.00%4100.00%

struct class_dir { struct kobject kobj; struct class *class; }; #define to_class_dir(obj) container_of(obj, struct class_dir, kobj)
static void class_dir_release(struct kobject *kobj) { struct class_dir *dir = to_class_dir(kobj); kfree(dir); }

Contributors

PersonTokensPropCommitsCommitProp
eric w. biedermaneric w. biederman26100.00%1100.00%
Total26100.00%1100.00%


static const struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj) { struct class_dir *dir = to_class_dir(kobj); return dir->class->ns_type; }

Contributors

PersonTokensPropCommitsCommitProp
eric w. biedermaneric w. biederman31100.00%1100.00%
Total31100.00%1100.00%

static struct kobj_type class_dir_ktype = { .release = class_dir_release, .sysfs_ops = &kobj_sysfs_ops, .child_ns_type = class_dir_child_ns_type };
static struct kobject * class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) { struct class_dir *dir; int retval; dir = kzalloc(sizeof(*dir), GFP_KERNEL); if (!dir) return NULL; dir->class = class; kobject_init(&dir->kobj, &class_dir_ktype); dir->kobj.kset = &class->p->glue_dirs; retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); if (retval < 0) { kobject_put(&dir->kobj); return NULL; } return &dir->kobj; }

Contributors

PersonTokensPropCommitsCommitProp
eric w. biedermaneric w. biederman11999.17%150.00%
kay sieverskay sievers10.83%150.00%
Total120100.00%2100.00%

static DEFINE_MUTEX(gdp_mutex);
static struct kobject *get_device_parent(struct device *dev, struct device *parent) { if (dev->class) { struct kobject *kobj = NULL; struct kobject *parent_kobj; struct kobject *k; #ifdef CONFIG_BLOCK /* block disks show up in /sys/block */ if (sysfs_deprecated && dev->class == &block_class) { if (parent && parent->class == &block_class) return &parent->kobj; return &block_class.p->subsys.kobj; } #endif /* * If we have no parent, we live in "virtual". * Class-devices with a non class-device as parent, live * in a "glue" directory to prevent namespace collisions. */ if (parent == NULL) parent_kobj = virtual_device_parent(dev); else if (parent->class && !dev->class->ns_type) return &parent->kobj; else parent_kobj = &parent->kobj; mutex_lock(&gdp_mutex); /* find our class-directory at the parent and reference it */ spin_lock(&dev->class->p->glue_dirs.list_lock); list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) if (k->parent == parent_kobj) { kobj = kobject_get(k); break; } spin_unlock(&dev->class->p->glue_dirs.list_lock); if (kobj) { mutex_unlock(&gdp_mutex); return kobj; } /* or create a new class-directory at the parent device */ k = class_dir_create_and_add(dev->class, parent_kobj); /* do not emit an uevent for this simple "glue" directory */ mutex_unlock(&gdp_mutex); return k; } /* subsystems can specify a default root directory for their devices */ if (!parent && dev->bus && dev->bus->dev_root) return &dev->bus->dev_root->kobj; if (parent) return &parent->kobj; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers17866.42%533.33%
greg kroah-hartmangreg kroah-hartman3814.18%320.00%
tejun heotejun heo217.84%16.67%
cornelia huckcornelia huck155.60%16.67%
eric w. biedermaneric w. biederman82.99%213.33%
randy dunlaprandy dunlap51.87%16.67%
andi kleenandi kleen20.75%16.67%
adrian bunkadrian bunk10.37%16.67%
Total268100.00%15100.00%


static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) { /* see if we live in a "glue" directory */ if (!glue_dir || !dev->class || glue_dir->kset != &dev->class->p->glue_dirs) return; mutex_lock(&gdp_mutex); kobject_put(glue_dir); mutex_unlock(&gdp_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers3763.79%342.86%
wang yijingwang yijing1220.69%114.29%
cornelia huckcornelia huck712.07%228.57%
greg kroah-hartmangreg kroah-hartman23.45%114.29%
Total58100.00%7100.00%


static void cleanup_device_parent(struct device *dev) { cleanup_glue_dir(dev, dev->kobj.parent); }

Contributors

PersonTokensPropCommitsCommitProp
cornelia huckcornelia huck22100.00%1100.00%
Total22100.00%1100.00%


static int device_add_class_symlinks(struct device *dev) { struct device_node *of_node = dev_of_node(dev); int error; if (of_node) { error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node"); if (error) dev_warn(dev, "Error %d creating of_node link\n",error); /* An error here doesn't warrant bringing down the device */ } if (!dev->class) return 0; error = sysfs_create_link(&dev->kobj, &dev->class->p->subsys.kobj, "subsystem"); if (error) goto out_devnode; if (dev->parent && device_is_not_partition(dev)) { error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); if (error) goto out_subsys; } #ifdef CONFIG_BLOCK /* /sys/block has directories and does not need symlinks */ if (sysfs_deprecated && dev->class == &block_class) return 0; #endif /* link in the class directory pointing to the device */ error = sysfs_create_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); if (error) goto out_device; return 0; out_device: sysfs_remove_link(&dev->kobj, "device"); out_subsys: sysfs_remove_link(&dev->kobj, "subsystem"); out_devnode: sysfs_remove_link(&dev->kobj, "of_node"); return error; }

Contributors

PersonTokensPropCommitsCommitProp
cornelia huckcornelia huck10142.80%18.33%
kay sieverskay sievers6025.42%541.67%
benjamin herrenschmidtbenjamin herrenschmidt5925.00%18.33%
greg kroah-hartmangreg kroah-hartman72.97%216.67%
randy dunlaprandy dunlap52.12%18.33%
andi kleenandi kleen20.85%18.33%
eric w. biedermaneric w. biederman20.85%18.33%
Total236100.00%12100.00%


static void device_remove_class_symlinks(struct device *dev) { if (dev_of_node(dev)) sysfs_remove_link(&dev->kobj, "of_node"); if (!dev->class) return; if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "subsystem"); #ifdef CONFIG_BLOCK if (sysfs_deprecated && dev->class == &block_class) return; #endif sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers6358.33%541.67%
benjamin herrenschmidtbenjamin herrenschmidt1715.74%18.33%
cornelia huckcornelia huck109.26%18.33%
eric w. biedermaneric w. biederman65.56%18.33%
greg kroah-hartmangreg kroah-hartman54.63%216.67%
randy dunlaprandy dunlap54.63%18.33%
andi kleenandi kleen21.85%18.33%
Total108100.00%12100.00%

/** * dev_set_name - set a device name * @dev: device * @fmt: format string for the device's name */
int dev_set_name(struct device *dev, const char *fmt, ...) { va_list vargs; int err; va_start(vargs, fmt); err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); va_end(vargs); return err; }

Contributors

PersonTokensPropCommitsCommitProp
stephen rothwellstephen rothwell4382.69%133.33%
kay sieverskay sievers815.38%133.33%
roland dreierroland dreier11.92%133.33%
Total52100.00%3100.00%

EXPORT_SYMBOL_GPL(dev_set_name); /** * device_to_dev_kobj - select a /sys/dev/ directory for the device * @dev: device * * By default we select char/ for new entries. Setting class->dev_obj * to NULL prevents an entry from being created. class->dev_kobj must * be set (or cleared) before any devices are registered to the class * otherwise device_create_sys_dev_entry() and * device_remove_sys_dev_entry() will disagree about the presence of * the link. */
static struct kobject *device_to_dev_kobj(struct device *dev) { struct kobject *kobj; if (dev->class) kobj = dev->class->dev_kobj; else kobj = sysfs_dev_char_kobj; return kobj; }

Contributors

PersonTokensPropCommitsCommitProp
dan williamsdan williams40100.00%1100.00%
Total40100.00%1100.00%


static int device_create_sys_dev_entry(struct device *dev) { struct kobject *kobj = device_to_dev_kobj(dev); int error = 0; char devt_str[15]; if (kobj) { format_dev_t(devt_str, dev->devt); error = sysfs_create_link(kobj, &dev->kobj, devt_str); } return error; }

Contributors

PersonTokensPropCommitsCommitProp
dan williamsdan williams64100.00%1100.00%
Total64100.00%1100.00%


static void device_remove_sys_dev_entry(struct device *dev) { struct kobject *kobj = device_to_dev_kobj(dev); char devt_str[15]; if (kobj) { format_dev_t(devt_str, dev->devt); sysfs_remove_link(kobj, devt_str); } }

Contributors

PersonTokensPropCommitsCommitProp
dan williamsdan williams49100.00%1100.00%
Total49100.00%1100.00%


int device_private_init(struct device *dev) { dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); if (!dev->p) return -ENOMEM; dev->p->device = dev; klist_init(&dev->p->klist_children, klist_children_get, klist_children_put); INIT_LIST_HEAD(&dev->p->deferred_probe); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman73100.00%2100.00%
Total73100.00%2100.00%

/** * device_add - add device to device hierarchy. * @dev: device. * * This is part 2 of device_register(), though may be called * separately _iff_ device_initialize() has been called separately. * * This adds @dev to the kobject hierarchy via kobject_add(), adds it * to the global and sibling lists for the device, then * adds it to the other relevant subsystems of the driver model. * * Do not call this routine or device_register() more than once for * any device structure. The driver model core is not designed to work * with devices that get unregistered and then spring back to life. * (Among other things, it's very hard to guarantee that all references * to the previous incarnation of @dev have been dropped.) Allocate * and register a fresh new struct device instead. * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up your * reference instead. */
int device_add(struct device *dev) { struct device *parent = NULL; struct kobject *kobj; struct class_interface *class_intf; int error = -EINVAL; dev = get_device(dev); if (!dev) goto done; if (!dev->p) { error = device_private_init(dev); if (error) goto done; } /* * for statically allocated devices, which should all be converted * some day, we need to initialize the name. We prevent reading back * the name, and force the use of dev_name() */ if (dev->init_name) { dev_set_name(dev, "%s", dev->init_name); dev->init_name = NULL; } /* subsystems can specify simple device enumeration */ if (!dev_name(dev) && dev->bus && dev->bus->dev_name) dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); if (!dev_name(dev)) { error = -EINVAL; goto name_error; } pr_debug("device: '%s': %s\n", dev_name(dev), __func__); parent = get_device(dev->parent); kobj = get_device_parent(dev, parent); if (kobj) dev->kobj.parent = kobj; /* use parent numa_node */ if (parent && (dev_to_node(dev) == NUMA_NO_NODE)) set_dev_node(dev, dev_to_node(parent)); /* first, register with generic layer. */ /* we require the name to be set before, and pass NULL */ error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); if (error) goto Error; /* notify platform of device entry */ if (platform_notify) platform_notify(dev); error = device_create_file(dev, &dev_attr_uevent); if (error) goto attrError; error = device_add_class_symlinks(dev); if (error) goto SymlinkError; error = device_add_attrs(dev); if (error) goto AttrsError; error = bus_add_device(dev); if (error) goto BusError; error = dpm_sysfs_add(dev); if (error) goto DPMError; device_pm_add(dev); if (MAJOR(dev->devt)) { error = device_create_file(dev, &dev_attr_dev); if (error) goto DevAttrError; error = device_create_sys_dev_entry(dev); if (error) goto SysEntryError; devtmpfs_create_node(dev); } /* Notify clients of device addition. This call must come * after dpm_sysfs_add() and before kobject_uevent(). */ if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_ADD_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_ADD); bus_probe_device(dev); if (parent) klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children); if (dev->class) { mutex_lock(&dev->class->p->mutex); /* tie the class to the device */ klist_add_tail(&dev->knode_class, &dev->class->p->klist_devices); /* notify any interfaces that the device is here */ list_for_each_entry(class_intf, &dev->class->p->interfaces, node) if (class_intf->add_dev) class_intf->add_dev(dev, class_intf); mutex_unlock(&dev->class->p->mutex); } done: put_device(dev); return error; SysEntryError: if (MAJOR(dev->devt)) device_remove_file(dev, &dev_attr_dev); DevAttrError: device_pm_remove(dev); dpm_sysfs_remove(dev); DPMError: bus_remove_device(dev); BusError: device_remove_attrs(dev); AttrsError: device_remove_class_symlinks(dev); SymlinkError: device_remove_file(dev, &dev_attr_uevent); attrError: kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); Error: cleanup_device_parent(dev); put_device(parent); name_error: kfree(dev->p); dev->p = NULL; goto done; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman20532.33%1727.42%
kay sieverskay sievers12219.24%1016.13%
patrick mochelpatrick mochel9615.14%1016.13%
sergey klyaussergey klyaus568.83%11.61%
cornelia huckcornelia huck416.47%69.68%
alan sternalan stern274.26%34.84%
dan williamsdan williams203.15%11.61%
yinghai luyinghai lu152.37%11.61%
brian walshbrian walsh101.58%11.61%
tejun heotejun heo101.58%34.84%
zhen leizhen lei91.42%11.61%
thomas gleixnerthomas gleixner71.10%11.61%
linus torvaldslinus torvalds60.95%11.61%
james bottomleyjames bottomley40.63%11.61%
dave youngdave young20.32%11.61%
ma jianpengma jianpeng10.16%11.61%
frank a. ueppingfrank a. uepping10.16%11.61%
al viroal viro10.16%11.61%
harvey harrisonharvey harrison10.16%11.61%
Total634100.00%62100.00%

EXPORT_SYMBOL_GPL(device_add); /** * device_register - register a device with the system. * @dev: pointer to the device structure * * This happens in two clean steps - initialize the device * and add it to the system. The two steps can be called * separately, but this is the easiest and most common. * I.e. you should only call the two helpers separately if * have a clearly defined need to use and refcount the device * before it is added to the hierarchy. * * For more information, see the kerneldoc for device_initialize() * and device_add(). * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up the * reference initialized in this function instead. */
int device_register(struct device *dev) { device_initialize(dev); return device_add(dev); }

Contributors

PersonTokensPropCommitsCommitProp
al viroal viro1885.71%133.33%
linus torvaldslinus torvalds29.52%133.33%
patrick mochelpatrick mochel14.76%133.33%
Total21100.00%3100.00%

EXPORT_SYMBOL_GPL(device_register); /** * get_device - increment reference count for device. * @dev: device. * * This simply forwards the call to kobject_get(), though * we do take care to provide for the case that we get a NULL * pointer passed in. */
struct device *get_device(struct device *dev) { return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel2796.43%480.00%
lars-peter clausenlars-peter clausen13.57%120.00%
Total28100.00%5100.00%

EXPORT_SYMBOL_GPL(get_device); /** * put_device - decrement reference count. * @dev: device in question. */
void put_device(struct device *dev) { /* might_sleep(); */ if (dev) kobject_put(&dev->kobj); }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds1460.87%125.00%
hannes reineckehannes reinecke417.39%125.00%
patrick mochelpatrick mochel417.39%125.00%
kay sieverskay sievers14.35%125.00%
Total23100.00%4100.00%

EXPORT_SYMBOL_GPL(put_device); /** * device_del - delete device from system. * @dev: device. * * This is the first part of the device unregistration * sequence. This removes the device from the lists we control * from here, has it removed from the other driver model * subsystems it was added to in device_add(), and removes it * from the kobject hierarchy. * * NOTE: this should be called manually _iff_ device_add() was * also called manually. */
void device_del(struct device *dev) { struct device *parent = dev->parent; struct class_interface *class_intf; /* Notify clients of device removal. This call must come * before dpm_sysfs_remove(). */ if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); dpm_sysfs_remove(dev); if (parent) klist_del(&dev->p->knode_parent); if (MAJOR(dev->devt)) { devtmpfs_delete_node(dev); device_remove_sys_dev_entry(dev); device_remove_file(dev, &dev_attr_dev); } if (dev->class) { device_remove_class_symlinks(dev); mutex_lock(&dev->class->p->mutex); /* notify any interfaces that the device is now gone */ list_for_each_entry(class_intf, &dev->class->p->interfaces, node) if (class_intf->remove_dev) class_intf->remove_dev(dev, class_intf); /* remove the device from the class list */ klist_del(&dev->knode_class); mutex_unlock(&dev->class->p->mutex); } device_remove_file(dev, &dev_attr_uevent); device_remove_attrs(dev); bus_remove_device(dev); device_pm_remove(dev); driver_deferred_probe_del(dev); /* Notify the platform of the removal, in case they * need to do anything... */ if (platform_notify_remove) platform_notify_remove(dev); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_REMOVED_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_REMOVE); cleanup_device_parent(dev); kobject_del(&dev->kobj); put_device(parent); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman8332.81%822.86%
patrick mochelpatrick mochel4116.21%720.00%
kay sieverskay sievers3313.04%720.00%
alan sternalan stern2811.07%25.71%
joerg roedeljoerg roedel228.70%12.86%
linus torvaldslinus torvalds124.74%12.86%
tejun heotejun heo72.77%25.71%
dan williamsdan williams72.77%12.86%
grant likelygrant likely51.98%12.86%
benjamin herrenschmidtbenjamin herrenschmidt51.98%12.86%
longx zhanglongx zhang51.98%12.86%
dave youngdave young20.79%12.86%
catalin marinascatalin marinas20.79%12.86%
al viroal viro10.40%12.86%
Total253100.00%35100.00%

EXPORT_SYMBOL_GPL(device_del); /** * device_unregister - unregister device from system. * @dev: device going away. * * We do this in two parts, like we do device_register(). First, * we remove it from all the subsystems with device_del(), then * we decrement the reference count via put_device(). If that * is the final reference count, the device will be cleaned up * via device_release() above. Otherwise, the structure will * stick around until the final reference to the device is dropped. */
void device_unregister(struct device *dev) { pr_debug("device: '%s': %s\n", dev_name(dev), __func__); device_del(dev); put_device(dev); }

Contributors

PersonTokensPropCommitsCommitProp
al viroal viro1237.50%111.11%
patrick mochelpatrick mochel928.12%444.44%
linus torvaldslinus torvalds515.62%111.11%
kay sieverskay sievers39.38%111.11%
greg kroah-hartmangreg kroah-hartman26.25%111.11%
harvey harrisonharvey harrison13.12%111.11%
Total32100.00%9100.00%

EXPORT_SYMBOL_GPL(device_unregister);
static struct device *prev_device(struct klist_iter *i) { struct klist_node *n = klist_prev(i); struct device *dev = NULL; struct device_private *p; if (n) { p = to_device_private_parent(n); dev = p->device; } return dev; }

Contributors

PersonTokensPropCommitsCommitProp
andy shevchenkoandy shevchenko57100.00%1100.00%
Total57100.00%1100.00%


static struct device *next_device(struct klist_iter *i) { struct klist_node *n = klist_next(i); struct device *dev = NULL; struct device_private *p; if (n) { p = to_device_private_parent(n); dev = p->device; } return dev; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3052.63%266.67%
patrick mochelpatrick mochel2747.37%133.33%
Total57100.00%3100.00%

/** * device_get_devnode - path of device node file * @dev: device * @mode: returned file access mode * @uid: returned file owner * @gid: returned file group * @tmp: possibly allocated string * * Return the relative path of a possible device node. * Non-default names may need to allocate a memory to compose * a name. This memory is returned in tmp and needs to be * freed by the caller. */
const char *device_get_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid, const char **tmp) { char *s; *tmp = NULL; /* the device type may provide a specific name */ if (dev->type && dev->type->devnode) *tmp = dev->type->devnode(dev, mode, uid, gid); if (*tmp) return *tmp; /* the class may provide a specific name */ if (dev->class && dev->class->devnode) *tmp = dev->class->devnode(dev, mode); if (*tmp) return *tmp; /* return name without allocation, tmp == NULL */ if (strchr(dev_name(dev), '!') == NULL) return dev_name(dev); /* replace '!' in the name with '/' */ s = kstrdup(dev_name(dev), GFP_KERNEL); if (!s) return NULL; strreplace(s, '!', '/'); return *tmp = s; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers16193.60%350.00%
rasmus villemoesrasmus villemoes84.65%116.67%
greg kroah-hartmangreg kroah-hartman21.16%116.67%
al viroal viro10.58%116.67%
Total172100.00%6100.00%

/** * device_for_each_child - device child iterator. * @parent: parent struct device. * @fn: function to be called for each device. * @data: data for the callback. * * Iterate over @parent's child devices, and call @fn for each, * passing it @data. * * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. */
int device_for_each_child(struct device *parent, void *data, int (*fn)(struct device *dev, void *data)) { struct klist_iter i; struct device *child; int error = 0; if (!parent->p) return 0; klist_iter_init(&parent->p->klist_children, &i); while ((child = next_device(&i)) && !error) error = fn(child, data); klist_iter_exit(&i); return error; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel8686.00%240.00%
greg kroah-hartmangreg kroah-hartman1414.00%360.00%
Total100100.00%5100.00%

EXPORT_SYMBOL_GPL(device_for_each_child); /** * device_for_each_child_reverse - device child iterator in reversed order. * @parent: parent struct device. * @fn: function to be called for each device. * @data: data for the callback. * * Iterate over @parent's child devices, and call @fn for each, * passing it @data. * * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. */
int device_for_each_child_reverse(struct device *parent, void *data, int (*fn)(struct device *dev, void *data)) { struct klist_iter i; struct device *child; int error = 0; if (!parent->p) return 0; klist_iter_init(&parent->p->klist_children, &i); while ((child = prev_device(&i)) && !error) error = fn(child, data); klist_iter_exit(&i); return error; }

Contributors

PersonTokensPropCommitsCommitProp
andy shevchenkoandy shevchenko100100.00%1100.00%
Total100100.00%1100.00%

EXPORT_SYMBOL_GPL(device_for_each_child_reverse); /** * device_find_child - device iterator for locating a particular device. * @parent: parent struct device * @match: Callback function to check device * @data: Data to pass to match function * * This is similar to the device_for_each_child() function above, but it * returns a reference to a device that is 'found' for later use, as * determined by the @match callback. * * The callback should return 0 if the device doesn't match and non-zero * if it does. If the callback returns non-zero and a reference to the * current device can be obtained, this function will return to the caller * and not iterate over any more devices. * * NOTE: you will need to drop the reference with put_device() after use. */
struct device *device_find_child(struct device *parent, void *data, int (*match)(struct device *dev, void *data)) { struct klist_iter i; struct device *child; if (!parent) return NULL; klist_iter_init(&parent->p->klist_children, &i); while ((child = next_device(&i))) if (match(child, data) && get_device(child)) break; klist_iter_exit(&i); return child; }

Contributors

PersonTokensPropCommitsCommitProp
cornelia huckcornelia huck9495.92%133.33%
greg kroah-hartmangreg kroah-hartman44.08%266.67%
Total98100.00%3100.00%

EXPORT_SYMBOL_GPL(device_find_child);
int __init devices_init(void) { devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); if (!devices_kset) return -ENOMEM; dev_kobj = kobject_create_and_add("dev", NULL); if (!dev_kobj) goto dev_kobj_err; sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); if (!sysfs_dev_block_kobj) goto block_kobj_err; sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); if (!sysfs_dev_char_kobj) goto char_kobj_err; return 0; char_kobj_err: kobject_put(sysfs_dev_block_kobj); block_kobj_err: kobject_put(dev_kobj); dev_kobj_err: kset_unregister(devices_kset); return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
dan williamsdan williams7670.37%125.00%
greg kroah-hartmangreg kroah-hartman2018.52%125.00%
patrick mochelpatrick mochel1211.11%250.00%
Total108100.00%4100.00%


static int device_check_offline(struct device *dev, void *not_used) { int ret; ret = device_for_each_child(dev, NULL, device_check_offline); if (ret) return ret; return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki52100.00%1100.00%
Total52100.00%1100.00%

/** * device_offline - Prepare the device for hot-removal. * @dev: Device to be put offline. * * Execute the device bus type's .offline() callback, if present, to prepare * the device for a subsequent hot-removal. If that succeeds, the device must * not be used until either it is removed or its bus type's .online() callback * is executed. * * Call under device_hotplug_lock. */
int device_offline(struct device *dev) { int ret; if (dev->offline_disabled) return -EPERM; ret = device_for_each_child(dev, NULL, device_check_offline); if (ret) return ret; device_lock(dev); if (device_supports_offline(dev)) { if (dev->offline) { ret = 1; } else { ret = dev->bus->offline(dev); if (!ret) { kobject_uevent(&dev->kobj, KOBJ_OFFLINE); dev->offline = true; } } } device_unlock(dev); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki112100.00%1100.00%
Total112100.00%1100.00%

/** * device_online - Put the device back online after successful device_offline(). * @dev: Device to be put back online. * * If device_offline() has been successfully executed for @dev, but the device * has not been removed subsequently, execute its bus type's .online() callback * to indicate that the device can be used again. * * Call under device_hotplug_lock. */
int device_online(struct device *dev) { int ret = 0; device_lock(dev); if (device_supports_offline(dev)) { if (dev->offline) { ret = dev->bus->online(dev); if (!ret) { kobject_uevent(&dev->kobj, KOBJ_ONLINE); dev->offline = false; } } else { ret = 1; } } device_unlock(dev); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki86100.00%1100.00%
Total86100.00%1100.00%

struct root_device { struct device dev; struct module *owner; };
static inline struct root_device *to_root_device(struct device *d) { return container_of(d, struct root_device, dev); }

Contributors

PersonTokensPropCommitsCommitProp
wagner ferencwagner ferenc2184.00%133.33%
mark mcloughlinmark mcloughlin312.00%133.33%
josh triplettjosh triplett14.00%133.33%
Total25100.00%3100.00%


static void root_device_release(struct device *dev) { kfree(to_root_device(dev)); }

Contributors

PersonTokensPropCommitsCommitProp
mark mcloughlinmark mcloughlin19100.00%1100.00%
Total19100.00%1100.00%

/** * __root_device_register - allocate and register a root device * @name: root device name * @owner: owner module of the root device, usually THIS_MODULE * * This function allocates a root device and registers it * using device_register(). In order to free the returned * device, use root_device_unregister(). * * Root devices are dummy devices which allow other devices * to be grouped under /sys/devices. Use this function to * allocate a root device and then use it as the parent of * any device which should appear under /sys/devices/{name} * * The /sys/devices/{name} directory will also contain a * 'module' symlink which points to the @owner directory * in sysfs. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: You probably want to use root_device_register(). */
struct device *__root_device_register(const char *name, struct module *owner) { struct root_device *root; int err = -ENOMEM; root = kzalloc(sizeof(struct root_device), GFP_KERNEL); if (!root) return ERR_PTR(err); err = dev_set_name(&root->dev, "%s", name); if (err) { kfree(root); return ERR_PTR(err); } root->dev.release = root_device_release; err = device_register(&root->dev); if (err) { put_device(&root->dev); return ERR_PTR(err); } #ifdef CONFIG_MODULES /* gotta find a "cleaner" way to do this */ if (owner) { struct module_kobject *mk = &owner->mkobj; err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module"); if (err) { device_unregister(&root->dev); return ERR_PTR(err); } root->owner = owner; } #endif return &root->dev; }

Contributors

PersonTokensPropCommitsCommitProp
mark mcloughlinmark mcloughlin19198.45%133.33%
greg kroah-hartmangreg kroah-hartman21.03%133.33%
christoph eggerchristoph egger10.52%133.33%
Total194100.00%3100.00%

EXPORT_SYMBOL_GPL(__root_device_register); /** * root_device_unregister - unregister and free a root device * @dev: device going away * * This function unregisters and cleans up a device that was created by * root_device_register(). */
void root_device_unregister(struct device *dev) { struct root_device *root = to_root_device(dev); if (root->owner) sysfs_remove_link(&root->dev.kobj, "module"); device_unregister(dev); }

Contributors

PersonTokensPropCommitsCommitProp
mark mcloughlinmark mcloughlin43100.00%1100.00%
Total43100.00%1100.00%

EXPORT_SYMBOL_GPL(root_device_unregister);
static void device_create_release(struct device *dev) { pr_debug("device: '%s': %s\n", dev_name(dev), __func__); kfree(dev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman2485.71%250.00%
kay sieverskay sievers310.71%125.00%
harvey harrisonharvey harrison13.57%125.00%
Total28100.00%4100.00%


static struct device * device_create_groups_vargs(struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, va_list args) { struct device *dev = NULL; int retval = -ENODEV; if (class == NULL || IS_ERR(class)) goto error; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { retval = -ENOMEM; goto error; } device_initialize(dev); dev->devt = devt; dev->class = class; dev->parent = parent; dev->groups = groups; dev->release = device_create_release; dev_set_drvdata(dev, drvdata); retval = kobject_set_name_vargs(&dev->kobj, fmt, args); if (retval) goto error; retval = device_add(dev); if (retval) goto error; return dev; error: put_device(dev); return ERR_PTR(retval); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman15481.91%342.86%
guenter roeckguenter roeck157.98%114.29%
kay sieverskay sievers126.38%114.29%
david herrmanndavid herrmann63.19%114.29%
cornelia huckcornelia huck10.53%114.29%
Total188100.00%7100.00%

/** * device_create_vargs - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @fmt: string for the device's name * @args: va_list for the device's name * * This function can be used by char device classes. A struct device * will be created in sysfs, registered to the specified class. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */
struct device *device_create_vargs(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, va_list args) { return device_create_groups_vargs(class, parent, devt, drvdata, NULL, fmt, args); }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck50100.00%1100.00%
Total50100.00%1100.00%

EXPORT_SYMBOL_GPL(device_create_vargs); /** * device_create - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @fmt: string for the device's name * * This function can be used by char device classes. A struct device * will be created in sysfs, registered to the specified class. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) { va_list vargs; struct device *dev; va_start(vargs, fmt); dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); va_end(vargs); return dev; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman71100.00%2100.00%
Total71100.00%2100.00%

EXPORT_SYMBOL_GPL(device_create); /** * device_create_with_groups - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @groups: NULL-terminated list of attribute groups to be created * @fmt: string for the device's name * * This function can be used by char device classes. A struct device * will be created in sysfs, registered to the specified class. * Additional attributes specified in the groups parameter will also * be created automatically. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */
struct device *device_create_with_groups(struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...) { va_list vargs; struct device *dev; va_start(vargs, fmt); dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, fmt, vargs); va_end(vargs); return dev; }

Contributors

PersonTokensPropCommitsCommitProp
guenter roeckguenter roeck80100.00%1100.00%
Total80100.00%1100.00%

EXPORT_SYMBOL_GPL(device_create_with_groups);
static int __match_devt(struct device *dev, const void *data) { const dev_t *devt = data; return dev->devt == *devt; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman1341.94%125.00%
dave youngdave young1341.94%125.00%
rafael j. wysockirafael j. wysocki39.68%125.00%
michal miroslawmichal miroslaw26.45%125.00%
Total31100.00%4100.00%

/** * device_destroy - removes a device that was created with device_create() * @class: pointer to the struct class that this device was registered with * @devt: the dev_t of the device that was previously registered * * This call unregisters and cleans up a device that was created with a * call to device_create(). */
void device_destroy(struct class *class, dev_t devt) { struct device *dev; dev = class_find_device(class, NULL, &devt, __match_devt); if (dev) { put_device(dev); device_unregister(dev); } }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki2552.08%125.00%
greg kroah-hartmangreg kroah-hartman1225.00%250.00%
dave youngdave young1122.92%125.00%
Total48100.00%4100.00%

EXPORT_SYMBOL_GPL(device_destroy); /** * device_rename - renames a device * @dev: the pointer to the struct device to be renamed * @new_name: the new name of the device * * It is the responsibility of the caller to provide mutual * exclusion between two different calls of device_rename * on the same device to ensure that new_name is valid and * won't conflict with other devices. * * Note: Don't call this function. Currently, the networking layer calls this * function, but that will change. The following text from Kay Sievers offers * some insight: * * Renaming devices is racy at many levels, symlinks and other stuff are not * replaced atomically, and you get a "move" uevent, but it's not easy to * connect the event to the old and new device. Device nodes are not renamed at * all, there isn't even support for that in the kernel now. * * In the meantime, during renaming, your target name might be taken by another * driver, creating conflicts. Or the old name is taken directly after you * renamed it -- then you get events for the same DEVPATH, before you even see * the "move" event. It's just a mess, and nothing new should ever rely on * kernel device renaming. Besides that, it's not even implemented now for * other things than (driver-core wise very simple) network devices. * * We are currently about to change network renaming in udev to completely * disallow renaming of devices in the same namespace as the kernel uses, * because we can't solve the problems properly, that arise with swapping names * of multiple interfaces without races. Means, renaming of eth[0-9]* will only * be allowed to some other name than eth[0-9]*, for the aforementioned * reasons. * * Make up a "real" name in the driver before you register anything, or add * some other attributes for userspace to find the device, or use udev to add * symlinks -- but never rename kernel devices later, it's a complete mess. We * don't even want to get into that and try to implement the missing pieces in * the core. We really have other pieces to fix in the driver core mess. :) */
int device_rename(struct device *dev, const char *new_name) { struct kobject *kobj = &dev->kobj; char *old_device_name = NULL; int error; dev = get_device(dev); if (!dev) return -EINVAL; dev_dbg(dev, "renaming to %s\n", new_name); old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); if (!old_device_name) { error = -ENOMEM; goto out; } if (dev->class) { error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj, kobj, old_device_name, new_name, kobject_namespace(kobj)); if (error) goto out; } error = kobject_rename(kobj, new_name); if (error) goto out; out: put_device(dev); kfree(old_device_name); return error; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman7748.43%218.18%
eric w. biedermaneric w. biederman3522.01%19.09%
tejun heotejun heo1610.06%19.09%
cornelia huckcornelia huck148.81%19.09%
kay sieverskay sievers74.40%327.27%
jesper juhljesper juhl74.40%19.09%
ethan zhaoethan zhao21.26%19.09%
johannes bergjohannes berg10.63%19.09%
Total159100.00%11100.00%

EXPORT_SYMBOL_GPL(device_rename);
static int device_move_class_links(struct device *dev, struct device *old_parent, struct device *new_parent) { int error = 0; if (old_parent) sysfs_remove_link(&dev->kobj, "device"); if (new_parent) error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); return error; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3859.38%150.00%
cornelia huckcornelia huck2640.62%150.00%
Total64100.00%2100.00%

/** * device_move - moves a device to a new parent * @dev: the pointer to the struct device to be moved * @new_parent: the new parent of the device (can by NULL) * @dpm_order: how to reorder the dpm_list */
int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order) { int error; struct device *old_parent; struct kobject *new_parent_kobj; dev = get_device(dev); if (!dev) return -EINVAL; device_pm_lock(); new_parent = get_device(new_parent); new_parent_kobj = get_device_parent(dev, new_parent); pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), __func__, new_parent ? dev_name(new_parent) : "<NULL>"); error = kobject_move(&dev->kobj, new_parent_kobj); if (error) { cleanup_glue_dir(dev, new_parent_kobj); put_device(new_parent); goto out; } old_parent = dev->parent; dev->parent = new_parent; if (old_parent) klist_remove(&dev->p->knode_parent); if (new_parent) { klist_add_tail(&dev->p->knode_parent, &new_parent->p->klist_children); set_dev_node(dev, dev_to_node(new_parent)); } if (dev->class) { error = device_move_class_links(dev, old_parent, new_parent); if (error) { /* We ignore errors on cleanup since we're hosed anyway... */ device_move_class_links(dev, new_parent, old_parent); if (!kobject_move(&dev->kobj, &old_parent->kobj)) { if (new_parent) klist_remove(&dev->p->knode_parent); dev->parent = old_parent; if (old_parent) { klist_add_tail(&dev->p->knode_parent, &old_parent->p->klist_children); set_dev_node(dev, dev_to_node(old_parent)); } } cleanup_glue_dir(dev, new_parent_kobj); put_device(new_parent); goto out; } } switch (dpm_order) { case DPM_ORDER_NONE: break; case DPM_ORDER_DEV_AFTER_PARENT: device_pm_move_after(dev, new_parent); devices_kset_move_after(dev, new_parent); break; case DPM_ORDER_PARENT_BEFORE_DEV: device_pm_move_before(new_parent, dev); devices_kset_move_before(new_parent, dev); break; case DPM_ORDER_DEV_LAST: device_pm_move_last(dev); devices_kset_move_last(dev); break; } put_device(old_parent); out: device_pm_unlock(); put_device(dev); return error; }

Contributors

PersonTokensPropCommitsCommitProp
cornelia huckcornelia huck30781.00%541.67%
yinghai luyinghai lu307.92%18.33%
grygorii strashkogrygorii strashko195.01%18.33%
greg kroah-hartmangreg kroah-hartman143.69%216.67%
kay sieverskay sievers61.58%18.33%
rabin vincentrabin vincent20.53%18.33%
harvey harrisonharvey harrison10.26%18.33%
Total379100.00%12100.00%

EXPORT_SYMBOL_GPL(device_move); /** * device_shutdown - call ->shutdown() on each device to shutdown. */
void device_shutdown(void) { struct device *dev, *parent; spin_lock(&devices_kset->list_lock); /* * Walk the devices list backward, shutting down each in turn. * Beware that device unplug events may also start pulling * devices offline, even as the system is shutting down. */ while (!list_empty(&devices_kset->list)) { dev = list_entry(devices_kset->list.prev, struct device, kobj.entry); /* * hold reference count of device's parent to * prevent it from being freed because parent's * lock is to be held */ parent = get_device(dev->parent); get_device(dev); /* * Make sure the device is off the kset list, in the * event that dev->*->shutdown() doesn't remove it. */ list_del_init(&dev->kobj.entry); spin_unlock(&devices_kset->list_lock); /* hold lock to avoid race with probe/release */ if (parent) device_lock(parent); device_lock(dev); /* Don't allow any more runtime suspends */ pm_runtime_get_noresume(dev); pm_runtime_barrier(dev); if (dev->bus && dev->bus->shutdown) { if (initcall_debug) dev_info(dev, "shutdown\n"); dev->bus->shutdown(dev); } else if (dev->driver && dev->driver->shutdown) { if (initcall_debug) dev_info(dev, "shutdown\n"); dev->driver->shutdown(dev); } device_unlock(dev); if (parent) device_unlock(parent); put_device(dev); put_device(parent); spin_lock(&devices_kset->list_lock); } spin_unlock(&devices_kset->list_lock); }

Contributors

PersonTokensPropCommitsCommitProp
hugh daschbachhugh daschbach8035.71%114.29%
greg kroah-hartmangreg kroah-hartman7633.93%114.29%
ming leiming lei4218.75%114.29%
liu shuoxliu shuox104.46%114.29%
alan sternalan stern73.12%114.29%
benson leungbenson leung52.23%114.29%
peter chenpeter chen41.79%114.29%
Total224100.00%7100.00%

/* * Device logging functions */ #ifdef CONFIG_PRINTK
static int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) { const char *subsys; size_t pos = 0; if (dev->class) subsys = dev->class->name; else if (dev->bus) subsys = dev->bus->name; else return 0; pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys); if (pos >= hdrlen) goto overflow; /* * Add device identifier DEVICE=: * b12:8 block dev_t * c127:3 char dev_t * n8 netdev ifindex * +sound:card0 subsystem:devname */ if (MAJOR(dev->devt)) { char c; if (strcmp(subsys, "block") == 0) c = 'b'; else c = 'c'; pos++; pos += snprintf(hdr + pos, hdrlen - pos, "DEVICE=%c%u:%u", c, MAJOR(dev->devt), MINOR(dev->devt)); } else if (strcmp(subsys, "net") == 0) { struct net_device *net = to_net_dev(dev); pos++; pos += snprintf(hdr + pos, hdrlen - pos, "DEVICE=n%u", net->ifindex); } else { pos++; pos += snprintf(hdr + pos, hdrlen - pos, "DEVICE=+%s:%s", subsys, dev_name(dev)); } if (pos >= hdrlen) goto overflow; return pos; overflow: dev_WARN(dev, "device/subsystem name too long"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
kay sieverskay sievers17167.06%116.67%
joe perchesjoe perches5019.61%350.00%
ben hutchingsben hutchings3011.76%116.67%
jim cromiejim cromie41.57%116.67%
Total255100.00%6100.00%


int dev_vprintk_emit(int level, const struct device *dev, const char *fmt, va_list args) { char hdr[128]; size_t hdrlen; hdrlen = create_syslog_header(dev, hdr, sizeof(hdr)); return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args); }

Contributors

PersonTokensPropCommitsCommitProp
joe perchesjoe perches65100.00%1100.00%
Total65100.00%1100.00%

EXPORT_SYMBOL(dev_vprintk_emit);
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) { va_list args; int r; va_start(args, fmt); r = dev_vprintk_emit(level, dev, fmt, args); va_end(args); return r; }

Contributors

PersonTokensPropCommitsCommitProp
joe perchesjoe perches55100.00%1100.00%
Total55100.00%1100.00%

EXPORT_SYMBOL(dev_printk_emit);
static void __dev_printk(const char *level, const struct device *dev, struct va_format *vaf) { if (dev) dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", dev_driver_string(dev), dev_name(dev), vaf); else printk("%s(NULL device *): %pV", level, vaf); }

Contributors

PersonTokensPropCommitsCommitProp
joe perchesjoe perches5385.48%466.67%
kay sieverskay sievers711.29%116.67%
jim cromiejim cromie23.23%116.67%
Total62100.00%6100.00%


void dev_printk(const char *level, const struct device *dev, const char *fmt, ...) { struct va_format vaf; va_list args; va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; __dev_printk(level, dev, &vaf); va_end(args); }

Contributors

PersonTokensPropCommitsCommitProp
joe perchesjoe perches65100.00%2100.00%
Total65100.00%2100.00%

EXPORT_SYMBOL(dev_printk); #define define_dev_printk_level(func, kern_level) \ void func(const struct device *dev, const char *fmt, ...) \ { \ struct va_format vaf; \ va_list args; \ \ va_start(args, fmt); \ \ vaf.fmt = fmt; \ vaf.va = &args; \ \ __dev_printk(kern_level, dev, &vaf); \ \ va_end(args); \ } \ EXPORT_SYMBOL(func); define_dev_printk_level(dev_emerg, KERN_EMERG); define_dev_printk_level(dev_alert, KERN_ALERT); define_dev_printk_level(dev_crit, KERN_CRIT); define_dev_printk_level(dev_err, KERN_ERR); define_dev_printk_level(dev_warn, KERN_WARNING); define_dev_printk_level(dev_notice, KERN_NOTICE); define_dev_printk_level(_dev_info, KERN_INFO); #endif
static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) { return fwnode && !IS_ERR(fwnode->secondary); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki23100.00%1100.00%
Total23100.00%1100.00%

/** * set_primary_fwnode - Change the primary firmware node of a given device. * @dev: Device to handle. * @fwnode: New primary firmware node of the device. * * Set the device's firmware node pointer to @fwnode, but if a secondary * firmware node of the device is present, preserve it. */
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) { if (fwnode) { struct fwnode_handle *fn = dev->fwnode; if (fwnode_is_primary(fn)) fn = fn->secondary; if (fn) { WARN_ON(fwnode->secondary); fwnode->secondary = fn; } dev->fwnode = fwnode; } else { dev->fwnode = fwnode_is_primary(dev->fwnode) ? dev->fwnode->secondary : NULL; } }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki7785.56%150.00%
mika westerbergmika westerberg1314.44%150.00%
Total90100.00%2100.00%

EXPORT_SYMBOL_GPL(set_primary_fwnode); /** * set_secondary_fwnode - Change the secondary firmware node of a given device. * @dev: Device to handle. * @fwnode: New secondary firmware node of the device. * * If a primary firmware node of the device is present, set its secondary * pointer to @fwnode. Otherwise, set the device's firmware node pointer to * @fwnode. */
void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) { if (fwnode) fwnode->secondary = ERR_PTR(-ENODEV); if (fwnode_is_primary(dev->fwnode)) dev->fwnode->secondary = fwnode; else dev->fwnode = fwnode; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki53100.00%1100.00%
Total53100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman177520.28%5020.58%
kay sieverskay sievers172819.75%3213.17%
rafael j. wysockirafael j. wysocki6917.90%52.06%
cornelia huckcornelia huck6487.40%135.35%
patrick mochelpatrick mochel6046.90%2510.29%
joe perchesjoe perches3684.21%52.06%
eric w. biedermaneric w. biederman3313.78%31.23%
mark mcloughlinmark mcloughlin2803.20%10.41%
dan williamsdan williams2723.11%10.41%
grygorii strashkogrygorii strashko2192.50%10.41%
andy shevchenkoandy shevchenko1631.86%10.41%
guenter roeckguenter roeck1521.74%10.41%
tejun heotejun heo1221.39%72.88%
alan sternalan stern1221.39%72.88%
borislav petkovborislav petkov1131.29%10.41%
linus torvaldslinus torvalds840.96%10.41%
benjamin herrenschmidtbenjamin herrenschmidt840.96%31.23%
hugh daschbachhugh daschbach800.91%10.41%
dmitry torokhovdmitry torokhov740.85%41.65%
sergey klyaussergey klyaus560.64%10.41%
andi kleenandi kleen550.63%10.41%
david graham whitedavid graham white550.63%10.41%
stephen rothwellstephen rothwell480.55%10.41%
yinghai luyinghai lu450.51%10.41%
dave youngdave young450.51%31.23%
felipe balbifelipe balbi440.50%10.41%
ming leiming lei420.48%10.41%
james bottomleyjames bottomley380.43%20.82%
al viroal viro340.39%20.82%
ben hutchingsben hutchings300.34%10.41%
joerg roedeljoerg roedel220.25%10.41%
wagner ferencwagner ferenc210.24%10.41%
andrew mortonandrew morton210.24%10.41%
grant likelygrant likely190.22%20.82%
wang yijingwang yijing180.21%10.41%
randy dunlaprandy dunlap170.19%31.23%
mika westerbergmika westerberg130.15%10.41%
jiang liujiang liu130.15%10.41%
jean delvarejean delvare130.15%20.82%
brian walshbrian walsh100.11%10.41%
liu shuoxliu shuox100.11%10.41%
thomas gleixnerthomas gleixner90.10%20.82%
zhen leizhen lei90.10%10.41%
matthew wilcoxmatthew wilcox80.09%20.82%
peter zijlstrapeter zijlstra80.09%10.41%
rasmus villemoesrasmus villemoes80.09%10.41%
christoph hellwigchristoph hellwig80.09%10.41%
lars-peter clausenlars-peter clausen80.09%10.41%
harvey harrisonharvey harrison70.08%10.41%
peter chenpeter chen70.08%10.41%
jesper juhljesper juhl70.08%10.41%
jim cromiejim cromie60.07%10.41%
lei minglei ming60.07%10.41%
david herrmanndavid herrmann60.07%10.41%
johannes bergjohannes berg60.07%20.82%
longx zhanglongx zhang50.06%10.41%
benson leungbenson leung50.06%10.41%
phil carmodyphil carmody40.05%20.82%
alexander nybergalexander nyberg40.05%10.41%
yani ioannouyani ioannou40.05%10.41%
hannes reineckehannes reinecke40.05%10.41%
david s. millerdavid s. miller30.03%10.41%
robert p. j. dayrobert p. j. day30.03%10.41%
arjan van de venarjan van de ven30.03%10.41%
deepak saxenadeepak saxena30.03%10.41%
emese revfyemese revfy20.02%20.82%
rabin vincentrabin vincent20.02%10.41%
david brownelldavid brownell20.02%10.41%
catalin marinascatalin marinas20.02%10.41%
jani nikulajani nikula20.02%10.41%
ethan zhaoethan zhao20.02%10.41%
stephen hemmingerstephen hemminger20.02%10.41%
dave jonesdave jones20.02%10.41%
michal miroslawmichal miroslaw20.02%10.41%
peter korsgaardpeter korsgaard10.01%10.41%
adrian bunkadrian bunk10.01%10.41%
christoph eggerchristoph egger10.01%10.41%
frank a. ueppingfrank a. uepping10.01%10.41%
hanjun guohanjun guo10.01%10.41%
stefan achatzstefan achatz10.01%10.41%
jingoo hanjingoo han10.01%10.41%
ma jianpengma jianpeng10.01%10.41%
josh triplettjosh triplett10.01%10.41%
stefan weilstefan weil10.01%10.41%
timur tabitimur tabi10.01%10.41%
roland dreierroland dreier10.01%10.41%
yan hongyan hong10.01%10.41%
Total8751100.00%243100.00%
Directory: drivers/base
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}