From 02fbe5e61df654b2b39a1ddc1ae912c9e14c3ddd Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 17 Apr 2012 12:13:18 +0200 Subject: devtmpfs: fix 'the the' typo Signed-off-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 8493536ea55b..765c3a28077a 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -7,9 +7,9 @@ * devtmpfs, a tmpfs-based filesystem is created. Every driver-core * device which requests a device node, will add a node in this * filesystem. - * By default, all devices are named after the the name of the - * device, owned by root and have a default mode of 0600. Subsystems - * can overwrite the default setting if needed. + * By default, all devices are named after the name of the device, + * owned by root and have a default mode of 0600. Subsystems can + * overwrite the default setting if needed. */ #include -- cgit v1.2.3 From 0d4e293ca8271cc7d7ac1423afe5ceb7d213d0fc Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 17 Apr 2012 12:12:57 +0200 Subject: core.c: fix 'the the' typo Signed-off-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index e28ce9898af4..6cb25f1511df 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -878,8 +878,8 @@ EXPORT_SYMBOL_GPL(dev_set_name); * to NULL prevents an entry from being created. class->dev_kobj must * be set (or cleared) before any devices are registered to the class * otherwise device_create_sys_dev_entry() and - * device_remove_sys_dev_entry() will disagree about the the presence - * of the link. + * device_remove_sys_dev_entry() will disagree about the presence of + * the link. */ static struct kobject *device_to_dev_kobj(struct device *dev) { -- cgit v1.2.3 From efb4df82ca97b3c1cadd03bb98bce7a7e206fa63 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Apr 2012 17:03:30 -0700 Subject: driver core: fix dma-buf.c kernel-doc warnings Fix kernel-doc warnings in dma-buf.c: Warning(drivers/base/dma-buf.c:305): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:305): Excess function parameter 'dma_buf' description in 'dma_buf_begin_cpu_access' Warning(drivers/base/dma-buf.c:332): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:332): Excess function parameter 'dma_buf' description in 'dma_buf_end_cpu_access' Warning(drivers/base/dma-buf.c:350): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:350): Excess function parameter 'dma_buf' description in 'dma_buf_kmap_atomic' Warning(drivers/base/dma-buf.c:367): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:367): Excess function parameter 'dma_buf' description in 'dma_buf_kunmap_atomic' Warning(drivers/base/dma-buf.c:385): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:385): Excess function parameter 'dma_buf' description in 'dma_buf_kmap' Warning(drivers/base/dma-buf.c:402): No description found for parameter 'dmabuf' Warning(drivers/base/dma-buf.c:402): Excess function parameter 'dma_buf' description in 'dma_buf_kunmap' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/base/dma-buf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 07cbbc6fddb4..05c64c11bad2 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); * cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific * preparations. Coherency is only guaranteed in the specified range for the * specified access direction. - * @dma_buf: [in] buffer to prepare cpu access for. + * @dmabuf: [in] buffer to prepare cpu access for. * @start: [in] start of range for cpu access. * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. @@ -320,7 +320,7 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific * actions. Coherency is only guaranteed in the specified range for the * specified access direction. - * @dma_buf: [in] buffer to complete cpu access for. + * @dmabuf: [in] buffer to complete cpu access for. * @start: [in] start of range for cpu access. * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. @@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); /** * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address * space. The same restrictions as for kmap_atomic and friends apply. - * @dma_buf: [in] buffer to map page from. + * @dmabuf: [in] buffer to map page from. * @page_num: [in] page in PAGE_SIZE units to map. * * This call must always succeed, any necessary preparations that might fail @@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap_atomic); /** * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. - * @dma_buf: [in] buffer to unmap page from. + * @dmabuf: [in] buffer to unmap page from. * @page_num: [in] page in PAGE_SIZE units to unmap. * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap_atomic. * @@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap_atomic); /** * dma_buf_kmap - Map a page of the buffer object into kernel address space. The * same restrictions as for kmap and friends apply. - * @dma_buf: [in] buffer to map page from. + * @dmabuf: [in] buffer to map page from. * @page_num: [in] page in PAGE_SIZE units to map. * * This call must always succeed, any necessary preparations that might fail @@ -391,7 +391,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap); /** * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. - * @dma_buf: [in] buffer to unmap page from. + * @dmabuf: [in] buffer to unmap page from. * @page_num: [in] page in PAGE_SIZE units to unmap. * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap. * -- cgit v1.2.3 From 97ec448aeadff55234368a89c4a07a7ef290a084 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 16 Apr 2012 18:14:10 -0700 Subject: drivers/base/bus.c: local variables should not be exposed globally The variable 'system_kset' is only referenced in this file and should be marked static to prevent it from being exposed globally. This quiets the sparse waring: warning: symbol 'system_kset' was not declared. Should it be static? Also, remove the comment since drivers/base/sys.c has now been deleted. Signed-off-by: H Hartley Sweeten Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 26a06b801b5b..2bcef657a60c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -21,8 +21,7 @@ #include "power/power.h" /* /sys/devices/system */ -/* FIXME: make static after drivers/base/sys.c is deleted */ -struct kset *system_kset; +static struct kset *system_kset; #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) -- cgit v1.2.3 From a15d49fd3094cff90e5410ca454a870e0a722fe1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 16 Apr 2012 15:06:25 +0200 Subject: driver core: check start node in klist_iter_init_node klist_iter_init_node() takes a node as a start argument. However, this node might not be valid anymore. This patch updates the klist_iter_init_node() and dependent functions to return an error if so. All calling functions have been audited to check for a return code here. Signed-off-by: Hannes Reinecke Cc: Greg Kroah-Hartmann Cc: Kay Sievers Cc: Stable Kernel Cc: Linux Kernel Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 46 +++++++++++++++++++++++++++++----------------- drivers/base/class.c | 32 ++++++++++++++++++++------------ drivers/base/driver.c | 18 +++++++++++------- include/linux/device.h | 10 +++++----- include/linux/klist.h | 2 +- lib/klist.c | 14 ++++++++++---- 6 files changed, 76 insertions(+), 46 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2bcef657a60c..76aed01a8b2c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -296,11 +296,13 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, if (!bus) return -EINVAL; - klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->p->knode_bus : NULL)); - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); + error = klist_iter_init_node(&bus->p->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)); + if (!error) { + while ((dev = next_device(&i)) && !error) + error = fn(dev, data); + klist_iter_exit(&i); + } return error; } EXPORT_SYMBOL_GPL(bus_for_each_dev); @@ -330,8 +332,10 @@ struct device *bus_find_device(struct bus_type *bus, if (!bus) return NULL; - klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->p->knode_bus : NULL)); + if (klist_iter_init_node(&bus->p->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)) < 0) + return NULL; + while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; @@ -384,7 +388,9 @@ struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id return NULL; if (hint) { - klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus); + if (klist_iter_init_node(&subsys->p->klist_devices, &i, + &hint->p->knode_bus) < 0) + return NULL; dev = next_device(&i); if (dev && dev->id == id && get_device(dev)) { klist_iter_exit(&i); @@ -446,11 +452,13 @@ int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, if (!bus) return -EINVAL; - klist_iter_init_node(&bus->p->klist_drivers, &i, - start ? &start->p->knode_bus : NULL); - while ((drv = next_driver(&i)) && !error) - error = fn(drv, data); - klist_iter_exit(&i); + error = klist_iter_init_node(&bus->p->klist_drivers, &i, + start ? &start->p->knode_bus : NULL); + if (!error) { + while ((drv = next_driver(&i)) && !error) + error = fn(drv, data); + klist_iter_exit(&i); + } return error; } EXPORT_SYMBOL_GPL(bus_for_each_drv); @@ -1111,15 +1119,19 @@ EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); * otherwise if it is NULL, the iteration starts at the beginning of * the list. */ -void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, - struct device *start, const struct device_type *type) +int subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, + struct device *start, const struct device_type *type) { struct klist_node *start_knode = NULL; + int error; if (start) start_knode = &start->p->knode_bus; - klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode); - iter->type = type; + error = klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, + start_knode); + if (!error) + iter->type = type; + return error; } EXPORT_SYMBOL_GPL(subsys_dev_iter_init); diff --git a/drivers/base/class.c b/drivers/base/class.c index 03243d4002fd..23dbc661d4a0 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -301,15 +301,20 @@ void class_destroy(struct class *cls) * otherwise if it is NULL, the iteration starts at the beginning of * the list. */ -void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, - struct device *start, const struct device_type *type) +int class_dev_iter_init(struct class_dev_iter *iter, struct class *class, + struct device *start, const struct device_type *type) { struct klist_node *start_knode = NULL; + int error; if (start) start_knode = &start->knode_class; - klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode); - iter->type = type; + error = klist_iter_init_node(&class->p->klist_devices, &iter->ki, + start_knode); + if (!error) + iter->type = type; + + return error; } EXPORT_SYMBOL_GPL(class_dev_iter_init); @@ -387,14 +392,15 @@ int class_for_each_device(struct class *class, struct device *start, return -EINVAL; } - class_dev_iter_init(&iter, class, start, NULL); - while ((dev = class_dev_iter_next(&iter))) { - error = fn(dev, data); - if (error) - break; + error = class_dev_iter_init(&iter, class, start, NULL); + if (!error) { + while ((dev = class_dev_iter_next(&iter))) { + error = fn(dev, data); + if (error) + break; + } + class_dev_iter_exit(&iter); } - class_dev_iter_exit(&iter); - return error; } EXPORT_SYMBOL_GPL(class_for_each_device); @@ -434,7 +440,9 @@ struct device *class_find_device(struct class *class, struct device *start, return NULL; } - class_dev_iter_init(&iter, class, start, NULL); + if (class_dev_iter_init(&iter, class, start, NULL) < 0) + return NULL; + while ((dev = class_dev_iter_next(&iter))) { if (match(dev, data)) { get_device(dev); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3ec3896c83a6..16f6dd2c4403 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -49,11 +49,13 @@ int driver_for_each_device(struct device_driver *drv, struct device *start, if (!drv) return -EINVAL; - klist_iter_init_node(&drv->p->klist_devices, &i, - start ? &start->p->knode_driver : NULL); - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); + error = klist_iter_init_node(&drv->p->klist_devices, &i, + start ? &start->p->knode_driver : NULL); + if (!error) { + while ((dev = next_device(&i)) && !error) + error = fn(dev, data); + klist_iter_exit(&i); + } return error; } EXPORT_SYMBOL_GPL(driver_for_each_device); @@ -83,8 +85,10 @@ struct device *driver_find_device(struct device_driver *drv, if (!drv) return NULL; - klist_iter_init_node(&drv->p->klist_devices, &i, - (start ? &start->p->knode_driver : NULL)); + if (klist_iter_init_node(&drv->p->klist_devices, &i, + (start ? &start->p->knode_driver : NULL)) < 0) + return NULL; + while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; diff --git a/include/linux/device.h b/include/linux/device.h index 5ad17cccdd71..50429b911b21 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -128,7 +128,7 @@ struct subsys_dev_iter { struct klist_iter ki; const struct device_type *type; }; -void subsys_dev_iter_init(struct subsys_dev_iter *iter, +int subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, struct device *start, const struct device_type *type); @@ -380,10 +380,10 @@ int class_compat_create_link(struct class_compat *cls, struct device *dev, void class_compat_remove_link(struct class_compat *cls, struct device *dev, struct device *device_link); -extern void class_dev_iter_init(struct class_dev_iter *iter, - struct class *class, - struct device *start, - const struct device_type *type); +extern int class_dev_iter_init(struct class_dev_iter *iter, + struct class *class, + struct device *start, + const struct device_type *type); extern struct device *class_dev_iter_next(struct class_dev_iter *iter); extern void class_dev_iter_exit(struct class_dev_iter *iter); diff --git a/include/linux/klist.h b/include/linux/klist.h index a370ce57cf1d..9f633230f189 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h @@ -60,7 +60,7 @@ struct klist_iter { extern void klist_iter_init(struct klist *k, struct klist_iter *i); -extern void klist_iter_init_node(struct klist *k, struct klist_iter *i, +extern int klist_iter_init_node(struct klist *k, struct klist_iter *i, struct klist_node *n); extern void klist_iter_exit(struct klist_iter *i); extern struct klist_node *klist_next(struct klist_iter *i); diff --git a/lib/klist.c b/lib/klist.c index 0874e41609a6..a2741a7d9784 100644 --- a/lib/klist.c +++ b/lib/klist.c @@ -278,13 +278,19 @@ EXPORT_SYMBOL_GPL(klist_node_attached); * Similar to klist_iter_init(), but starts the action off with @n, * instead of with the list head. */ -void klist_iter_init_node(struct klist *k, struct klist_iter *i, - struct klist_node *n) +int klist_iter_init_node(struct klist *k, struct klist_iter *i, + struct klist_node *n) { + if (n) { + kref_get(&n->n_ref); + if (!n->n_klist) { + kref_put(&n->n_ref); + return -ENODEV; + } + } i->i_klist = k; i->i_cur = n; - if (n) - kref_get(&n->n_ref); + return 0; } EXPORT_SYMBOL_GPL(klist_iter_init_node); -- cgit v1.2.3 From 7cd9c9bb57476167e83b7780dbc06d1dd601789d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 19 Apr 2012 19:17:30 -0700 Subject: Revert "driver core: check start node in klist_iter_init_node" This reverts commit a15d49fd3094cff90e5410ca454a870e0a722fe1 as that patch broke the build. Cc: Hannes Reinecke Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 46 +++++++++++++++++----------------------------- drivers/base/class.c | 32 ++++++++++++-------------------- drivers/base/driver.c | 18 +++++++----------- include/linux/device.h | 10 +++++----- include/linux/klist.h | 2 +- lib/klist.c | 14 ++++---------- 6 files changed, 46 insertions(+), 76 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 76aed01a8b2c..2bcef657a60c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -296,13 +296,11 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, if (!bus) return -EINVAL; - error = klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->p->knode_bus : NULL)); - if (!error) { - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); - } + klist_iter_init_node(&bus->p->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)); + while ((dev = next_device(&i)) && !error) + error = fn(dev, data); + klist_iter_exit(&i); return error; } EXPORT_SYMBOL_GPL(bus_for_each_dev); @@ -332,10 +330,8 @@ struct device *bus_find_device(struct bus_type *bus, if (!bus) return NULL; - if (klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->p->knode_bus : NULL)) < 0) - return NULL; - + klist_iter_init_node(&bus->p->klist_devices, &i, + (start ? &start->p->knode_bus : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; @@ -388,9 +384,7 @@ struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id return NULL; if (hint) { - if (klist_iter_init_node(&subsys->p->klist_devices, &i, - &hint->p->knode_bus) < 0) - return NULL; + klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus); dev = next_device(&i); if (dev && dev->id == id && get_device(dev)) { klist_iter_exit(&i); @@ -452,13 +446,11 @@ int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, if (!bus) return -EINVAL; - error = klist_iter_init_node(&bus->p->klist_drivers, &i, - start ? &start->p->knode_bus : NULL); - if (!error) { - while ((drv = next_driver(&i)) && !error) - error = fn(drv, data); - klist_iter_exit(&i); - } + klist_iter_init_node(&bus->p->klist_drivers, &i, + start ? &start->p->knode_bus : NULL); + while ((drv = next_driver(&i)) && !error) + error = fn(drv, data); + klist_iter_exit(&i); return error; } EXPORT_SYMBOL_GPL(bus_for_each_drv); @@ -1119,19 +1111,15 @@ EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); * otherwise if it is NULL, the iteration starts at the beginning of * the list. */ -int subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, - struct device *start, const struct device_type *type) +void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, + struct device *start, const struct device_type *type) { struct klist_node *start_knode = NULL; - int error; if (start) start_knode = &start->p->knode_bus; - error = klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, - start_knode); - if (!error) - iter->type = type; - return error; + klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode); + iter->type = type; } EXPORT_SYMBOL_GPL(subsys_dev_iter_init); diff --git a/drivers/base/class.c b/drivers/base/class.c index 23dbc661d4a0..03243d4002fd 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -301,20 +301,15 @@ void class_destroy(struct class *cls) * otherwise if it is NULL, the iteration starts at the beginning of * the list. */ -int class_dev_iter_init(struct class_dev_iter *iter, struct class *class, - struct device *start, const struct device_type *type) +void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, + struct device *start, const struct device_type *type) { struct klist_node *start_knode = NULL; - int error; if (start) start_knode = &start->knode_class; - error = klist_iter_init_node(&class->p->klist_devices, &iter->ki, - start_knode); - if (!error) - iter->type = type; - - return error; + klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode); + iter->type = type; } EXPORT_SYMBOL_GPL(class_dev_iter_init); @@ -392,15 +387,14 @@ int class_for_each_device(struct class *class, struct device *start, return -EINVAL; } - error = class_dev_iter_init(&iter, class, start, NULL); - if (!error) { - while ((dev = class_dev_iter_next(&iter))) { - error = fn(dev, data); - if (error) - break; - } - class_dev_iter_exit(&iter); + class_dev_iter_init(&iter, class, start, NULL); + while ((dev = class_dev_iter_next(&iter))) { + error = fn(dev, data); + if (error) + break; } + class_dev_iter_exit(&iter); + return error; } EXPORT_SYMBOL_GPL(class_for_each_device); @@ -440,9 +434,7 @@ struct device *class_find_device(struct class *class, struct device *start, return NULL; } - if (class_dev_iter_init(&iter, class, start, NULL) < 0) - return NULL; - + class_dev_iter_init(&iter, class, start, NULL); while ((dev = class_dev_iter_next(&iter))) { if (match(dev, data)) { get_device(dev); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 16f6dd2c4403..3ec3896c83a6 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -49,13 +49,11 @@ int driver_for_each_device(struct device_driver *drv, struct device *start, if (!drv) return -EINVAL; - error = klist_iter_init_node(&drv->p->klist_devices, &i, - start ? &start->p->knode_driver : NULL); - if (!error) { - while ((dev = next_device(&i)) && !error) - error = fn(dev, data); - klist_iter_exit(&i); - } + klist_iter_init_node(&drv->p->klist_devices, &i, + start ? &start->p->knode_driver : NULL); + while ((dev = next_device(&i)) && !error) + error = fn(dev, data); + klist_iter_exit(&i); return error; } EXPORT_SYMBOL_GPL(driver_for_each_device); @@ -85,10 +83,8 @@ struct device *driver_find_device(struct device_driver *drv, if (!drv) return NULL; - if (klist_iter_init_node(&drv->p->klist_devices, &i, - (start ? &start->p->knode_driver : NULL)) < 0) - return NULL; - + klist_iter_init_node(&drv->p->klist_devices, &i, + (start ? &start->p->knode_driver : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; diff --git a/include/linux/device.h b/include/linux/device.h index 50429b911b21..5ad17cccdd71 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -128,7 +128,7 @@ struct subsys_dev_iter { struct klist_iter ki; const struct device_type *type; }; -int subsys_dev_iter_init(struct subsys_dev_iter *iter, +void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, struct device *start, const struct device_type *type); @@ -380,10 +380,10 @@ int class_compat_create_link(struct class_compat *cls, struct device *dev, void class_compat_remove_link(struct class_compat *cls, struct device *dev, struct device *device_link); -extern int class_dev_iter_init(struct class_dev_iter *iter, - struct class *class, - struct device *start, - const struct device_type *type); +extern void class_dev_iter_init(struct class_dev_iter *iter, + struct class *class, + struct device *start, + const struct device_type *type); extern struct device *class_dev_iter_next(struct class_dev_iter *iter); extern void class_dev_iter_exit(struct class_dev_iter *iter); diff --git a/include/linux/klist.h b/include/linux/klist.h index 9f633230f189..a370ce57cf1d 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h @@ -60,7 +60,7 @@ struct klist_iter { extern void klist_iter_init(struct klist *k, struct klist_iter *i); -extern int klist_iter_init_node(struct klist *k, struct klist_iter *i, +extern void klist_iter_init_node(struct klist *k, struct klist_iter *i, struct klist_node *n); extern void klist_iter_exit(struct klist_iter *i); extern struct klist_node *klist_next(struct klist_iter *i); diff --git a/lib/klist.c b/lib/klist.c index a2741a7d9784..0874e41609a6 100644 --- a/lib/klist.c +++ b/lib/klist.c @@ -278,19 +278,13 @@ EXPORT_SYMBOL_GPL(klist_node_attached); * Similar to klist_iter_init(), but starts the action off with @n, * instead of with the list head. */ -int klist_iter_init_node(struct klist *k, struct klist_iter *i, - struct klist_node *n) +void klist_iter_init_node(struct klist *k, struct klist_iter *i, + struct klist_node *n) { - if (n) { - kref_get(&n->n_ref); - if (!n->n_klist) { - kref_put(&n->n_ref); - return -ENODEV; - } - } i->i_klist = k; i->i_cur = n; - return 0; + if (n) + kref_get(&n->n_ref); } EXPORT_SYMBOL_GPL(klist_iter_init_node); -- cgit v1.2.3 From 9169c01236ab29ce55c93aaf22ec6ecc65c46d1a Mon Sep 17 00:00:00 2001 From: yan Date: Fri, 20 Apr 2012 21:08:45 +0800 Subject: drivers/base/core.c: Fix a typo in comment Signed-off-by: YanHong Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index 6cb25f1511df..33461ec35d8f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -65,7 +65,7 @@ static inline int device_is_not_partition(struct device *dev) * @dev: struct device to get the name of * * Will return the device's driver's name if it is bound to a device. If - * the device is not bound to a device, it will return the name of the bus + * the device is not bound to a driver, it will return the name of the bus * it is attached to. If it is not attached to a bus either, an empty * string will be returned. */ -- cgit v1.2.3 From 698cd2ddd851b34e7200b4f846ae68306e11bae4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 May 2012 18:15:12 +0100 Subject: devres: Clarify documentation for devres_destroy() It's not massively obvious (at least to me) that removing and freeing a resource does not involve calling the release function for the resource but rather only removes the management of it. Make the documentation more explicit. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 524bf96c289f..1741a60de117 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -309,6 +309,10 @@ EXPORT_SYMBOL_GPL(devres_remove); * which @match returns 1. If @match is NULL, it's considered to * match all. If found, the resource is removed atomically and freed. * + * Note that the release function for the resource will not be called, + * only the devres-allocated data will be freed. The caller becomes + * responsible for freeing any other data. + * * RETURNS: * 0 if devres is found and freed, -ENOENT if not found. */ -- cgit v1.2.3 From d926d0e4c74cfcb42a05e91d1cdf698b41e1e118 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 May 2012 18:15:13 +0100 Subject: devres: Add devres_release() APIs using devres frequently want to implement a "remove and free the resource" operation so it seems sensible that they should be able to just have devres do the freeing for them since that's a big part of what devres is all about. Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 31 +++++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 33 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 1741a60de117..2360adb7a58f 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -330,6 +330,37 @@ int devres_destroy(struct device *dev, dr_release_t release, } EXPORT_SYMBOL_GPL(devres_destroy); + +/** + * devres_release - Find a device resource and destroy it, calling release + * @dev: Device to find resource from + * @release: Look for resources associated with this release function + * @match: Match function (optional) + * @match_data: Data for the match function + * + * Find the latest devres of @dev associated with @release and for + * which @match returns 1. If @match is NULL, it's considered to + * match all. If found, the resource is removed atomically, the + * release function called and the resource freed. + * + * RETURNS: + * 0 if devres is found and freed, -ENOENT if not found. + */ +int devres_release(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data) +{ + void *res; + + res = devres_remove(dev, release, match, match_data); + if (unlikely(!res)) + return -ENOENT; + + (*release)(dev, res); + devres_free(res); + return 0; +} +EXPORT_SYMBOL_GPL(devres_release); + static int remove_nodes(struct device *dev, struct list_head *first, struct list_head *end, struct list_head *todo) diff --git a/include/linux/device.h b/include/linux/device.h index 3ab4d63609b6..863acf8a0dce 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -541,6 +541,8 @@ extern void *devres_remove(struct device *dev, dr_release_t release, dr_match_t match, void *match_data); extern int devres_destroy(struct device *dev, dr_release_t release, dr_match_t match, void *match_data); +extern int devres_release(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data); /* devres group */ extern void * __must_check devres_open_group(struct device *dev, void *id, -- cgit v1.2.3 From c4e00daaa96d3a0786f1f4fe6456281c60ef9a16 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 3 May 2012 02:29:59 +0200 Subject: driver-core: extend dev_printk() to pass structured data Extends dev_printk() to attach a dictionary with a device identifier and the driver core subsystem name to logged messages, which makes dev_prink() reliable machine-readable. In addition to the printed plain text message, it creates these properties: SUBSYSTEM= - the driver-core subsytem name DEVICE= b12:8 - block dev_t c127:3 - char dev_t n8 - netdev ifindex +sound:card0 - subsystem:devname Tested-by: William Douglas Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/core.c b/drivers/base/core.c index 33461ec35d8f..346be8b78b24 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -1843,15 +1844,60 @@ void device_shutdown(void) */ #ifdef CONFIG_PRINTK - int __dev_printk(const char *level, const struct device *dev, struct va_format *vaf) { + char dict[128]; + size_t dictlen = 0; + const char *subsys; + if (!dev) return printk("%s(NULL device *): %pV", level, vaf); - return printk("%s%s %s: %pV", - level, dev_driver_string(dev), dev_name(dev), vaf); + if (dev->class) + subsys = dev->class->name; + else if (dev->bus) + subsys = dev->bus->name; + else + goto skip; + + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, + "SUBSYSTEM=%s", subsys); + + /* + * Add device identifier DEVICE=: + * b12:8 block dev_t + * c127:3 char dev_t + * n8 netdev ifindex + * +sound:card0 subsystem:devname + */ + if (MAJOR(dev->devt)) { + char c; + + if (strcmp(subsys, "block") == 0) + c = 'b'; + else + c = 'c'; + dictlen++; + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, + "DEVICE=%c%u:%u", + c, MAJOR(dev->devt), MINOR(dev->devt)); + } else if (strcmp(subsys, "net") == 0) { + struct net_device *net = to_net_dev(dev); + + dictlen++; + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, + "DEVICE=n%u", net->ifindex); + } else { + dictlen++; + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, + "DEVICE=+%s:%s", subsys, dev_name(dev)); + } +skip: + return printk_emit(0, level[1] - '0', + dictlen ? dict : NULL, dictlen, + "%s %s: %pV", + dev_driver_string(dev), dev_name(dev), vaf); } EXPORT_SYMBOL(__dev_printk); -- cgit v1.2.3 From 094e47e9fa79e28f0e51e37400ea6eea35a4ee1f Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Fri, 11 May 2012 11:03:09 +0300 Subject: Driver Core: don't oops with unregistered driver in driver_find_device() driver_find_device() can be called with an unregistered driver. Need to check driver_private to see if it's populated or not, especially under deferrable probe. In the case that there are 2 drivers, one depends on the other. With -EPROBE_DEFER, two drivers can use deferred probe to ensure that their relative probe order doesn't matter. If dependee driver is probed first, then the dependant's driver_find_device('dependee') succeeds. If the dependant is probed first, then the dependant's driver_find_device('dependee') should return NULL, and the dependant should get -EPROBE_DEFER. driver_find_device() needs to return NULL if it's not populated. In [PATCHv5 2/3] ARM: tegra: Add SMMU enabler in AHB: http://article.gmane.org/gmane.linux.ports.tegra/4658 "tegra_ahb_driver" may not be populated when it's called. For more SMMU/AHB specific discussion, refer to the following thread: https://lkml.org/lkml/2012/5/10/21 Signed-off-by: Hiroshi DOYU Cc: Stephen Warren Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3ec3896c83a6..207c27ddf828 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -80,7 +80,7 @@ struct device *driver_find_device(struct device_driver *drv, struct klist_iter i; struct device *dev; - if (!drv) + if (!drv || !drv->p) return NULL; klist_iter_init_node(&drv->p->klist_devices, &i, -- cgit v1.2.3