diff options
-rw-r--r-- | drivers/base/driver.c | 42 | ||||
-rw-r--r-- | include/linux/device.h | 1 |
2 files changed, 42 insertions, 1 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f94be40646d2..e3b58407fedc 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -142,6 +142,37 @@ void put_driver(struct device_driver * drv) | |||
142 | kobject_put(&drv->kobj); | 142 | kobject_put(&drv->kobj); |
143 | } | 143 | } |
144 | 144 | ||
145 | static int driver_add_groups(struct device_driver *drv, | ||
146 | struct attribute_group **groups) | ||
147 | { | ||
148 | int error = 0; | ||
149 | int i; | ||
150 | |||
151 | if (groups) { | ||
152 | for (i = 0; groups[i]; i++) { | ||
153 | error = sysfs_create_group(&drv->kobj, groups[i]); | ||
154 | if (error) { | ||
155 | while (--i >= 0) | ||
156 | sysfs_remove_group(&drv->kobj, | ||
157 | groups[i]); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | return error; | ||
163 | } | ||
164 | |||
165 | static void driver_remove_groups(struct device_driver *drv, | ||
166 | struct attribute_group **groups) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | if (groups) | ||
171 | for (i = 0; groups[i]; i++) | ||
172 | sysfs_remove_group(&drv->kobj, groups[i]); | ||
173 | } | ||
174 | |||
175 | |||
145 | /** | 176 | /** |
146 | * driver_register - register driver with bus | 177 | * driver_register - register driver with bus |
147 | * @drv: driver to register | 178 | * @drv: driver to register |
@@ -152,13 +183,21 @@ void put_driver(struct device_driver * drv) | |||
152 | */ | 183 | */ |
153 | int driver_register(struct device_driver * drv) | 184 | int driver_register(struct device_driver * drv) |
154 | { | 185 | { |
186 | int ret; | ||
187 | |||
155 | if ((drv->bus->probe && drv->probe) || | 188 | if ((drv->bus->probe && drv->probe) || |
156 | (drv->bus->remove && drv->remove) || | 189 | (drv->bus->remove && drv->remove) || |
157 | (drv->bus->shutdown && drv->shutdown)) { | 190 | (drv->bus->shutdown && drv->shutdown)) { |
158 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); | 191 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); |
159 | } | 192 | } |
160 | klist_init(&drv->klist_devices, NULL, NULL); | 193 | klist_init(&drv->klist_devices, NULL, NULL); |
161 | return bus_add_driver(drv); | 194 | ret = bus_add_driver(drv); |
195 | if (ret) | ||
196 | return ret; | ||
197 | ret = driver_add_groups(drv, drv->groups); | ||
198 | if (ret) | ||
199 | bus_remove_driver(drv); | ||
200 | return ret; | ||
162 | } | 201 | } |
163 | 202 | ||
164 | /** | 203 | /** |
@@ -170,6 +209,7 @@ int driver_register(struct device_driver * drv) | |||
170 | 209 | ||
171 | void driver_unregister(struct device_driver * drv) | 210 | void driver_unregister(struct device_driver * drv) |
172 | { | 211 | { |
212 | driver_remove_groups(drv, drv->groups); | ||
173 | bus_remove_driver(drv); | 213 | bus_remove_driver(drv); |
174 | } | 214 | } |
175 | 215 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 3f24bf46d298..d974dda4aa51 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -129,6 +129,7 @@ struct device_driver { | |||
129 | void (*shutdown) (struct device * dev); | 129 | void (*shutdown) (struct device * dev); |
130 | int (*suspend) (struct device * dev, pm_message_t state); | 130 | int (*suspend) (struct device * dev, pm_message_t state); |
131 | int (*resume) (struct device * dev); | 131 | int (*resume) (struct device * dev); |
132 | struct attribute_group **groups; | ||
132 | }; | 133 | }; |
133 | 134 | ||
134 | 135 | ||