Commit e55c8790 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent fcaf71fd
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include "base.h" #include "base.h"
#define to_dev(obj) container_of(obj, struct device, kobj)
MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_DESCRIPTION("Multi purpose firmware loading support");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -86,12 +88,12 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) ...@@ -86,12 +88,12 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
static void fw_class_dev_release(struct class_device *class_dev); static void fw_dev_release(struct device *dev);
static int firmware_class_uevent(struct class_device *class_dev, char **envp, static int firmware_uevent(struct device *dev, char **envp, int num_envp,
int num_envp, char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
int i = 0, len = 0; int i = 0, len = 0;
if (!test_bit(FW_STATUS_READY, &fw_priv->status)) 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,21 +112,21 @@ static int firmware_class_uevent(struct class_device *class_dev, char **envp,
static struct class firmware_class = { static struct class firmware_class = {
.name = "firmware", .name = "firmware",
.uevent = firmware_class_uevent, .dev_uevent = firmware_uevent,
.release = fw_class_dev_release, .dev_release = fw_dev_release,
}; };
static ssize_t static ssize_t firmware_loading_show(struct device *dev,
firmware_loading_show(struct class_device *class_dev, char *buf) struct device_attribute *attr, char *buf)
{ {
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
return sprintf(buf, "%d\n", loading); return sprintf(buf, "%d\n", loading);
} }
/** /**
* firmware_loading_store - set value in the 'loading' control file * firmware_loading_store - set value in the 'loading' control file
* @class_dev: class_device pointer * @dev: device pointer
* @buf: buffer to scan for loading control value * @buf: buffer to scan for loading control value
* @count: number of bytes in @buf * @count: number of bytes in @buf
* *
...@@ -134,11 +136,11 @@ firmware_loading_show(struct class_device *class_dev, char *buf) ...@@ -134,11 +136,11 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
* 0: Conclude the load and hand the data to the driver code. * 0: Conclude the load and hand the data to the driver code.
* -1: Conclude the load with an error and discard any written data. * -1: Conclude the load with an error and discard any written data.
**/ **/
static ssize_t static ssize_t firmware_loading_store(struct device *dev,
firmware_loading_store(struct class_device *class_dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
int loading = simple_strtol(buf, NULL, 10); int loading = simple_strtol(buf, NULL, 10);
switch (loading) { switch (loading) {
...@@ -174,15 +176,14 @@ firmware_loading_store(struct class_device *class_dev, ...@@ -174,15 +176,14 @@ firmware_loading_store(struct class_device *class_dev,
return count; return count;
} }
static CLASS_DEVICE_ATTR(loading, 0644, static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
firmware_loading_show, firmware_loading_store);
static ssize_t static ssize_t
firmware_data_read(struct kobject *kobj, firmware_data_read(struct kobject *kobj,
char *buffer, loff_t offset, size_t count) char *buffer, loff_t offset, size_t count)
{ {
struct class_device *class_dev = to_class_dev(kobj); struct device *dev = to_dev(kobj);
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
struct firmware *fw; struct firmware *fw;
ssize_t ret_count = count; ssize_t ret_count = count;
...@@ -234,7 +235,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) ...@@ -234,7 +235,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
/** /**
* firmware_data_write - write method for firmware * firmware_data_write - write method for firmware
* @kobj: kobject for the class_device * @kobj: kobject for the device
* @buffer: buffer being written * @buffer: buffer being written
* @offset: buffer offset for write in total data store area * @offset: buffer offset for write in total data store area
* @count: buffer size * @count: buffer size
...@@ -246,8 +247,8 @@ static ssize_t ...@@ -246,8 +247,8 @@ static ssize_t
firmware_data_write(struct kobject *kobj, firmware_data_write(struct kobject *kobj,
char *buffer, loff_t offset, size_t count) char *buffer, loff_t offset, size_t count)
{ {
struct class_device *class_dev = to_class_dev(kobj); struct device *dev = to_dev(kobj);
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
struct firmware *fw; struct firmware *fw;
ssize_t retval; ssize_t retval;
...@@ -280,13 +281,12 @@ static struct bin_attribute firmware_attr_data_tmpl = { ...@@ -280,13 +281,12 @@ static struct bin_attribute firmware_attr_data_tmpl = {
.write = firmware_data_write, .write = firmware_data_write,
}; };
static void static void fw_dev_release(struct device *dev)
fw_class_dev_release(struct class_device *class_dev)
{ {
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = dev_get_drvdata(dev);
kfree(fw_priv); kfree(fw_priv);
kfree(class_dev); kfree(dev);
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
...@@ -298,26 +298,23 @@ firmware_class_timeout(u_long data) ...@@ -298,26 +298,23 @@ firmware_class_timeout(u_long data)
fw_load_abort(fw_priv); fw_load_abort(fw_priv);
} }
static inline void static inline void fw_setup_device_id(struct device *f_dev, struct device *dev)
fw_setup_class_device_id(struct class_device *class_dev, struct device *dev)
{ {
/* XXX warning we should watch out for name collisions */ /* XXX warning we should watch out for name collisions */
strlcpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE); strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE);
} }
static int static int fw_register_device(struct device **dev_p, const char *fw_name,
fw_register_class_device(struct class_device **class_dev_p, struct device *device)
const char *fw_name, struct device *device)
{ {
int retval; int retval;
struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv),
GFP_KERNEL); GFP_KERNEL);
struct class_device *class_dev = kzalloc(sizeof(*class_dev), struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL);
GFP_KERNEL);
*class_dev_p = NULL; *dev_p = NULL;
if (!fw_priv || !class_dev) { if (!fw_priv || !f_dev) {
printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__);
retval = -ENOMEM; retval = -ENOMEM;
goto error_kfree; goto error_kfree;
...@@ -331,55 +328,54 @@ fw_register_class_device(struct class_device **class_dev_p, ...@@ -331,55 +328,54 @@ fw_register_class_device(struct class_device **class_dev_p,
fw_priv->timeout.data = (u_long) fw_priv; fw_priv->timeout.data = (u_long) fw_priv;
init_timer(&fw_priv->timeout); init_timer(&fw_priv->timeout);
fw_setup_class_device_id(class_dev, device); fw_setup_device_id(f_dev, device);
class_dev->dev = device; f_dev->parent = device;
class_dev->class = &firmware_class; f_dev->class = &firmware_class;
class_set_devdata(class_dev, fw_priv); dev_set_drvdata(f_dev, fw_priv);
retval = class_device_register(class_dev); retval = device_register(f_dev);
if (retval) { if (retval) {
printk(KERN_ERR "%s: class_device_register failed\n", printk(KERN_ERR "%s: device_register failed\n",
__FUNCTION__); __FUNCTION__);
goto error_kfree; goto error_kfree;
} }
*class_dev_p = class_dev; *dev_p = f_dev;
return 0; return 0;
error_kfree: error_kfree:
kfree(fw_priv); kfree(fw_priv);
kfree(class_dev); kfree(f_dev);
return retval; return retval;
} }
static int static int fw_setup_device(struct firmware *fw, struct device **dev_p,
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 uevent) int uevent)
{ {
struct class_device *class_dev; struct device *f_dev;
struct firmware_priv *fw_priv; struct firmware_priv *fw_priv;
int retval; int retval;
*class_dev_p = NULL; *dev_p = NULL;
retval = fw_register_class_device(&class_dev, fw_name, device); retval = fw_register_device(&f_dev, fw_name, device);
if (retval) if (retval)
goto out; goto out;
/* Need to pin this module until class device is destroyed */ /* Need to pin this module until class device is destroyed */
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
fw_priv = class_get_devdata(class_dev); fw_priv = dev_get_drvdata(f_dev);
fw_priv->fw = fw; fw_priv->fw = fw;
retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data); retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
if (retval) { if (retval) {
printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
__FUNCTION__); __FUNCTION__);
goto error_unreg; goto error_unreg;
} }
retval = class_device_create_file(class_dev, retval = device_create_file(f_dev, &dev_attr_loading);
&class_device_attr_loading);
if (retval) { if (retval) {
printk(KERN_ERR "%s: class_device_create_file failed\n", printk(KERN_ERR "%s: device_create_file failed\n",
__FUNCTION__); __FUNCTION__);
goto error_unreg; goto error_unreg;
} }
...@@ -388,11 +384,11 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, ...@@ -388,11 +384,11 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
set_bit(FW_STATUS_READY, &fw_priv->status); set_bit(FW_STATUS_READY, &fw_priv->status);
else else
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
*class_dev_p = class_dev; *dev_p = f_dev;
goto out; goto out;
error_unreg: error_unreg:
class_device_unregister(class_dev); device_unregister(f_dev);
out: out:
return retval; return retval;
} }
...@@ -401,7 +397,7 @@ static int ...@@ -401,7 +397,7 @@ static int
_request_firmware(const struct firmware **firmware_p, const char *name, _request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device, int uevent) struct device *device, int uevent)
{ {
struct class_device *class_dev; struct device *f_dev;
struct firmware_priv *fw_priv; struct firmware_priv *fw_priv;
struct firmware *firmware; struct firmware *firmware;
int retval; int retval;
...@@ -417,12 +413,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name, ...@@ -417,12 +413,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
goto out; goto out;
} }
retval = fw_setup_class_device(firmware, &class_dev, name, device, retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
uevent);
if (retval) if (retval)
goto error_kfree_fw; goto error_kfree_fw;
fw_priv = class_get_devdata(class_dev); fw_priv = dev_get_drvdata(f_dev);
if (uevent) { if (uevent) {
if (loading_timeout > 0) { if (loading_timeout > 0) {
...@@ -430,7 +425,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, ...@@ -430,7 +425,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
add_timer(&fw_priv->timeout); add_timer(&fw_priv->timeout);
} }
kobject_uevent(&class_dev->kobj, KOBJ_ADD); kobject_uevent(&f_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion); wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status); set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout); del_timer_sync(&fw_priv->timeout);
...@@ -445,7 +440,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, ...@@ -445,7 +440,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
} }
fw_priv->fw = NULL; fw_priv->fw = NULL;
mutex_unlock(&fw_lock); mutex_unlock(&fw_lock);
class_device_unregister(class_dev); device_unregister(f_dev);
goto out; goto out;
error_kfree_fw: error_kfree_fw:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment