| From foo@baz Sun Jan 25 20:47:00 PST 2009 |
| Date: Sun, 25 Jan 2009 20:47:00 -0800 |
| To: Greg KH <greg@kroah.com> |
| From: Greg Kroah-Hartman <gregkh@suse.de> |
| Subject: Driver core: device_initialize can return a value |
| |
| Make device_initialize return a value if everything went well or not. |
| This allows us in the future to change the function to allocate memory |
| and properly handle error conditions. |
| |
| It is not marked __must_check yet, as the rest of the kernel tree has |
| not been fixed to check the value yet. That will be in future patches. |
| |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| drivers/base/core.c | 13 ++++++++++--- |
| drivers/base/platform.c | 13 ++++++++++--- |
| include/linux/device.h | 2 +- |
| 3 files changed, 21 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/base/core.c |
| +++ b/drivers/base/core.c |
| @@ -547,7 +547,7 @@ static void klist_children_put(struct kl |
| * NOTE: Use put_device() to give up your reference instead of freeing |
| * @dev directly once you have called this function. |
| */ |
| -void device_initialize(struct device *dev) |
| +int device_initialize(struct device *dev) |
| { |
| dev->kobj.kset = devices_kset; |
| kobject_init(&dev->kobj, &device_ktype); |
| @@ -558,6 +558,7 @@ void device_initialize(struct device *de |
| INIT_LIST_HEAD(&dev->devres_head); |
| device_pm_init(dev); |
| set_dev_node(dev, -1); |
| + return 0; |
| } |
| |
| static struct kobject *virtual_device_parent(struct device *dev) |
| @@ -1005,7 +1006,11 @@ name_error: |
| */ |
| int device_register(struct device *dev) |
| { |
| - device_initialize(dev); |
| + int retval; |
| + |
| + retval = device_initialize(dev); |
| + if (retval) |
| + return retval; |
| return device_add(dev); |
| } |
| |
| @@ -1389,7 +1394,9 @@ int device_init_and_add(struct device *d |
| dev->bus = bus; |
| dev->release = release; |
| |
| - device_initialize(dev); |
| + err = device_initialize(dev); |
| + if (err) |
| + return err; |
| |
| va_start(vargs, name); |
| err = kobject_set_name_vargs(&dev->kobj, name, vargs); |
| --- a/drivers/base/platform.c |
| +++ b/drivers/base/platform.c |
| @@ -170,8 +170,11 @@ struct platform_device *platform_device_ |
| strcpy(pa->name, name); |
| pa->pdev.name = pa->name; |
| pa->pdev.id = id; |
| - device_initialize(&pa->pdev.dev); |
| - pa->pdev.dev.release = platform_device_release; |
| + if (device_initialize(&pa->pdev.dev)) { |
| + kfree(pa); |
| + pa = NULL; |
| + } else |
| + pa->pdev.dev.release = platform_device_release; |
| } |
| |
| return pa ? &pa->pdev : NULL; |
| @@ -332,7 +335,11 @@ EXPORT_SYMBOL_GPL(platform_device_del); |
| */ |
| int platform_device_register(struct platform_device *pdev) |
| { |
| - device_initialize(&pdev->dev); |
| + int retval; |
| + |
| + retval = device_initialize(&pdev->dev); |
| + if (retval) |
| + return retval; |
| return platform_device_add(pdev); |
| } |
| EXPORT_SYMBOL_GPL(platform_device_register); |
| --- a/include/linux/device.h |
| +++ b/include/linux/device.h |
| @@ -545,7 +545,7 @@ void driver_init(void); |
| */ |
| extern int __must_check device_register(struct device *dev); |
| extern void device_unregister(struct device *dev); |
| -extern void device_initialize(struct device *dev); |
| +extern int device_initialize(struct device *dev); |
| extern int __must_check device_add(struct device *dev); |
| extern int __must_check device_init_and_add(struct device *dev, |
| struct device *parent, |