Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 7366
b: refs/heads/master
c: 6e3eaab
h: refs/heads/master
v: v3
  • Loading branch information
Abhay Salunke authored and Linus Torvalds committed Sep 7, 2005
1 parent edb8036 commit 654c660
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f3ef6f63e5c575c136b39bb423a6e9a002932da7
refs/heads/master: 6e3eaab02028c4087a92711b20abb9e72cc803a7
79 changes: 50 additions & 29 deletions trunk/drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum {
FW_STATUS_DONE,
FW_STATUS_ABORT,
FW_STATUS_READY,
FW_STATUS_READY_NOHOTPLUG,
};

static int loading_timeout = 10; /* In seconds */
Expand Down Expand Up @@ -344,7 +345,7 @@ fw_register_class_device(struct class_device **class_dev_p,

static int
fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
const char *fw_name, struct device *device)
const char *fw_name, struct device *device, int hotplug)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
Expand Down Expand Up @@ -376,7 +377,10 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
goto error_unreg;
}

set_bit(FW_STATUS_READY, &fw_priv->status);
if (hotplug)
set_bit(FW_STATUS_READY, &fw_priv->status);
else
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
*class_dev_p = class_dev;
goto out;

Expand All @@ -386,21 +390,9 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
return retval;
}

/**
* request_firmware: - request firmware to hotplug and wait for it
* Description:
* @firmware will be used to return a firmware image by the name
* of @name for device @device.
*
* Should be called from user context where sleeping is allowed.
*
* @name will be use as $FIRMWARE in the hotplug environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
int
request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device)
static int
_request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device, int hotplug)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
Expand All @@ -419,22 +411,25 @@ request_firmware(const struct firmware **firmware_p, const char *name,
}
memset(firmware, 0, sizeof (*firmware));

retval = fw_setup_class_device(firmware, &class_dev, name, device);
retval = fw_setup_class_device(firmware, &class_dev, name, device,
hotplug);
if (retval)
goto error_kfree_fw;

fw_priv = class_get_devdata(class_dev);

if (loading_timeout > 0) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout);
}

kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status);
if (hotplug) {
if (loading_timeout > 0) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout);
}

del_timer_sync(&fw_priv->timeout);
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout);
} else
wait_for_completion(&fw_priv->completion);

down(&fw_lock);
if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
Expand All @@ -454,6 +449,26 @@ request_firmware(const struct firmware **firmware_p, const char *name,
return retval;
}

/**
* request_firmware: - request firmware to hotplug and wait for it
* Description:
* @firmware will be used to return a firmware image by the name
* of @name for device @device.
*
* Should be called from user context where sleeping is allowed.
*
* @name will be use as $FIRMWARE in the hotplug environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
int
request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device)
{
int hotplug = 1;
return _request_firmware(firmware_p, name, device, hotplug);
}

/**
* release_firmware: - release the resource associated with a firmware image
**/
Expand Down Expand Up @@ -491,6 +506,7 @@ struct firmware_work {
struct device *device;
void *context;
void (*cont)(const struct firmware *fw, void *context);
int hotplug;
};

static int
Expand All @@ -503,7 +519,8 @@ request_firmware_work_func(void *arg)
return 0;
}
daemonize("%s/%s", "firmware", fw_work->name);
request_firmware(&fw, fw_work->name, fw_work->device);
_request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->hotplug);
fw_work->cont(fw, fw_work->context);
release_firmware(fw);
module_put(fw_work->module);
Expand All @@ -518,6 +535,9 @@ request_firmware_work_func(void *arg)
* Asynchronous variant of request_firmware() for contexts where
* it is not possible to sleep.
*
* @hotplug invokes hotplug event to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
*
* @cont will be called asynchronously when the firmware request is over.
*
* @context will be passed over to @cont.
Expand All @@ -527,7 +547,7 @@ request_firmware_work_func(void *arg)
**/
int
request_firmware_nowait(
struct module *module,
struct module *module, int hotplug,
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
Expand All @@ -548,6 +568,7 @@ request_firmware_nowait(
.device = device,
.context = context,
.cont = cont,
.hotplug = hotplug,
};

ret = kernel_thread(request_firmware_work_func, fw_work,
Expand Down
5 changes: 4 additions & 1 deletion trunk/include/linux/firmware.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <linux/module.h>
#include <linux/types.h>
#define FIRMWARE_NAME_MAX 30
#define FW_ACTION_NOHOTPLUG 0
#define FW_ACTION_HOTPLUG 1

struct firmware {
size_t size;
u8 *data;
Expand All @@ -11,7 +14,7 @@ struct device;
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
int request_firmware_nowait(
struct module *module,
struct module *module, int hotplug,
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context));

Expand Down

0 comments on commit 654c660

Please sign in to comment.