diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-14 10:30:59 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-01 17:52:00 -0500 |
commit | e55c8790d40fdbc6887b4e3e52afefe4b03f1311 (patch) | |
tree | 4bcf70b8a5f5f4896c4fc942c8def16581ae1228 | |
parent | fcaf71fd51f9cfc504455d3e19ec242e4b2073ed (diff) |
Driver core: convert firmware code to use struct device
Converts from using struct "class_device" to "struct device" making
everything show up properly in /sys/devices/ with symlinks from the
/sys/class directory.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/base/firmware_class.c | 119 |
1 files changed, 57 insertions, 62 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 14615694ae9a..4bad2870c485 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include "base.h" | 22 | #include "base.h" |
23 | 23 | ||
24 | #define to_dev(obj) container_of(obj, struct device, kobj) | ||
25 | |||
24 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); | 26 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); |
25 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); | 27 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
26 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
@@ -86,12 +88,12 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) | |||
86 | 88 | ||
87 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); | 89 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); |
88 | 90 | ||
89 | static void fw_class_dev_release(struct class_device *class_dev); | 91 | static void fw_dev_release(struct device *dev); |
90 | 92 | ||
91 | static int firmware_class_uevent(struct class_device *class_dev, char **envp, | 93 | static int firmware_uevent(struct device *dev, char **envp, int num_envp, |
92 | int num_envp, char *buffer, int buffer_size) | 94 | char *buffer, int buffer_size) |
93 | { | 95 | { |
94 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 96 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
95 | int i = 0, len = 0; | 97 | int i = 0, len = 0; |
96 | 98 | ||
97 | if (!test_bit(FW_STATUS_READY, &fw_priv->status)) | 99 | if (!test_bit(FW_STATUS_READY, &fw_priv->status)) |
@@ -110,21 +112,21 @@ static int firmware_class_uevent(struct class_device *class_dev, char **envp, | |||
110 | 112 | ||
111 | static struct class firmware_class = { | 113 | static struct class firmware_class = { |
112 | .name = "firmware", | 114 | .name = "firmware", |
113 | .uevent = firmware_class_uevent, | 115 | .dev_uevent = firmware_uevent, |
114 | .release = fw_class_dev_release, | 116 | .dev_release = fw_dev_release, |
115 | }; | 117 | }; |
116 | 118 | ||
117 | static ssize_t | 119 | static ssize_t firmware_loading_show(struct device *dev, |
118 | firmware_loading_show(struct class_device *class_dev, char *buf) | 120 | struct device_attribute *attr, char *buf) |
119 | { | 121 | { |
120 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 122 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
121 | int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); | 123 | int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); |
122 | return sprintf(buf, "%d\n", loading); | 124 | return sprintf(buf, "%d\n", loading); |
123 | } | 125 | } |
124 | 126 | ||
125 | /** | 127 | /** |
126 | * firmware_loading_store - set value in the 'loading' control file | 128 | * firmware_loading_store - set value in the 'loading' control file |
127 | * @class_dev: class_device pointer | 129 | * @dev: device pointer |
128 | * @buf: buffer to scan for loading control value | 130 | * @buf: buffer to scan for loading control value |
129 | * @count: number of bytes in @buf | 131 | * @count: number of bytes in @buf |
130 | * | 132 | * |
@@ -134,11 +136,11 @@ firmware_loading_show(struct class_device *class_dev, char *buf) | |||
134 | * 0: Conclude the load and hand the data to the driver code. | 136 | * 0: Conclude the load and hand the data to the driver code. |
135 | * -1: Conclude the load with an error and discard any written data. | 137 | * -1: Conclude the load with an error and discard any written data. |
136 | **/ | 138 | **/ |
137 | static ssize_t | 139 | static ssize_t firmware_loading_store(struct device *dev, |
138 | firmware_loading_store(struct class_device *class_dev, | 140 | struct device_attribute *attr, |
139 | const char *buf, size_t count) | 141 | const char *buf, size_t count) |
140 | { | 142 | { |
141 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 143 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
142 | int loading = simple_strtol(buf, NULL, 10); | 144 | int loading = simple_strtol(buf, NULL, 10); |
143 | 145 | ||
144 | switch (loading) { | 146 | switch (loading) { |
@@ -174,15 +176,14 @@ firmware_loading_store(struct class_device *class_dev, | |||
174 | return count; | 176 | return count; |
175 | } | 177 | } |
176 | 178 | ||
177 | static CLASS_DEVICE_ATTR(loading, 0644, | 179 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); |
178 | firmware_loading_show, firmware_loading_store); | ||
179 | 180 | ||
180 | static ssize_t | 181 | static ssize_t |
181 | firmware_data_read(struct kobject *kobj, | 182 | firmware_data_read(struct kobject *kobj, |
182 | char *buffer, loff_t offset, size_t count) | 183 | char *buffer, loff_t offset, size_t count) |
183 | { | 184 | { |
184 | struct class_device *class_dev = to_class_dev(kobj); | 185 | struct device *dev = to_dev(kobj); |
185 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 186 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
186 | struct firmware *fw; | 187 | struct firmware *fw; |
187 | ssize_t ret_count = count; | 188 | ssize_t ret_count = count; |
188 | 189 | ||
@@ -234,7 +235,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) | |||
234 | 235 | ||
235 | /** | 236 | /** |
236 | * firmware_data_write - write method for firmware | 237 | * firmware_data_write - write method for firmware |
237 | * @kobj: kobject for the class_device | 238 | * @kobj: kobject for the device |
238 | * @buffer: buffer being written | 239 | * @buffer: buffer being written |
239 | * @offset: buffer offset for write in total data store area | 240 | * @offset: buffer offset for write in total data store area |
240 | * @count: buffer size | 241 | * @count: buffer size |
@@ -246,8 +247,8 @@ static ssize_t | |||
246 | firmware_data_write(struct kobject *kobj, | 247 | firmware_data_write(struct kobject *kobj, |
247 | char *buffer, loff_t offset, size_t count) | 248 | char *buffer, loff_t offset, size_t count) |
248 | { | 249 | { |
249 | struct class_device *class_dev = to_class_dev(kobj); | 250 | struct device *dev = to_dev(kobj); |
250 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 251 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
251 | struct firmware *fw; | 252 | struct firmware *fw; |
252 | ssize_t retval; | 253 | ssize_t retval; |
253 | 254 | ||
@@ -280,13 +281,12 @@ static struct bin_attribute firmware_attr_data_tmpl = { | |||
280 | .write = firmware_data_write, | 281 | .write = firmware_data_write, |
281 | }; | 282 | }; |
282 | 283 | ||
283 | static void | 284 | static void fw_dev_release(struct device *dev) |
284 | fw_class_dev_release(struct class_device *class_dev) | ||
285 | { | 285 | { |
286 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 286 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
287 | 287 | ||
288 | kfree(fw_priv); | 288 | kfree(fw_priv); |
289 | kfree(class_dev); | 289 | kfree(dev); |
290 | 290 | ||
291 | module_put(THIS_MODULE); | 291 | module_put(THIS_MODULE); |
292 | } | 292 | } |
@@ -298,26 +298,23 @@ firmware_class_timeout(u_long data) | |||
298 | fw_load_abort(fw_priv); | 298 | fw_load_abort(fw_priv); |
299 | } | 299 | } |
300 | 300 | ||
301 | static inline void | 301 | static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) |
302 | fw_setup_class_device_id(struct class_device *class_dev, struct device *dev) | ||
303 | { | 302 | { |
304 | /* XXX warning we should watch out for name collisions */ | 303 | /* XXX warning we should watch out for name collisions */ |
305 | strlcpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE); | 304 | strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE); |
306 | } | 305 | } |
307 | 306 | ||
308 | static int | 307 | static int fw_register_device(struct device **dev_p, const char *fw_name, |
309 | fw_register_class_device(struct class_device **class_dev_p, | 308 | struct device *device) |
310 | const char *fw_name, struct device *device) | ||
311 | { | 309 | { |
312 | int retval; | 310 | int retval; |
313 | struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), | 311 | struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), |
314 | GFP_KERNEL); | 312 | GFP_KERNEL); |
315 | struct class_device *class_dev = kzalloc(sizeof(*class_dev), | 313 | struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL); |
316 | GFP_KERNEL); | ||
317 | 314 | ||
318 | *class_dev_p = NULL; | 315 | *dev_p = NULL; |
319 | 316 | ||
320 | if (!fw_priv || !class_dev) { | 317 | if (!fw_priv || !f_dev) { |
321 | printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); | 318 | printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); |
322 | retval = -ENOMEM; | 319 | retval = -ENOMEM; |
323 | goto error_kfree; | 320 | goto error_kfree; |
@@ -331,55 +328,54 @@ fw_register_class_device(struct class_device **class_dev_p, | |||
331 | fw_priv->timeout.data = (u_long) fw_priv; | 328 | fw_priv->timeout.data = (u_long) fw_priv; |
332 | init_timer(&fw_priv->timeout); | 329 | init_timer(&fw_priv->timeout); |
333 | 330 | ||
334 | fw_setup_class_device_id(class_dev, device); | 331 | fw_setup_device_id(f_dev, device); |
335 | class_dev->dev = device; | 332 | f_dev->parent = device; |
336 | class_dev->class = &firmware_class; | 333 | f_dev->class = &firmware_class; |
337 | class_set_devdata(class_dev, fw_priv); | 334 | dev_set_drvdata(f_dev, fw_priv); |
338 | retval = class_device_register(class_dev); | 335 | retval = device_register(f_dev); |
339 | if (retval) { | 336 | if (retval) { |
340 | printk(KERN_ERR "%s: class_device_register failed\n", | 337 | printk(KERN_ERR "%s: device_register failed\n", |
341 | __FUNCTION__); | 338 | __FUNCTION__); |
342 | goto error_kfree; | 339 | goto error_kfree; |
343 | } | 340 | } |
344 | *class_dev_p = class_dev; | 341 | *dev_p = f_dev; |
345 | return 0; | 342 | return 0; |
346 | 343 | ||
347 | error_kfree: | 344 | error_kfree: |
348 | kfree(fw_priv); | 345 | kfree(fw_priv); |
349 | kfree(class_dev); | 346 | kfree(f_dev); |
350 | return retval; | 347 | return retval; |
351 | } | 348 | } |
352 | 349 | ||
353 | static int | 350 | static int fw_setup_device(struct firmware *fw, struct device **dev_p, |
354 | fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, | 351 | const char *fw_name, struct device *device, |
355 | const char *fw_name, struct device *device, int uevent) | 352 | int uevent) |
356 | { | 353 | { |
357 | struct class_device *class_dev; | 354 | struct device *f_dev; |
358 | struct firmware_priv *fw_priv; | 355 | struct firmware_priv *fw_priv; |
359 | int retval; | 356 | int retval; |
360 | 357 | ||
361 | *class_dev_p = NULL; | 358 | *dev_p = NULL; |
362 | retval = fw_register_class_device(&class_dev, fw_name, device); | 359 | retval = fw_register_device(&f_dev, fw_name, device); |
363 | if (retval) | 360 | if (retval) |
364 | goto out; | 361 | goto out; |
365 | 362 | ||
366 | /* Need to pin this module until class device is destroyed */ | 363 | /* Need to pin this module until class device is destroyed */ |
367 | __module_get(THIS_MODULE); | 364 | __module_get(THIS_MODULE); |
368 | 365 | ||
369 | fw_priv = class_get_devdata(class_dev); | 366 | fw_priv = dev_get_drvdata(f_dev); |
370 | 367 | ||
371 | fw_priv->fw = fw; | 368 | fw_priv->fw = fw; |
372 | retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data); | 369 | retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); |
373 | if (retval) { | 370 | if (retval) { |
374 | printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", | 371 | printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", |
375 | __FUNCTION__); | 372 | __FUNCTION__); |
376 | goto error_unreg; | 373 | goto error_unreg; |
377 | } | 374 | } |
378 | 375 | ||
379 | retval = class_device_create_file(class_dev, | 376 | retval = device_create_file(f_dev, &dev_attr_loading); |
380 | &class_device_attr_loading); | ||
381 | if (retval) { | 377 | if (retval) { |
382 | printk(KERN_ERR "%s: class_device_create_file failed\n", | 378 | printk(KERN_ERR "%s: device_create_file failed\n", |
383 | __FUNCTION__); | 379 | __FUNCTION__); |
384 | goto error_unreg; | 380 | goto error_unreg; |
385 | } | 381 | } |
@@ -388,11 +384,11 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, | |||
388 | set_bit(FW_STATUS_READY, &fw_priv->status); | 384 | set_bit(FW_STATUS_READY, &fw_priv->status); |
389 | else | 385 | else |
390 | set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); | 386 | set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); |
391 | *class_dev_p = class_dev; | 387 | *dev_p = f_dev; |
392 | goto out; | 388 | goto out; |
393 | 389 | ||
394 | error_unreg: | 390 | error_unreg: |
395 | class_device_unregister(class_dev); | 391 | device_unregister(f_dev); |
396 | out: | 392 | out: |
397 | return retval; | 393 | return retval; |
398 | } | 394 | } |
@@ -401,7 +397,7 @@ static int | |||
401 | _request_firmware(const struct firmware **firmware_p, const char *name, | 397 | _request_firmware(const struct firmware **firmware_p, const char *name, |
402 | struct device *device, int uevent) | 398 | struct device *device, int uevent) |
403 | { | 399 | { |
404 | struct class_device *class_dev; | 400 | struct device *f_dev; |
405 | struct firmware_priv *fw_priv; | 401 | struct firmware_priv *fw_priv; |
406 | struct firmware *firmware; | 402 | struct firmware *firmware; |
407 | int retval; | 403 | int retval; |
@@ -417,12 +413,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
417 | goto out; | 413 | goto out; |
418 | } | 414 | } |
419 | 415 | ||
420 | retval = fw_setup_class_device(firmware, &class_dev, name, device, | 416 | retval = fw_setup_device(firmware, &f_dev, name, device, uevent); |
421 | uevent); | ||
422 | if (retval) | 417 | if (retval) |
423 | goto error_kfree_fw; | 418 | goto error_kfree_fw; |
424 | 419 | ||
425 | fw_priv = class_get_devdata(class_dev); | 420 | fw_priv = dev_get_drvdata(f_dev); |
426 | 421 | ||
427 | if (uevent) { | 422 | if (uevent) { |
428 | if (loading_timeout > 0) { | 423 | if (loading_timeout > 0) { |
@@ -430,7 +425,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
430 | add_timer(&fw_priv->timeout); | 425 | add_timer(&fw_priv->timeout); |
431 | } | 426 | } |
432 | 427 | ||
433 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 428 | kobject_uevent(&f_dev->kobj, KOBJ_ADD); |
434 | wait_for_completion(&fw_priv->completion); | 429 | wait_for_completion(&fw_priv->completion); |
435 | set_bit(FW_STATUS_DONE, &fw_priv->status); | 430 | set_bit(FW_STATUS_DONE, &fw_priv->status); |
436 | del_timer_sync(&fw_priv->timeout); | 431 | del_timer_sync(&fw_priv->timeout); |
@@ -445,7 +440,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
445 | } | 440 | } |
446 | fw_priv->fw = NULL; | 441 | fw_priv->fw = NULL; |
447 | mutex_unlock(&fw_lock); | 442 | mutex_unlock(&fw_lock); |
448 | class_device_unregister(class_dev); | 443 | device_unregister(f_dev); |
449 | goto out; | 444 | goto out; |
450 | 445 | ||
451 | error_kfree_fw: | 446 | error_kfree_fw: |