aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
authorAbhay Salunke <Abhay_Salunke@dell.com>2005-09-06 18:17:13 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:26 -0400
commit6e3eaab02028c4087a92711b20abb9e72cc803a7 (patch)
tree4b1cb2be9d74307ff7fd5517b2f03d6e8b19171a /drivers/base/firmware_class.c
parentf3ef6f63e5c575c136b39bb423a6e9a002932da7 (diff)
[PATCH] modified firmware_class.c to support no hotplug
Upgrade the request_firmware_nowait function to not start the hotplug action on a firmware update. This patch is tested along with dell_rbu driver on i386 and x86-64 systems. Signed-off-by: Abhay Salunke <Abhay_Salunke@dell.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c79
1 files changed, 50 insertions, 29 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 652281402c92..5bfa2e9a7c26 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -28,6 +28,7 @@ enum {
28 FW_STATUS_DONE, 28 FW_STATUS_DONE,
29 FW_STATUS_ABORT, 29 FW_STATUS_ABORT,
30 FW_STATUS_READY, 30 FW_STATUS_READY,
31 FW_STATUS_READY_NOHOTPLUG,
31}; 32};
32 33
33static int loading_timeout = 10; /* In seconds */ 34static int loading_timeout = 10; /* In seconds */
@@ -344,7 +345,7 @@ error_kfree:
344 345
345static int 346static int
346fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, 347fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
347 const char *fw_name, struct device *device) 348 const char *fw_name, struct device *device, int hotplug)
348{ 349{
349 struct class_device *class_dev; 350 struct class_device *class_dev;
350 struct firmware_priv *fw_priv; 351 struct firmware_priv *fw_priv;
@@ -376,7 +377,10 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
376 goto error_unreg; 377 goto error_unreg;
377 } 378 }
378 379
379 set_bit(FW_STATUS_READY, &fw_priv->status); 380 if (hotplug)
381 set_bit(FW_STATUS_READY, &fw_priv->status);
382 else
383 set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
380 *class_dev_p = class_dev; 384 *class_dev_p = class_dev;
381 goto out; 385 goto out;
382 386
@@ -386,21 +390,9 @@ out:
386 return retval; 390 return retval;
387} 391}
388 392
389/** 393static int
390 * request_firmware: - request firmware to hotplug and wait for it 394_request_firmware(const struct firmware **firmware_p, const char *name,
391 * Description: 395 struct device *device, int hotplug)
392 * @firmware will be used to return a firmware image by the name
393 * of @name for device @device.
394 *
395 * Should be called from user context where sleeping is allowed.
396 *
397 * @name will be use as $FIRMWARE in the hotplug environment and
398 * should be distinctive enough not to be confused with any other
399 * firmware image for this or any other device.
400 **/
401int
402request_firmware(const struct firmware **firmware_p, const char *name,
403 struct device *device)
404{ 396{
405 struct class_device *class_dev; 397 struct class_device *class_dev;
406 struct firmware_priv *fw_priv; 398 struct firmware_priv *fw_priv;
@@ -419,22 +411,25 @@ request_firmware(const struct firmware **firmware_p, const char *name,
419 } 411 }
420 memset(firmware, 0, sizeof (*firmware)); 412 memset(firmware, 0, sizeof (*firmware));
421 413
422 retval = fw_setup_class_device(firmware, &class_dev, name, device); 414 retval = fw_setup_class_device(firmware, &class_dev, name, device,
415 hotplug);
423 if (retval) 416 if (retval)
424 goto error_kfree_fw; 417 goto error_kfree_fw;
425 418
426 fw_priv = class_get_devdata(class_dev); 419 fw_priv = class_get_devdata(class_dev);
427 420
428 if (loading_timeout > 0) { 421 if (hotplug) {
429 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 422 if (loading_timeout > 0) {
430 add_timer(&fw_priv->timeout); 423 fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
431 } 424 add_timer(&fw_priv->timeout);
432 425 }
433 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
434 wait_for_completion(&fw_priv->completion);
435 set_bit(FW_STATUS_DONE, &fw_priv->status);
436 426
437 del_timer_sync(&fw_priv->timeout); 427 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
428 wait_for_completion(&fw_priv->completion);
429 set_bit(FW_STATUS_DONE, &fw_priv->status);
430 del_timer_sync(&fw_priv->timeout);
431 } else
432 wait_for_completion(&fw_priv->completion);
438 433
439 down(&fw_lock); 434 down(&fw_lock);
440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 435 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
@@ -455,6 +450,26 @@ out:
455} 450}
456 451
457/** 452/**
453 * request_firmware: - request firmware to hotplug and wait for it
454 * Description:
455 * @firmware will be used to return a firmware image by the name
456 * of @name for device @device.
457 *
458 * Should be called from user context where sleeping is allowed.
459 *
460 * @name will be use as $FIRMWARE in the hotplug environment and
461 * should be distinctive enough not to be confused with any other
462 * firmware image for this or any other device.
463 **/
464int
465request_firmware(const struct firmware **firmware_p, const char *name,
466 struct device *device)
467{
468 int hotplug = 1;
469 return _request_firmware(firmware_p, name, device, hotplug);
470}
471
472/**
458 * release_firmware: - release the resource associated with a firmware image 473 * release_firmware: - release the resource associated with a firmware image
459 **/ 474 **/
460void 475void
@@ -491,6 +506,7 @@ struct firmware_work {
491 struct device *device; 506 struct device *device;
492 void *context; 507 void *context;
493 void (*cont)(const struct firmware *fw, void *context); 508 void (*cont)(const struct firmware *fw, void *context);
509 int hotplug;
494}; 510};
495 511
496static int 512static int
@@ -503,7 +519,8 @@ request_firmware_work_func(void *arg)
503 return 0; 519 return 0;
504 } 520 }
505 daemonize("%s/%s", "firmware", fw_work->name); 521 daemonize("%s/%s", "firmware", fw_work->name);
506 request_firmware(&fw, fw_work->name, fw_work->device); 522 _request_firmware(&fw, fw_work->name, fw_work->device,
523 fw_work->hotplug);
507 fw_work->cont(fw, fw_work->context); 524 fw_work->cont(fw, fw_work->context);
508 release_firmware(fw); 525 release_firmware(fw);
509 module_put(fw_work->module); 526 module_put(fw_work->module);
@@ -518,6 +535,9 @@ request_firmware_work_func(void *arg)
518 * Asynchronous variant of request_firmware() for contexts where 535 * Asynchronous variant of request_firmware() for contexts where
519 * it is not possible to sleep. 536 * it is not possible to sleep.
520 * 537 *
538 * @hotplug invokes hotplug event to copy the firmware image if this flag
539 * is non-zero else the firmware copy must be done manually.
540 *
521 * @cont will be called asynchronously when the firmware request is over. 541 * @cont will be called asynchronously when the firmware request is over.
522 * 542 *
523 * @context will be passed over to @cont. 543 * @context will be passed over to @cont.
@@ -527,7 +547,7 @@ request_firmware_work_func(void *arg)
527 **/ 547 **/
528int 548int
529request_firmware_nowait( 549request_firmware_nowait(
530 struct module *module, 550 struct module *module, int hotplug,
531 const char *name, struct device *device, void *context, 551 const char *name, struct device *device, void *context,
532 void (*cont)(const struct firmware *fw, void *context)) 552 void (*cont)(const struct firmware *fw, void *context))
533{ 553{
@@ -548,6 +568,7 @@ request_firmware_nowait(
548 .device = device, 568 .device = device,
549 .context = context, 569 .context = context,
550 .cont = cont, 570 .cont = cont,
571 .hotplug = hotplug,
551 }; 572 };
552 573
553 ret = kernel_thread(request_firmware_work_func, fw_work, 574 ret = kernel_thread(request_firmware_work_func, fw_work,