mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
Driver core: move the static kobject out of struct driver
This patch removes the kobject, and a few other driver-core-only fields out of struct driver and into the driver core only. Now drivers can be safely create on the stack or statically (like they currently are.) Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c63469a398
commit
e5dd127846
7 changed files with 99 additions and 74 deletions
|
@ -27,6 +27,14 @@ struct bus_type_private {
|
||||||
struct bus_type *bus;
|
struct bus_type *bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct driver_private {
|
||||||
|
struct kobject kobj;
|
||||||
|
struct klist klist_devices;
|
||||||
|
struct klist_node knode_bus;
|
||||||
|
struct module_kobject *mkobj;
|
||||||
|
struct device_driver *driver;
|
||||||
|
};
|
||||||
|
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
|
||||||
|
|
||||||
/* initialisation functions */
|
/* initialisation functions */
|
||||||
extern int devices_init(void);
|
extern int devices_init(void);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-3 Patrick Mochel
|
* Copyright (c) 2002-3 Patrick Mochel
|
||||||
* Copyright (c) 2002-3 Open Source Development Labs
|
* Copyright (c) 2002-3 Open Source Development Labs
|
||||||
|
* Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
|
||||||
|
* Copyright (c) 2007 Novell Inc.
|
||||||
*
|
*
|
||||||
* This file is released under the GPLv2
|
* This file is released under the GPLv2
|
||||||
*
|
*
|
||||||
|
@ -24,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
|
#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
|
||||||
#define to_driver(obj) container_of(obj, struct device_driver, kobj)
|
|
||||||
|
|
||||||
|
|
||||||
static int __must_check bus_rescan_devices_helper(struct device *dev,
|
static int __must_check bus_rescan_devices_helper(struct device *dev,
|
||||||
|
@ -49,11 +50,11 @@ static ssize_t
|
||||||
drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
||||||
{
|
{
|
||||||
struct driver_attribute * drv_attr = to_drv_attr(attr);
|
struct driver_attribute * drv_attr = to_drv_attr(attr);
|
||||||
struct device_driver * drv = to_driver(kobj);
|
struct driver_private *drv_priv = to_driver(kobj);
|
||||||
ssize_t ret = -EIO;
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
if (drv_attr->show)
|
if (drv_attr->show)
|
||||||
ret = drv_attr->show(drv, buf);
|
ret = drv_attr->show(drv_priv->driver, buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +63,11 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
|
||||||
const char * buf, size_t count)
|
const char * buf, size_t count)
|
||||||
{
|
{
|
||||||
struct driver_attribute * drv_attr = to_drv_attr(attr);
|
struct driver_attribute * drv_attr = to_drv_attr(attr);
|
||||||
struct device_driver * drv = to_driver(kobj);
|
struct driver_private *drv_priv = to_driver(kobj);
|
||||||
ssize_t ret = -EIO;
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
if (drv_attr->store)
|
if (drv_attr->store)
|
||||||
ret = drv_attr->store(drv, buf, count);
|
ret = drv_attr->store(drv_priv->driver, buf, count);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,22 +76,12 @@ static struct sysfs_ops driver_sysfs_ops = {
|
||||||
.store = drv_attr_store,
|
.store = drv_attr_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void driver_release(struct kobject *kobj)
|
static void driver_release(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
/*
|
struct driver_private *drv_priv = to_driver(kobj);
|
||||||
* Yes this is an empty release function, it is this way because struct
|
|
||||||
* device is always a static object, not a dynamic one. Yes, this is
|
pr_debug("%s: freeing %s\n", __FUNCTION__, kobject_name(kobj));
|
||||||
* not nice and bad, but remember, drivers are code, reference counted
|
kfree(drv_priv);
|
||||||
* by the module count, not a device, which is really data. And yes,
|
|
||||||
* in the future I do want to have all drivers be created dynamically,
|
|
||||||
* and am working toward that goal, but it will take a bit longer...
|
|
||||||
*
|
|
||||||
* But do not let this example give _anyone_ the idea that they can
|
|
||||||
* create a release function without any code in it at all, to do that
|
|
||||||
* is almost always wrong. If you have any questions about this,
|
|
||||||
* please send an email to <greg@kroah.com>
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kobj_type driver_ktype = {
|
static struct kobj_type driver_ktype = {
|
||||||
|
@ -350,7 +341,13 @@ struct device * bus_find_device(struct bus_type *bus,
|
||||||
static struct device_driver * next_driver(struct klist_iter * i)
|
static struct device_driver * next_driver(struct klist_iter * i)
|
||||||
{
|
{
|
||||||
struct klist_node * n = klist_next(i);
|
struct klist_node * n = klist_next(i);
|
||||||
return n ? container_of(n, struct device_driver, knode_bus) : NULL;
|
struct driver_private *drv_priv;
|
||||||
|
|
||||||
|
if (n) {
|
||||||
|
drv_priv = container_of(n, struct driver_private, knode_bus);
|
||||||
|
return drv_priv->driver;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -384,7 +381,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
klist_iter_init_node(&bus->p->klist_drivers, &i,
|
klist_iter_init_node(&bus->p->klist_drivers, &i,
|
||||||
start ? &start->knode_bus : NULL);
|
start ? &start->p->knode_bus : NULL);
|
||||||
while ((drv = next_driver(&i)) && !error)
|
while ((drv = next_driver(&i)) && !error)
|
||||||
error = fn(drv, data);
|
error = fn(drv, data);
|
||||||
klist_iter_exit(&i);
|
klist_iter_exit(&i);
|
||||||
|
@ -620,7 +617,7 @@ static ssize_t driver_uevent_store(struct device_driver *drv,
|
||||||
enum kobject_action action;
|
enum kobject_action action;
|
||||||
|
|
||||||
if (kobject_action_type(buf, count, &action) == 0)
|
if (kobject_action_type(buf, count, &action) == 0)
|
||||||
kobject_uevent(&drv->kobj, action);
|
kobject_uevent(&drv->p->kobj, action);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
|
static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
|
||||||
|
@ -632,19 +629,29 @@ static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
|
||||||
*/
|
*/
|
||||||
int bus_add_driver(struct device_driver *drv)
|
int bus_add_driver(struct device_driver *drv)
|
||||||
{
|
{
|
||||||
struct bus_type * bus = bus_get(drv->bus);
|
struct bus_type *bus;
|
||||||
|
struct driver_private *priv;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
bus = bus_get(drv->bus);
|
||||||
if (!bus)
|
if (!bus)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
|
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
|
||||||
error = kobject_set_name(&drv->kobj, "%s", drv->name);
|
|
||||||
|
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
error = kobject_set_name(&priv->kobj, "%s", drv->name);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put_bus;
|
goto out_put_bus;
|
||||||
drv->kobj.kset = bus->p->drivers_kset;
|
priv->kobj.kset = bus->p->drivers_kset;
|
||||||
drv->kobj.ktype = &driver_ktype;
|
priv->kobj.ktype = &driver_ktype;
|
||||||
error = kobject_register(&drv->kobj);
|
klist_init(&priv->klist_devices, NULL, NULL);
|
||||||
|
priv->driver = drv;
|
||||||
|
drv->p = priv;
|
||||||
|
error = kobject_register(&priv->kobj);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put_bus;
|
goto out_put_bus;
|
||||||
|
|
||||||
|
@ -653,7 +660,7 @@ int bus_add_driver(struct device_driver *drv)
|
||||||
if (error)
|
if (error)
|
||||||
goto out_unregister;
|
goto out_unregister;
|
||||||
}
|
}
|
||||||
klist_add_tail(&drv->knode_bus, &bus->p->klist_drivers);
|
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
|
||||||
module_add_driver(drv->owner, drv);
|
module_add_driver(drv->owner, drv);
|
||||||
|
|
||||||
error = driver_create_file(drv, &driver_attr_uevent);
|
error = driver_create_file(drv, &driver_attr_uevent);
|
||||||
|
@ -676,7 +683,7 @@ int bus_add_driver(struct device_driver *drv)
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
out_unregister:
|
out_unregister:
|
||||||
kobject_unregister(&drv->kobj);
|
kobject_unregister(&priv->kobj);
|
||||||
out_put_bus:
|
out_put_bus:
|
||||||
bus_put(bus);
|
bus_put(bus);
|
||||||
return error;
|
return error;
|
||||||
|
@ -699,11 +706,11 @@ void bus_remove_driver(struct device_driver * drv)
|
||||||
remove_bind_files(drv);
|
remove_bind_files(drv);
|
||||||
driver_remove_attrs(drv->bus, drv);
|
driver_remove_attrs(drv->bus, drv);
|
||||||
driver_remove_file(drv, &driver_attr_uevent);
|
driver_remove_file(drv, &driver_attr_uevent);
|
||||||
klist_remove(&drv->knode_bus);
|
klist_remove(&drv->p->knode_bus);
|
||||||
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
|
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
|
||||||
driver_detach(drv);
|
driver_detach(drv);
|
||||||
module_remove_driver(drv);
|
module_remove_driver(drv);
|
||||||
kobject_unregister(&drv->kobj);
|
kobject_unregister(&drv->p->kobj);
|
||||||
bus_put(drv->bus);
|
bus_put(drv->bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-5 Patrick Mochel
|
* Copyright (c) 2002-5 Patrick Mochel
|
||||||
* Copyright (c) 2002-3 Open Source Development Labs
|
* Copyright (c) 2002-3 Open Source Development Labs
|
||||||
|
* Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
|
||||||
|
* Copyright (c) 2007 Novell Inc.
|
||||||
*
|
*
|
||||||
* This file is released under the GPLv2
|
* This file is released under the GPLv2
|
||||||
*/
|
*/
|
||||||
|
@ -23,8 +25,6 @@
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
#include "power/power.h"
|
#include "power/power.h"
|
||||||
|
|
||||||
#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
|
|
||||||
|
|
||||||
|
|
||||||
static void driver_bound(struct device *dev)
|
static void driver_bound(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -41,20 +41,20 @@ static void driver_bound(struct device *dev)
|
||||||
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_BOUND_DRIVER, dev);
|
BUS_NOTIFY_BOUND_DRIVER, dev);
|
||||||
|
|
||||||
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
|
klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int driver_sysfs_add(struct device *dev)
|
static int driver_sysfs_add(struct device *dev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
|
ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
|
||||||
kobject_name(&dev->kobj));
|
kobject_name(&dev->kobj));
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj,
|
ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
|
||||||
"driver");
|
"driver");
|
||||||
if (ret)
|
if (ret)
|
||||||
sysfs_remove_link(&dev->driver->kobj,
|
sysfs_remove_link(&dev->driver->p->kobj,
|
||||||
kobject_name(&dev->kobj));
|
kobject_name(&dev->kobj));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -65,7 +65,7 @@ static void driver_sysfs_remove(struct device *dev)
|
||||||
struct device_driver *drv = dev->driver;
|
struct device_driver *drv = dev->driver;
|
||||||
|
|
||||||
if (drv) {
|
if (drv) {
|
||||||
sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
|
sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
|
||||||
sysfs_remove_link(&dev->kobj, "driver");
|
sysfs_remove_link(&dev->kobj, "driver");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,15 +339,15 @@ void driver_detach(struct device_driver * drv)
|
||||||
struct device * dev;
|
struct device * dev;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spin_lock(&drv->klist_devices.k_lock);
|
spin_lock(&drv->p->klist_devices.k_lock);
|
||||||
if (list_empty(&drv->klist_devices.k_list)) {
|
if (list_empty(&drv->p->klist_devices.k_list)) {
|
||||||
spin_unlock(&drv->klist_devices.k_lock);
|
spin_unlock(&drv->p->klist_devices.k_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev = list_entry(drv->klist_devices.k_list.prev,
|
dev = list_entry(drv->p->klist_devices.k_list.prev,
|
||||||
struct device, knode_driver.n_node);
|
struct device, knode_driver.n_node);
|
||||||
get_device(dev);
|
get_device(dev);
|
||||||
spin_unlock(&drv->klist_devices.k_lock);
|
spin_unlock(&drv->p->klist_devices.k_lock);
|
||||||
|
|
||||||
if (dev->parent) /* Needed for USB */
|
if (dev->parent) /* Needed for USB */
|
||||||
down(&dev->parent->sem);
|
down(&dev->parent->sem);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-3 Patrick Mochel
|
* Copyright (c) 2002-3 Patrick Mochel
|
||||||
* Copyright (c) 2002-3 Open Source Development Labs
|
* Copyright (c) 2002-3 Open Source Development Labs
|
||||||
|
* Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
|
||||||
|
* Copyright (c) 2007 Novell Inc.
|
||||||
*
|
*
|
||||||
* This file is released under the GPLv2
|
* This file is released under the GPLv2
|
||||||
*
|
*
|
||||||
|
@ -15,7 +17,6 @@
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
#define to_dev(node) container_of(node, struct device, driver_list)
|
#define to_dev(node) container_of(node, struct device, driver_list)
|
||||||
#define to_drv(obj) container_of(obj, struct device_driver, kobj)
|
|
||||||
|
|
||||||
|
|
||||||
static struct device * next_device(struct klist_iter * i)
|
static struct device * next_device(struct klist_iter * i)
|
||||||
|
@ -44,7 +45,7 @@ int driver_for_each_device(struct device_driver * drv, struct device * start,
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
klist_iter_init_node(&drv->klist_devices, &i,
|
klist_iter_init_node(&drv->p->klist_devices, &i,
|
||||||
start ? &start->knode_driver : NULL);
|
start ? &start->knode_driver : NULL);
|
||||||
while ((dev = next_device(&i)) && !error)
|
while ((dev = next_device(&i)) && !error)
|
||||||
error = fn(dev, data);
|
error = fn(dev, data);
|
||||||
|
@ -80,7 +81,7 @@ struct device * driver_find_device(struct device_driver *drv,
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
klist_iter_init_node(&drv->klist_devices, &i,
|
klist_iter_init_node(&drv->p->klist_devices, &i,
|
||||||
(start ? &start->knode_driver : NULL));
|
(start ? &start->knode_driver : NULL));
|
||||||
while ((dev = next_device(&i)))
|
while ((dev = next_device(&i)))
|
||||||
if (match(dev, data) && get_device(dev))
|
if (match(dev, data) && get_device(dev))
|
||||||
|
@ -100,7 +101,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
if (get_driver(drv)) {
|
if (get_driver(drv)) {
|
||||||
error = sysfs_create_file(&drv->kobj, &attr->attr);
|
error = sysfs_create_file(&drv->p->kobj, &attr->attr);
|
||||||
put_driver(drv);
|
put_driver(drv);
|
||||||
} else
|
} else
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
|
@ -117,7 +118,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
|
||||||
void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
|
void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
|
||||||
{
|
{
|
||||||
if (get_driver(drv)) {
|
if (get_driver(drv)) {
|
||||||
sysfs_remove_file(&drv->kobj, &attr->attr);
|
sysfs_remove_file(&drv->p->kobj, &attr->attr);
|
||||||
put_driver(drv);
|
put_driver(drv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +144,7 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj,
|
||||||
if (!name)
|
if (!name)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return kobject_add_ng(kobj, &drv->kobj, "%s", name);
|
return kobject_add_ng(kobj, &drv->p->kobj, "%s", name);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(driver_add_kobj);
|
EXPORT_SYMBOL_GPL(driver_add_kobj);
|
||||||
|
|
||||||
|
@ -153,7 +154,15 @@ EXPORT_SYMBOL_GPL(driver_add_kobj);
|
||||||
*/
|
*/
|
||||||
struct device_driver * get_driver(struct device_driver * drv)
|
struct device_driver * get_driver(struct device_driver * drv)
|
||||||
{
|
{
|
||||||
return drv ? to_drv(kobject_get(&drv->kobj)) : NULL;
|
if (drv) {
|
||||||
|
struct driver_private *priv;
|
||||||
|
struct kobject *kobj;
|
||||||
|
|
||||||
|
kobj = kobject_get(&drv->p->kobj);
|
||||||
|
priv = to_driver(kobj);
|
||||||
|
return priv->driver;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,7 +172,7 @@ struct device_driver * get_driver(struct device_driver * drv)
|
||||||
*/
|
*/
|
||||||
void put_driver(struct device_driver * drv)
|
void put_driver(struct device_driver * drv)
|
||||||
{
|
{
|
||||||
kobject_put(&drv->kobj);
|
kobject_put(&drv->p->kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int driver_add_groups(struct device_driver *drv,
|
static int driver_add_groups(struct device_driver *drv,
|
||||||
|
@ -174,10 +183,10 @@ static int driver_add_groups(struct device_driver *drv,
|
||||||
|
|
||||||
if (groups) {
|
if (groups) {
|
||||||
for (i = 0; groups[i]; i++) {
|
for (i = 0; groups[i]; i++) {
|
||||||
error = sysfs_create_group(&drv->kobj, groups[i]);
|
error = sysfs_create_group(&drv->p->kobj, groups[i]);
|
||||||
if (error) {
|
if (error) {
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
sysfs_remove_group(&drv->kobj,
|
sysfs_remove_group(&drv->p->kobj,
|
||||||
groups[i]);
|
groups[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +202,7 @@ static void driver_remove_groups(struct device_driver *drv,
|
||||||
|
|
||||||
if (groups)
|
if (groups)
|
||||||
for (i = 0; groups[i]; i++)
|
for (i = 0; groups[i]; i++)
|
||||||
sysfs_remove_group(&drv->kobj, groups[i]);
|
sysfs_remove_group(&drv->p->kobj, groups[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,7 +223,6 @@ int driver_register(struct device_driver * drv)
|
||||||
(drv->bus->shutdown && drv->shutdown)) {
|
(drv->bus->shutdown && drv->shutdown)) {
|
||||||
printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
|
printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
|
||||||
}
|
}
|
||||||
klist_init(&drv->klist_devices, NULL, NULL);
|
|
||||||
ret = bus_add_driver(drv);
|
ret = bus_add_driver(drv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -250,8 +258,12 @@ void driver_unregister(struct device_driver * drv)
|
||||||
struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
||||||
{
|
{
|
||||||
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
|
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
|
||||||
if (k)
|
struct driver_private *priv;
|
||||||
return to_drv(k);
|
|
||||||
|
if (k) {
|
||||||
|
priv = to_driver(k);
|
||||||
|
return priv->driver;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
|
||||||
if (mkobj) {
|
if (mkobj) {
|
||||||
mk = container_of(mkobj, struct module_kobject, kobj);
|
mk = container_of(mkobj, struct module_kobject, kobj);
|
||||||
/* remember our module structure */
|
/* remember our module structure */
|
||||||
drv->mkobj = mk;
|
drv->p->mkobj = mk;
|
||||||
/* kset_find_obj took a reference */
|
/* kset_find_obj took a reference */
|
||||||
kobject_put(mkobj);
|
kobject_put(mkobj);
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,11 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Don't check return codes; these calls are idempotent */
|
/* Don't check return codes; these calls are idempotent */
|
||||||
no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
|
no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
|
||||||
driver_name = make_driver_name(drv);
|
driver_name = make_driver_name(drv);
|
||||||
if (driver_name) {
|
if (driver_name) {
|
||||||
module_create_drivers_dir(mk);
|
module_create_drivers_dir(mk);
|
||||||
no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
|
no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
|
||||||
driver_name);
|
driver_name);
|
||||||
kfree(driver_name);
|
kfree(driver_name);
|
||||||
}
|
}
|
||||||
|
@ -78,12 +78,12 @@ void module_remove_driver(struct device_driver *drv)
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sysfs_remove_link(&drv->kobj, "module");
|
sysfs_remove_link(&drv->p->kobj, "module");
|
||||||
|
|
||||||
if (drv->owner)
|
if (drv->owner)
|
||||||
mk = &drv->owner->mkobj;
|
mk = &drv->owner->mkobj;
|
||||||
else if (drv->mkobj)
|
else if (drv->p->mkobj)
|
||||||
mk = drv->mkobj;
|
mk = drv->p->mkobj;
|
||||||
if (mk && mk->drivers_dir) {
|
if (mk && mk->drivers_dir) {
|
||||||
driver_name = make_driver_name(drv);
|
driver_name = make_driver_name(drv);
|
||||||
if (driver_name) {
|
if (driver_name) {
|
||||||
|
|
|
@ -499,7 +499,7 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
|
||||||
*/
|
*/
|
||||||
spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
|
spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
|
||||||
drv->probe = NULL;
|
drv->probe = NULL;
|
||||||
if (code == 0 && list_empty(&drv->driver.klist_devices.k_list))
|
if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
drv->driver.probe = platform_drv_probe_fail;
|
drv->driver.probe = platform_drv_probe_fail;
|
||||||
spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
|
spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
struct device;
|
struct device;
|
||||||
struct device_driver;
|
struct device_driver;
|
||||||
|
struct driver_private;
|
||||||
struct class;
|
struct class;
|
||||||
struct class_device;
|
struct class_device;
|
||||||
struct bus_type;
|
struct bus_type;
|
||||||
|
@ -116,13 +117,8 @@ struct device_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct bus_type *bus;
|
struct bus_type *bus;
|
||||||
|
|
||||||
struct kobject kobj;
|
|
||||||
struct klist klist_devices;
|
|
||||||
struct klist_node knode_bus;
|
|
||||||
|
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
const char *mod_name; /* used for built-in modules */
|
const char *mod_name; /* used for built-in modules */
|
||||||
struct module_kobject * mkobj;
|
|
||||||
|
|
||||||
int (*probe) (struct device * dev);
|
int (*probe) (struct device * dev);
|
||||||
int (*remove) (struct device * dev);
|
int (*remove) (struct device * dev);
|
||||||
|
@ -130,6 +126,8 @@ struct device_driver {
|
||||||
int (*suspend) (struct device * dev, pm_message_t state);
|
int (*suspend) (struct device * dev, pm_message_t state);
|
||||||
int (*resume) (struct device * dev);
|
int (*resume) (struct device * dev);
|
||||||
struct attribute_group **groups;
|
struct attribute_group **groups;
|
||||||
|
|
||||||
|
struct driver_private *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue