linux/drivers/base/driver.c
<<
>>
Prefs
   1/*
   2 * driver.c - centralized device driver management
   3 *
   4 * Copyright (c) 2002-3 Patrick Mochel
   5 * Copyright (c) 2002-3 Open Source Development Labs
   6 *
   7 * This file is released under the GPLv2
   8 *
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/device.h>
  13#include <linux/module.h>
  14#include <linux/errno.h>
  15#include <linux/string.h>
  16#include "base.h"
  17
  18#define to_dev(node) container_of(node, struct device, driver_list)
  19#define to_drv(obj) container_of(obj, struct device_driver, kobj)
  20
  21/**
  22 *      driver_create_file - create sysfs file for driver.
  23 *      @drv:   driver.
  24 *      @attr:  driver attribute descriptor.
  25 */
  26
  27int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
  28{
  29        int error;
  30        if (get_driver(drv)) {
  31                error = sysfs_create_file(&drv->kobj, &attr->attr);
  32                put_driver(drv);
  33        } else
  34                error = -EINVAL;
  35        return error;
  36}
  37
  38
  39/**
  40 *      driver_remove_file - remove sysfs file for driver.
  41 *      @drv:   driver.
  42 *      @attr:  driver attribute descriptor.
  43 */
  44
  45void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
  46{
  47        if (get_driver(drv)) {
  48                sysfs_remove_file(&drv->kobj, &attr->attr);
  49                put_driver(drv);
  50        }
  51}
  52
  53
  54/**
  55 *      get_driver - increment driver reference count.
  56 *      @drv:   driver.
  57 */
  58struct device_driver * get_driver(struct device_driver * drv)
  59{
  60        return drv ? to_drv(kobject_get(&drv->kobj)) : NULL;
  61}
  62
  63
  64/**
  65 *      put_driver - decrement driver's refcount.
  66 *      @drv:   driver.
  67 */
  68void put_driver(struct device_driver * drv)
  69{
  70        kobject_put(&drv->kobj);
  71}
  72
  73
  74/**
  75 *      driver_register - register driver with bus
  76 *      @drv:   driver to register
  77 *
  78 *      We pass off most of the work to the bus_add_driver() call,
  79 *      since most of the things we have to do deal with the bus
  80 *      structures.
  81 *
  82 *      The one interesting aspect is that we initialize @drv->unload_sem
  83 *      to a locked state here. It will be unlocked when the driver
  84 *      reference count reaches 0.
  85 */
  86int driver_register(struct device_driver * drv)
  87{
  88        INIT_LIST_HEAD(&drv->devices);
  89        init_MUTEX_LOCKED(&drv->unload_sem);
  90        return bus_add_driver(drv);
  91}
  92
  93
  94/**
  95 *      driver_unregister - remove driver from system.
  96 *      @drv:   driver.
  97 *
  98 *      Again, we pass off most of the work to the bus-level call.
  99 *
 100 *      Though, once that is done, we attempt to take @drv->unload_sem.
 101 *      This will block until the driver refcount reaches 0, and it is
 102 *      released. Only modular drivers will call this function, and we
 103 *      have to guarantee that it won't complete, letting the driver
 104 *      unload until all references are gone.
 105 */
 106
 107void driver_unregister(struct device_driver * drv)
 108{
 109        bus_remove_driver(drv);
 110        down(&drv->unload_sem);
 111        up(&drv->unload_sem);
 112}
 113
 114/**
 115 *      driver_find - locate driver on a bus by its name.
 116 *      @name:  name of the driver.
 117 *      @bus:   bus to scan for the driver.
 118 *
 119 *      Call kset_find_obj() to iterate over list of drivers on
 120 *      a bus to find driver by name. Return driver if found.
 121 *
 122 *      Note that kset_find_obj increments driver's reference count.
 123 */
 124struct device_driver *driver_find(const char *name, struct bus_type *bus)
 125{
 126        struct kobject *k = kset_find_obj(&bus->drivers, name);
 127        if (k)
 128                return to_drv(k);
 129        return NULL;
 130}
 131
 132EXPORT_SYMBOL_GPL(driver_register);
 133EXPORT_SYMBOL_GPL(driver_unregister);
 134EXPORT_SYMBOL_GPL(get_driver);
 135EXPORT_SYMBOL_GPL(put_driver);
 136EXPORT_SYMBOL_GPL(driver_find);
 137
 138EXPORT_SYMBOL_GPL(driver_create_file);
 139EXPORT_SYMBOL_GPL(driver_remove_file);
 140
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.