From 6acf70f078ca42a63397b8b84bf6383b01303009 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 23 Apr 2009 22:31:52 +0800 Subject: driver core: firmware_class: replace kfree(dev) with put_device(dev) against v2.6.30-rc3-next tree. Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8a267c427629..2d296b7f7034 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -356,7 +356,7 @@ static void fw_dev_release(struct device *dev) __free_page(fw_priv->pages[i]); kfree(fw_priv->pages); kfree(fw_priv); - kfree(dev); + put_device(dev); module_put(THIS_MODULE); } @@ -400,14 +400,16 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, retval = device_register(f_dev); if (retval) { dev_err(device, "%s: device_register failed\n", __func__); - goto error_kfree; + put_device(f_dev); + goto error_kfree1; } *dev_p = f_dev; return 0; error_kfree: - kfree(fw_priv); kfree(f_dev); +error_kfree1: + kfree(fw_priv); return retval; } -- cgit v1.2.2 From 309b7d60a345f402bec3cf9caadb53de4028e2aa Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 24 Apr 2009 14:57:00 +0200 Subject: driver core: add BUS_NOTIFY_UNBOUND_DRIVER event This patch adds a new bus notifier event which is emitted _after_ a device is removed from its driver. This event will be used by the dma-api debug code to check if a driver has released all dma allocations for that device. Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 742cbe6b042b..efd00de183b1 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -320,6 +320,10 @@ static void __device_release_driver(struct device *dev) devres_release_all(dev); dev->driver = NULL; klist_remove(&dev->p->knode_driver); + if (dev->bus) + blocking_notifier_call_chain(&dev->bus->p->bus_notifier, + BUS_NOTIFY_UNBOUND_DRIVER, + dev); } } -- cgit v1.2.2 From c0afe7ba5e71d8ab66bc42f90b3e237581d3c509 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 27 Apr 2009 02:38:16 +0200 Subject: driver core: Const-correct platform getbyname functions This converts resource and IRQ getbyname functions for the platform bus to use const char *, I ran into compiler moanings when I tried using a const char * for looking up a certain resource. Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index ead3f64c41d0..59df6290951b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -69,7 +69,8 @@ EXPORT_SYMBOL_GPL(platform_get_irq); * @name: resource name */ struct resource *platform_get_resource_byname(struct platform_device *dev, - unsigned int type, char *name) + unsigned int type, + const char *name) { int i; @@ -88,7 +89,7 @@ EXPORT_SYMBOL_GPL(platform_get_resource_byname); * @dev: platform device * @name: IRQ name */ -int platform_get_irq_byname(struct platform_device *dev, char *name) +int platform_get_irq_byname(struct platform_device *dev, const char *name) { struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); -- cgit v1.2.2 From 59a3cd7f9da60ac4ba8ae5a4cddc48fe4a450129 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 5 May 2009 20:38:28 -0700 Subject: Driver core: fix comment for device_attach() We are looking for matching drivers, not devices. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index efd00de183b1..f0106875f01d 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -226,7 +226,7 @@ static int __device_attach(struct device_driver *drv, void *data) * pair is found, break out and return. * * Returns 1 if the device was bound to a driver; - * 0 if no matching device was found; + * 0 if no matching driver was found; * -ENODEV if the device is not registered. * * When called for a USB interface, @dev->parent->sem must be held. -- cgit v1.2.2 From 9227c47bbdd87f276e08ed17877cc1649f5ed10a Mon Sep 17 00:00:00 2001 From: Dave Young Date: Mon, 11 May 2009 14:18:55 +0800 Subject: driver-core: make sysdev_class_register check kobject_set_name return value sysdev_class_register should check the kobject_set_name return value. Add the return value checking code. Signed-off-by: Dave Young Signed-off-by: Greg Kroah-Hartman --- drivers/base/sys.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 9742a78c9fe4..162355cd745a 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -131,6 +131,8 @@ static struct kset *system_kset; int sysdev_class_register(struct sysdev_class *cls) { + int retval; + pr_debug("Registering sysdev class '%s'\n", cls->name); INIT_LIST_HEAD(&cls->drivers); @@ -138,7 +140,11 @@ int sysdev_class_register(struct sysdev_class *cls) cls->kset.kobj.parent = &system_kset->kobj; cls->kset.kobj.ktype = &ktype_sysdev_class; cls->kset.kobj.kset = system_kset; - kobject_set_name(&cls->kset.kobj, cls->name); + + retval = kobject_set_name(&cls->kset.kobj, cls->name); + if (retval) + return retval; + return kset_register(&cls->kset); } -- cgit v1.2.2 From 401097ea4b89846d66ac78f7f108d49c2e922d9c Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 12 May 2009 13:37:57 -0700 Subject: driver core: synchronize device shutdown A patch series to make .shutdown execute asynchronously. Some drivers's shutdown can take a lot of time. The patches can help save some shutdown time. The patches use Arjan's async API. This patch: synchronize all tasks submitted by .shutdown Signed-off-by: Shaohua Li Cc: Arjan van de Ven Cc: Dmitry Torokhov Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index 1977d4beb89e..7e8576d7822d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -1665,4 +1666,5 @@ void device_shutdown(void) kobject_put(sysfs_dev_char_kobj); kobject_put(sysfs_dev_block_kobj); kobject_put(dev_kobj); + async_synchronize_full(); } -- cgit v1.2.2 From 7fcab099795812a8a08eb3b8c8ddb35c3685045f Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 29 May 2009 11:33:19 +0800 Subject: driver core: fix documentation of request_firmware_nowait request_firmware_nowait declares it can be called in non-sleep contexts, but kthead_run called by request_firmware_nowait may sleep. So fix its documentation and comment to make callers clear about it. Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 2d296b7f7034..242770250584 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -617,8 +617,9 @@ request_firmware_work_func(void *arg) * @cont: function will be called asynchronously when the firmware * request is over. * - * Asynchronous variant of request_firmware() for contexts where - * it is not possible to sleep. + * Asynchronous variant of request_firmware() for user contexts where + * it is not possible to sleep for long time. It can't be called + * in atomic contexts. **/ int request_firmware_nowait( -- cgit v1.2.2 From 976821d756c53b421d7c58a9ed60125016d330aa Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 27 May 2009 00:49:31 +0200 Subject: firmware: allocate firmware id dynamically The firmware loader has a statically allocated 30 bytes long string for the firmware id (a.k.a. the firmware file name). There is no reason why we couldnt allocate it dynamically, and avoid having restrictions on the firmware names lengths. Signed-off-by: Samuel Ortiz Cc: Marcel Holtmann Cc: Zhu Yi , Cc: John Linville Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 242770250584..3591ba7ff6f7 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -40,7 +40,7 @@ static int loading_timeout = 60; /* In seconds */ static DEFINE_MUTEX(fw_lock); struct firmware_priv { - char fw_id[FIRMWARE_NAME_MAX]; + char *fw_id; struct completion completion; struct bin_attribute attr_data; struct firmware *fw; @@ -355,6 +355,7 @@ static void fw_dev_release(struct device *dev) for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); kfree(fw_priv->pages); + kfree(fw_priv->fw_id); kfree(fw_priv); put_device(dev); @@ -386,7 +387,13 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, init_completion(&fw_priv->completion); fw_priv->attr_data = firmware_attr_data_tmpl; - strlcpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX); + fw_priv->fw_id = kstrdup(fw_name, GFP_KERNEL); + if (!fw_priv->fw_id) { + dev_err(device, "%s: Firmware name allocation failed\n", + __func__); + retval = -ENOMEM; + goto error_kfree; + } fw_priv->timeout.function = firmware_class_timeout; fw_priv->timeout.data = (u_long) fw_priv; @@ -401,14 +408,15 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, if (retval) { dev_err(device, "%s: device_register failed\n", __func__); put_device(f_dev); - goto error_kfree1; + goto error_kfree_fw_id; } *dev_p = f_dev; return 0; +error_kfree_fw_id: + kfree(fw_priv->fw_id); error_kfree: kfree(f_dev); -error_kfree1: kfree(fw_priv); return retval; } -- cgit v1.2.2 From acc0e90fbccbc6e4d48184cba0983ea044e131af Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Jun 2009 15:39:55 -0700 Subject: driver core: fix gcc 4.3.3 warnings about string literals This removes the warning: format not a string literal and no format arguments warnings in the driver core that gcc 4.3.3 complains about. Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- drivers/base/firmware_class.c | 2 +- drivers/base/platform.c | 2 +- drivers/base/sys.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index 7e8576d7822d..4d59975c24a8 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -875,7 +875,7 @@ int device_add(struct device *dev) * the name, and force the use of dev_name() */ if (dev->init_name) { - dev_set_name(dev, dev->init_name); + dev_set_name(dev, "%s", dev->init_name); dev->init_name = NULL; } @@ -1272,7 +1272,7 @@ struct device *__root_device_register(const char *name, struct module *owner) if (!root) return ERR_PTR(err); - err = dev_set_name(&root->dev, name); + err = dev_set_name(&root->dev, "%s", name); if (err) { kfree(root); return ERR_PTR(err); diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3591ba7ff6f7..ddeb819c8f87 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -399,7 +399,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, fw_priv->timeout.data = (u_long) fw_priv; init_timer(&fw_priv->timeout); - dev_set_name(f_dev, dev_name(device)); + dev_set_name(f_dev, "%s", dev_name(device)); f_dev->parent = device; f_dev->class = &firmware_class; dev_set_drvdata(f_dev, fw_priv); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 59df6290951b..81cb01bfc356 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -245,7 +245,7 @@ int platform_device_add(struct platform_device *pdev) if (pdev->id != -1) dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); else - dev_set_name(&pdev->dev, pdev->name); + dev_set_name(&pdev->dev, "%s", pdev->name); for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 162355cd745a..79a9ae5238ac 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class *cls) cls->kset.kobj.ktype = &ktype_sysdev_class; cls->kset.kobj.kset = system_kset; - retval = kobject_set_name(&cls->kset.kobj, cls->name); + retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name); if (retval) return retval; -- cgit v1.2.2 From 6fcf53acccf85b4b0d0260e66c692a341760f464 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Apr 2009 15:23:42 +0200 Subject: Driver Core: add nodename callbacks This adds the nodename callback for struct class, struct device_type and struct device, to allow drivers to send userspace hints on the device name and subdirectory that should be used for it. Signed-off-by: Kay Sievers Signed-off-by: Jan Blunck Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index 4d59975c24a8..7ecb1938e590 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -162,10 +162,18 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, struct device *dev = to_dev(kobj); int retval = 0; - /* add the major/minor if present */ + /* add device node properties if present */ if (MAJOR(dev->devt)) { + const char *tmp; + const char *name; + add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); + name = device_get_nodename(dev, &tmp); + if (name) { + add_uevent_var(env, "DEVNAME=%s", name); + kfree(tmp); + } } if (dev->type && dev->type->name) @@ -1128,6 +1136,47 @@ static struct device *next_device(struct klist_iter *i) return dev; } +/** + * device_get_nodename - path of device node file + * @dev: device + * @tmp: possibly allocated string + * + * Return the relative path of a possible device node. + * Non-default names may need to allocate a memory to compose + * a name. This memory is returned in tmp and needs to be + * freed by the caller. + */ +const char *device_get_nodename(struct device *dev, const char **tmp) +{ + char *s; + + *tmp = NULL; + + /* the device type may provide a specific name */ + if (dev->type && dev->type->nodename) + *tmp = dev->type->nodename(dev); + if (*tmp) + return *tmp; + + /* the class may provide a specific name */ + if (dev->class && dev->class->nodename) + *tmp = dev->class->nodename(dev); + if (*tmp) + return *tmp; + + /* return name without allocation, tmp == NULL */ + if (strchr(dev_name(dev), '!') == NULL) + return dev_name(dev); + + /* replace '!' in the name with '/' */ + *tmp = kstrdup(dev_name(dev), GFP_KERNEL); + if (!*tmp) + return NULL; + while ((s = strchr(*tmp, '!'))) + s[0] = '/'; + return *tmp; +} + /** * device_for_each_child - device child iterator. * @parent: parent struct device. -- cgit v1.2.2