diff options
Diffstat (limited to 'drivers/base/driver.c')
-rw-r--r-- | drivers/base/driver.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 633ae1d70e14..5aacff208f21 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -15,7 +17,6 @@ | |||
15 | #include "base.h" | 17 | #include "base.h" |
16 | 18 | ||
17 | #define to_dev(node) container_of(node, struct device, driver_list) | 19 | #define to_dev(node) container_of(node, struct device, driver_list) |
18 | #define to_drv(obj) container_of(obj, struct device_driver, kobj) | ||
19 | 20 | ||
20 | 21 | ||
21 | static struct device * next_device(struct klist_iter * i) | 22 | 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, | |||
44 | if (!drv) | 45 | if (!drv) |
45 | return -EINVAL; | 46 | return -EINVAL; |
46 | 47 | ||
47 | klist_iter_init_node(&drv->klist_devices, &i, | 48 | klist_iter_init_node(&drv->p->klist_devices, &i, |
48 | start ? &start->knode_driver : NULL); | 49 | start ? &start->knode_driver : NULL); |
49 | while ((dev = next_device(&i)) && !error) | 50 | while ((dev = next_device(&i)) && !error) |
50 | error = fn(dev, data); | 51 | error = fn(dev, data); |
@@ -80,7 +81,7 @@ struct device * driver_find_device(struct device_driver *drv, | |||
80 | if (!drv) | 81 | if (!drv) |
81 | return NULL; | 82 | return NULL; |
82 | 83 | ||
83 | klist_iter_init_node(&drv->klist_devices, &i, | 84 | klist_iter_init_node(&drv->p->klist_devices, &i, |
84 | (start ? &start->knode_driver : NULL)); | 85 | (start ? &start->knode_driver : NULL)); |
85 | while ((dev = next_device(&i))) | 86 | while ((dev = next_device(&i))) |
86 | if (match(dev, data) && get_device(dev)) | 87 | if (match(dev, data) && get_device(dev)) |
@@ -100,7 +101,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att | |||
100 | { | 101 | { |
101 | int error; | 102 | int error; |
102 | if (get_driver(drv)) { | 103 | if (get_driver(drv)) { |
103 | error = sysfs_create_file(&drv->kobj, &attr->attr); | 104 | error = sysfs_create_file(&drv->p->kobj, &attr->attr); |
104 | put_driver(drv); | 105 | put_driver(drv); |
105 | } else | 106 | } else |
106 | error = -EINVAL; | 107 | error = -EINVAL; |
@@ -117,7 +118,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att | |||
117 | void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) | 118 | void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) |
118 | { | 119 | { |
119 | if (get_driver(drv)) { | 120 | if (get_driver(drv)) { |
120 | sysfs_remove_file(&drv->kobj, &attr->attr); | 121 | sysfs_remove_file(&drv->p->kobj, &attr->attr); |
121 | put_driver(drv); | 122 | put_driver(drv); |
122 | } | 123 | } |
123 | } | 124 | } |
@@ -143,7 +144,7 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, | |||
143 | if (!name) | 144 | if (!name) |
144 | return -ENOMEM; | 145 | return -ENOMEM; |
145 | 146 | ||
146 | return kobject_add_ng(kobj, &drv->kobj, "%s", name); | 147 | return kobject_add_ng(kobj, &drv->p->kobj, "%s", name); |
147 | } | 148 | } |
148 | EXPORT_SYMBOL_GPL(driver_add_kobj); | 149 | EXPORT_SYMBOL_GPL(driver_add_kobj); |
149 | 150 | ||
@@ -153,7 +154,15 @@ EXPORT_SYMBOL_GPL(driver_add_kobj); | |||
153 | */ | 154 | */ |
154 | struct device_driver * get_driver(struct device_driver * drv) | 155 | struct device_driver * get_driver(struct device_driver * drv) |
155 | { | 156 | { |
156 | return drv ? to_drv(kobject_get(&drv->kobj)) : NULL; | 157 | if (drv) { |
158 | struct driver_private *priv; | ||
159 | struct kobject *kobj; | ||
160 | |||
161 | kobj = kobject_get(&drv->p->kobj); | ||
162 | priv = to_driver(kobj); | ||
163 | return priv->driver; | ||
164 | } | ||
165 | return NULL; | ||
157 | } | 166 | } |
158 | 167 | ||
159 | 168 | ||
@@ -163,7 +172,7 @@ struct device_driver * get_driver(struct device_driver * drv) | |||
163 | */ | 172 | */ |
164 | void put_driver(struct device_driver * drv) | 173 | void put_driver(struct device_driver * drv) |
165 | { | 174 | { |
166 | kobject_put(&drv->kobj); | 175 | kobject_put(&drv->p->kobj); |
167 | } | 176 | } |
168 | 177 | ||
169 | static int driver_add_groups(struct device_driver *drv, | 178 | static int driver_add_groups(struct device_driver *drv, |
@@ -174,10 +183,10 @@ static int driver_add_groups(struct device_driver *drv, | |||
174 | 183 | ||
175 | if (groups) { | 184 | if (groups) { |
176 | for (i = 0; groups[i]; i++) { | 185 | for (i = 0; groups[i]; i++) { |
177 | error = sysfs_create_group(&drv->kobj, groups[i]); | 186 | error = sysfs_create_group(&drv->p->kobj, groups[i]); |
178 | if (error) { | 187 | if (error) { |
179 | while (--i >= 0) | 188 | while (--i >= 0) |
180 | sysfs_remove_group(&drv->kobj, | 189 | sysfs_remove_group(&drv->p->kobj, |
181 | groups[i]); | 190 | groups[i]); |
182 | break; | 191 | break; |
183 | } | 192 | } |
@@ -193,7 +202,7 @@ static void driver_remove_groups(struct device_driver *drv, | |||
193 | 202 | ||
194 | if (groups) | 203 | if (groups) |
195 | for (i = 0; groups[i]; i++) | 204 | for (i = 0; groups[i]; i++) |
196 | sysfs_remove_group(&drv->kobj, groups[i]); | 205 | sysfs_remove_group(&drv->p->kobj, groups[i]); |
197 | } | 206 | } |
198 | 207 | ||
199 | 208 | ||
@@ -214,7 +223,6 @@ int driver_register(struct device_driver * drv) | |||
214 | (drv->bus->shutdown && drv->shutdown)) { | 223 | (drv->bus->shutdown && drv->shutdown)) { |
215 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); | 224 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); |
216 | } | 225 | } |
217 | klist_init(&drv->klist_devices, NULL, NULL); | ||
218 | ret = bus_add_driver(drv); | 226 | ret = bus_add_driver(drv); |
219 | if (ret) | 227 | if (ret) |
220 | return ret; | 228 | return ret; |
@@ -250,8 +258,12 @@ void driver_unregister(struct device_driver * drv) | |||
250 | struct device_driver *driver_find(const char *name, struct bus_type *bus) | 258 | struct device_driver *driver_find(const char *name, struct bus_type *bus) |
251 | { | 259 | { |
252 | struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); | 260 | struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); |
253 | if (k) | 261 | struct driver_private *priv; |
254 | return to_drv(k); | 262 | |
263 | if (k) { | ||
264 | priv = to_driver(k); | ||
265 | return priv->driver; | ||
266 | } | ||
255 | return NULL; | 267 | return NULL; |
256 | } | 268 | } |
257 | 269 | ||