linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed!
  2006-09-26  5:37 [GIT PATCH] Driver Core patches for 2.6.18 Greg KH
@ 2006-09-26  5:37 ` Greg KH
  2006-09-26  5:37   ` [PATCH 2/47] deprecate PHYSDEV* keys Greg KH
  2006-09-26 12:34 ` [GIT PATCH] Driver Core patches for 2.6.18 Mike Galbraith
  1 sibling, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: jens m. noedler <noedler@web.de>

Signed-off-by: Jens M. Noedler <noedler@web.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/ABI/{obsolete => removed}/devfs |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/obsolete/devfs b/Documentation/ABI/removed/devfs
similarity index 73%
rename from Documentation/ABI/obsolete/devfs
rename to Documentation/ABI/removed/devfs
index b8b8739..8195c4e 100644
--- a/Documentation/ABI/obsolete/devfs
+++ b/Documentation/ABI/removed/devfs
@@ -1,13 +1,12 @@
 What:		devfs
-Date:		July 2005
+Date:		July 2005 (scheduled), finally removed in kernel v2.6.18
 Contact:	Greg Kroah-Hartman <gregkh@suse.de>
 Description:
 	devfs has been unmaintained for a number of years, has unfixable
 	races, contains a naming policy within the kernel that is
 	against the LSB, and can be replaced by using udev.
-	The files fs/devfs/*, include/linux/devfs_fs*.h will be removed,
+	The files fs/devfs/*, include/linux/devfs_fs*.h were removed,
 	along with the the assorted devfs function calls throughout the
 	kernel tree.
 
 Users:
-
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 2/47] deprecate PHYSDEV* keys
  2006-09-26  5:37 ` [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed! Greg KH
@ 2006-09-26  5:37   ` Greg KH
  2006-09-26  5:37     ` [PATCH 3/47] class_device_create(): make fmt argument 'const char *' Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Kay Sievers, Greg Kroah-Hartman

From: Kay Sievers <kay.sievers@suse.de>

deprecate PHYSDEV* values in the uevent environment

These values are no longer needed and inconsistent with the
stacking of class devices. The event environment should not
carry properties of a parent device. The key PHYSDEVDRIVER is
available as DRIVER, PHYDEVBUS is indentical SUBSYSTEM. Class
devices should not carry any of these values.

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/feature-removal-schedule.txt |   12 ++++++++++++
 drivers/base/class.c                       |    2 +-
 drivers/base/core.c                        |   10 +++++++---
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 552507f..a89a1b7 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -294,3 +294,15 @@ Why:	The frame diverter is included in m
 	It is not clear if anyone is still using it.
 Who:	Stephen Hemminger <shemminger@osdl.org>
 
+---------------------------
+
+
+What:	PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
+When:	Oktober 2008
+Why:	The stacking of class devices makes these values misleading and
+	inconsistent.
+	Class devices should not carry any of these properties, and bus
+	devices have SUBSYTEM and DRIVER as a replacement.
+Who:	Kay Sievers <kay.sievers@suse.de>
+
+---------------------------
diff --git a/drivers/base/class.c b/drivers/base/class.c
index de89083..46336f1 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -361,7 +361,7 @@ static int class_uevent(struct kset *kse
 	pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
 
 	if (class_dev->dev) {
-		/* add physical device, backing this device  */
+		/* add device, backing this class device (deprecated) */
 		struct device *dev = class_dev->dev;
 		char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
 
diff --git a/drivers/base/core.c b/drivers/base/core.c
index be6b5bc..04d089f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -149,17 +149,21 @@ static int dev_uevent(struct kset *kset,
 			       "MINOR=%u", MINOR(dev->devt));
 	}
 
-	/* add bus name of physical device */
+	/* add bus name (same as SUBSYSTEM, deprecated) */
 	if (dev->bus)
 		add_uevent_var(envp, num_envp, &i,
 			       buffer, buffer_size, &length,
 			       "PHYSDEVBUS=%s", dev->bus->name);
 
-	/* add driver name of physical device */
-	if (dev->driver)
+	/* add driver name (PHYSDEV* values are deprecated)*/
+	if (dev->driver) {
+		add_uevent_var(envp, num_envp, &i,
+			       buffer, buffer_size, &length,
+			       "DRIVER=%s", dev->driver->name);
 		add_uevent_var(envp, num_envp, &i,
 			       buffer, buffer_size, &length,
 			       "PHYSDEVDRIVER=%s", dev->driver->name);
+	}
 
 	/* terminate, set to next free slot, shrink available space */
 	envp[i] = NULL;
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 3/47] class_device_create(): make fmt argument 'const char *'
  2006-09-26  5:37   ` [PATCH 2/47] deprecate PHYSDEV* keys Greg KH
@ 2006-09-26  5:37     ` Greg KH
  2006-09-26  5:37       ` [PATCH 4/47] device_create(): " Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dmitry Torokhov, Dmitry Torokhov, Greg Kroah-Hartman

From: Dmitry Torokhov <dtor@insightbb.com>

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/class.c   |    3 ++-
 include/linux/device.h |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index 46336f1..75057aa 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -679,7 +679,8 @@ int class_device_register(struct class_d
 struct class_device *class_device_create(struct class *cls,
 					 struct class_device *parent,
 					 dev_t devt,
-					 struct device *device, char *fmt, ...)
+					 struct device *device,
+					 const char *fmt, ...)
 {
 	va_list args;
 	struct class_device *class_dev = NULL;
diff --git a/include/linux/device.h b/include/linux/device.h
index 1e5f30d..1fec285 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -277,7 +277,7 @@ extern struct class_device *class_device
 						struct class_device *parent,
 						dev_t devt,
 						struct device *device,
-						char *fmt, ...)
+						const char *fmt, ...)
 					__attribute__((format(printf,5,6)));
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 4/47] device_create(): make fmt argument 'const char *'
  2006-09-26  5:37     ` [PATCH 3/47] class_device_create(): make fmt argument 'const char *' Greg KH
@ 2006-09-26  5:37       ` Greg KH
  2006-09-26  5:37         ` [PATCH 5/47] Driver core: add const to class_create Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c    |    2 +-
 include/linux/device.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 04d089f..5d4b7e0 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -583,7 +583,7 @@ static void device_create_release(struct
  * been created with a call to class_create().
  */
 struct device *device_create(struct class *class, struct device *parent,
-			     dev_t devt, char *fmt, ...)
+			     dev_t devt, const char *fmt, ...)
 {
 	va_list args;
 	struct device *dev = NULL;
diff --git a/include/linux/device.h b/include/linux/device.h
index 1fec285..8d92013 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -384,7 +384,7 @@ extern void device_reprobe(struct device
  * Easy functions for dynamically creating devices on the fly
  */
 extern struct device *device_create(struct class *cls, struct device *parent,
-				    dev_t devt, char *fmt, ...)
+				    dev_t devt, const char *fmt, ...)
 				    __attribute__((format(printf,4,5)));
 extern void device_destroy(struct class *cls, dev_t devt);
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 5/47] Driver core: add const to class_create
  2006-09-26  5:37       ` [PATCH 4/47] device_create(): " Greg KH
@ 2006-09-26  5:37         ` Greg KH
  2006-09-26  5:37           ` [PATCH 6/47] sysfs: Make poll behaviour consistent Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Miguel Ojeda Sandonis, Greg Kroah-Hartman

From: Miguel Ojeda Sandonis <maxextreme@gmail.com>

Adds const to class_create second parameter, because:

struct class {
	const char * name;

	/*...*/
}

Signed-off-by: Miguel Ojeda Sandonis <maxextreme@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/class.c   |    2 +-
 include/linux/device.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index 75057aa..e078bc2 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -197,7 +197,7 @@ static int class_device_create_uevent(st
  * Note, the pointer created here is to be destroyed when finished by
  * making a call to class_destroy().
  */
-struct class *class_create(struct module *owner, char *name)
+struct class *class_create(struct module *owner, const char *name)
 {
 	struct class *cls;
 	int retval;
diff --git a/include/linux/device.h b/include/linux/device.h
index 8d92013..8a648cd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -271,7 +271,7 @@ struct class_interface {
 extern int class_interface_register(struct class_interface *);
 extern void class_interface_unregister(struct class_interface *);
 
-extern struct class *class_create(struct module *owner, char *name);
+extern struct class *class_create(struct module *owner, const char *name);
 extern void class_destroy(struct class *cls);
 extern struct class_device *class_device_create(struct class *cls,
 						struct class_device *parent,
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 6/47] sysfs: Make poll behaviour consistent
  2006-09-26  5:37         ` [PATCH 5/47] Driver core: add const to class_create Greg KH
@ 2006-09-26  5:37           ` Greg KH
  2006-09-26  5:37             ` [PATCH 7/47] Debugfs: kernel-doc fixes for debugfs Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Juha Yrj�l�, Greg Kroah-Hartman

From: =?utf-8?q?Juha_Yrj=F6l=E4?= <juha.yrjola@solidboot.com>

When no events have been reported by sysfs_notify(), sd->s_events
was previously set to zero.  The initial value for new readers is
also zero, so poll was blocking, regardless of whether the attribute
was read by the process or not.

Make poll behave consistently by setting the initial value of
sd->s_events to non-zero.

Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/sysfs/dir.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 61c4243..5f3d725 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -43,7 +43,7 @@ static struct sysfs_dirent * sysfs_new_d
 
 	memset(sd, 0, sizeof(*sd));
 	atomic_set(&sd->s_count, 1);
-	atomic_set(&sd->s_event, 0);
+	atomic_set(&sd->s_event, 1);
 	INIT_LIST_HEAD(&sd->s_children);
 	list_add(&sd->s_sibling, &parent_sd->s_children);
 	sd->s_element = element;
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 7/47] Debugfs: kernel-doc fixes for debugfs
  2006-09-26  5:37           ` [PATCH 6/47] sysfs: Make poll behaviour consistent Greg KH
@ 2006-09-26  5:37             ` Greg KH
  2006-09-26  5:37               ` [PATCH 8/47] SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, Greg Kroah-Hartman

From: Randy Dunlap <rdunlap@xenotime.net>

Fix kernel-doc and typos/spellos in fs/debugfs/.

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/debugfs/file.c  |   56 +++++++++++++++++++++++-----------------------------
 fs/debugfs/inode.c |   15 ++++++--------
 2 files changed, 31 insertions(+), 40 deletions(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 39640fd..e4b4305 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -55,12 +55,11 @@ static u64 debugfs_u8_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
- * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value.
- *
+ * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @value: a pointer to the variable that the file should read to and write
  *         from.
@@ -72,11 +71,11 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
@@ -97,12 +96,11 @@ static u64 debugfs_u16_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
 
 /**
- * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value.
- *
+ * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @value: a pointer to the variable that the file should read to and write
  *         from.
@@ -114,11 +112,11 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugf
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_u16(const char *name, mode_t mode,
@@ -139,12 +137,11 @@ static u64 debugfs_u32_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
 
 /**
- * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value.
- *
+ * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @value: a pointer to the variable that the file should read to and write
  *         from.
@@ -156,11 +153,11 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugf
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_u32(const char *name, mode_t mode,
@@ -219,12 +216,11 @@ static const struct file_operations fops
 };
 
 /**
- * debugfs_create_bool - create a file in the debugfs filesystem that is used to read and write a boolean value.
- *
+ * debugfs_create_bool - create a debugfs file that is used to read and write a boolean value
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @value: a pointer to the variable that the file should read to and write
  *         from.
@@ -236,11 +232,11 @@ static const struct file_operations fops
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_bool(const char *name, mode_t mode,
@@ -264,13 +260,11 @@ static struct file_operations fops_blob 
 };
 
 /**
- * debugfs_create_blob - create a file in the debugfs filesystem that is
- * used to read and write a binary blob.
- *
+ * debugfs_create_blob - create a debugfs file that is used to read and write a binary blob
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
  *        to the blob data and the size of the data.
@@ -282,11 +276,11 @@ static struct file_operations fops_blob 
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_blob(const char *name, mode_t mode,
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index e8ae304..3ca268d 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -162,7 +162,6 @@ static int debugfs_create_by_name(const 
 
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
- *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
@@ -182,11 +181,11 @@ static int debugfs_create_by_name(const 
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_file(const char *name, mode_t mode,
@@ -221,7 +220,6 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
 
 /**
  * debugfs_create_dir - create a directory in the debugfs filesystem
- *
  * @name: a pointer to a string containing the name of the directory to
  *        create.
  * @parent: a pointer to the parent dentry for this file.  This should be a
@@ -233,11 +231,11 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
  * This function will return a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the debugfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
  *
- * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
@@ -250,7 +248,6 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
 /**
  * debugfs_remove - removes a file or directory from the debugfs filesystem
- *
  * @dentry: a pointer to a the dentry of the file or directory to be
  *          removed.
  *
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [GIT PATCH] Driver Core patches for 2.6.18
@ 2006-09-26  5:37 Greg KH
  2006-09-26  5:37 ` [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed! Greg KH
  2006-09-26 12:34 ` [GIT PATCH] Driver Core patches for 2.6.18 Mike Galbraith
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=unknown-8bit, Size: 7143 bytes --]

Here are a bunch of driver core and sysfs patches and fixes for 2.6.18.
They contain the following changes:
	- your suspend resume api changes
	- lots of other suspend issue fixes and documentation for power
	  issues.
	- driver core additions to allow devices to replace class
	  devices (no subsystems have been changed however, those remain
	  out of mainline until udev and other helper utilities get
	  fixed up properly.)
	- __must_check config option to shut it up because of:
	- add __must_check to the driver core to fix driver bugs  (lots
	  of __must_check fixes are staged and ready to come in after
	  these patches go in).
	- multi-thread device probe addition to both the driver core,
	  and the PCI subsystem (overridden by a config and command line
	  option.)
	- other minor bugfixes.

All of these patches have been in the -mm tree for a quite a while.

Please pull from:
	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/
or if master.kernel.org hasn't synced up yet:
	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/

Patches will be sent as a follow-on to this message to lkml for people
to see.

thanks,

greg k-h


 Documentation/ABI/{obsolete => removed}/devfs |    5 
 Documentation/ABI/testing/sysfs-power         |   88 +++
 Documentation/feature-removal-schedule.txt    |   27 +
 Documentation/power/devices.txt               |  733 ++++++++++++++++++-------
 drivers/base/base.h                           |    2 
 drivers/base/bus.c                            |  133 +++--
 drivers/base/class.c                          |   34 +
 drivers/base/core.c                           |  230 +++++++-
 drivers/base/dd.c                             |  147 ++++-
 drivers/base/driver.c                         |   16 -
 drivers/base/platform.c                       |   30 +
 drivers/base/power/resume.c                   |   37 +
 drivers/base/power/suspend.c                  |   92 ++-
 drivers/base/power/sysfs.c                    |   35 +
 drivers/ide/ide.c                             |    6 
 drivers/ide/ppc/pmac.c                        |   14 
 drivers/media/dvb/cinergyT2/cinergyT2.c       |    2 
 drivers/pci/Kconfig                           |   25 +
 drivers/pci/hotplug/acpiphp_ibm.c             |    4 
 drivers/pci/pci-driver.c                      |   38 +
 drivers/pci/pci.c                             |    4 
 drivers/scsi/mesh.c                           |   15 -
 drivers/usb/core/hcd-pci.c                    |    2 
 drivers/usb/host/ehci-pci.c                   |    6 
 drivers/usb/host/ohci-pci.c                   |    5 
 drivers/usb/host/sl811-hcd.c                  |    9 
 drivers/usb/host/uhci-hcd.c                   |    4 
 drivers/video/aty/radeon_pm.c                 |   15 -
 drivers/video/i810/i810_main.c                |   12 
 drivers/video/nvidia/nvidia.c                 |   13 
 drivers/video/savage/savagefb_driver.c        |   14 
 fs/debugfs/file.c                             |   56 +-
 fs/debugfs/inode.c                            |   15 -
 fs/namespace.c                                |   10 
 fs/sysfs/bin.c                                |   13 
 fs/sysfs/dir.c                                |    2 
 fs/sysfs/inode.c                              |   11 
 fs/sysfs/symlink.c                            |   14 
 fs/sysfs/sysfs.h                              |    2 
 include/linux/compiler.h                      |    5 
 include/linux/device.h                        |   99 ++-
 include/linux/kobject.h                       |   16 -
 include/linux/pci.h                           |   36 +
 include/linux/platform_device.h               |    2 
 include/linux/pm.h                            |   63 ++
 include/linux/sysfs.h                         |   28 +
 include/media/v4l2-dev.h                      |    2 
 init/do_mounts.c                              |    5 
 kernel/power/Kconfig                          |   11 
 kernel/power/disk.c                           |    4 
 kernel/power/swsusp.c                         |    9 
 kernel/power/user.c                           |    2 
 lib/Kconfig.debug                             |    7 
 lib/klist.c                                   |   26 +
 lib/kobject.c                                 |    9 
 55 files changed, 1663 insertions(+), 581 deletions(-)
 rename Documentation/ABI/{obsolete/devfs => removed/devfs} (73%)
 create mode 100644 Documentation/ABI/testing/sysfs-power

---------------

Alan Stern:
      Driver core: Fix potential deadlock in driver core
      Driver core: Remove unneeded routines from driver core
      Driver core: Don't call put methods while holding a spinlock

Andrew Morton:
      add __must_check to device management code
      add CONFIG_ENABLE_MUST_CHECK
      v4l-dev2: handle __must_check
      drivers/base: check errors
      sysfs: add proper sysfs_init() prototype

Brian Walsh:
      drivers/base: Platform notify needs to occur before drivers attach to the device

David Brownell:
      make suspend quieter
      fix broken/dubious driver suspend() methods
      PM: define PM_EVENT_PRETHAW
      PM: PCI and IDE handle PM_EVENT_PRETHAW
      PM: video drivers and PM_EVENT_PRETHAW
      PM: USB HCDs use PM_EVENT_PRETHAW
      PM: issue PM_EVENT_PRETHAW
      updated Documentation/power/devices.txt
      PM: update docs for writing .../power/state
      PM: add kconfig option for deprecated .../power/state files
      PM: no suspend_prepare() phase
      PM: platform_bus and late_suspend/early_resume

Dmitry Torokhov:
      class_device_create(): make fmt argument 'const char *'
      Driver core: fix comments in drivers/base/power/resume.c

Greg Kroah-Hartman:
      device_create(): make fmt argument 'const char *'
      SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs
      Driver core: add groups support to struct device
      Driver core: allow devices in classes to have no parent
      Driver core: add ability for classes to handle devices properly
      Driver core: add device_rename function
      Driver core: create devices/virtual/ tree
      Class: add support for class interfaces for devices
      Driver core: add ability for devices to create and remove bin files
      Driver Core: add ability for drivers to do a threaded probe
      PCI: enable driver multi-threaded probe

jens m. noedler:
      Documentation/ABI: devfs is not obsolete, but removed!

Juha Yrjölä:
      sysfs: Make poll behaviour consistent

Kay Sievers:
      deprecate PHYSDEV* keys

Linus Torvalds:
      Suspend infrastructure cleanup and extension
      Suspend changes for PCI core

Miguel Ojeda Sandonis:
      Driver core: add const to class_create

Pavel Machek:
      PM: schedule /sys/devices/.../power/state for removal
      PM: device_suspend/resume may sleep

Rafael J. Wysocki:
      PM: add /sys/power documentation to Documentation/ABI

Randy Dunlap:
      Debugfs: kernel-doc fixes for debugfs
      kobject: must_check fixes

Randy.Dunlap:
      sysfs_remove_bin_file: no return value, dump_stack on error

Yoichi Yuasa:
      Driver core: fixed add_bind_files() definition


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 8/47] SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs
  2006-09-26  5:37             ` [PATCH 7/47] Debugfs: kernel-doc fixes for debugfs Greg KH
@ 2006-09-26  5:37               ` Greg KH
  2006-09-26  5:37                 ` [PATCH 9/47] Suspend infrastructure cleanup and extension Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This is needed to make the compatible link for /sys/block in the future.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/sysfs/symlink.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index d2eac3c..f50e3cc 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -3,6 +3,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
@@ -82,10 +83,19 @@ exit1:
  */
 int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
 {
-	struct dentry * dentry = kobj->dentry;
+	struct dentry *dentry = NULL;
 	int error = -EEXIST;
 
-	BUG_ON(!kobj || !kobj->dentry || !name);
+	BUG_ON(!name);
+
+	if (!kobj) {
+		if (sysfs_mount && sysfs_mount->mnt_sb)
+			dentry = sysfs_mount->mnt_sb->s_root;
+	} else
+		dentry = kobj->dentry;
+
+	if (!dentry)
+		return -EFAULT;
 
 	mutex_lock(&dentry->d_inode->i_mutex);
 	if (!sysfs_dirent_exist(dentry->d_fsdata, name))
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 9/47] Suspend infrastructure cleanup and extension
  2006-09-26  5:37               ` [PATCH 8/47] SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs Greg KH
@ 2006-09-26  5:37                 ` Greg KH
  2006-09-26  5:37                   ` [PATCH 10/47] Suspend changes for PCI core Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Linus Torvalds, Greg Kroah-Hartman

From: Linus Torvalds <torvalds@osdl.org>

Allow devices to participate in the suspend process more intimately,
in particular, allow the final phase (with interrupts disabled) to
also be open to normal devices, not just system devices.

Also, allow classes to participate in device suspend.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/resume.c  |   28 ++++++++--
 drivers/base/power/suspend.c |  122 ++++++++++++++++++++++++++++++++----------
 include/linux/device.h       |   11 +++-
 include/linux/pm.h           |    1 
 kernel/power/main.c          |    4 +
 5 files changed, 130 insertions(+), 36 deletions(-)

diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 826093e..48e3d49 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -38,13 +38,35 @@ int resume_device(struct device * dev)
 		dev_dbg(dev,"resuming\n");
 		error = dev->bus->resume(dev);
 	}
+	if (dev->class && dev->class->resume) {
+		dev_dbg(dev,"class resume\n");
+		error = dev->class->resume(dev);
+	}
 	up(&dev->sem);
 	TRACE_RESUME(error);
 	return error;
 }
 
 
+static int resume_device_early(struct device * dev)
+{
+	int error = 0;
 
+	TRACE_DEVICE(dev);
+	TRACE_RESUME(0);
+	if (dev->bus && dev->bus->resume_early) {
+		dev_dbg(dev,"EARLY resume\n");
+		error = dev->bus->resume_early(dev);
+	}
+	TRACE_RESUME(error);
+	return error;
+}
+
+/*
+ * Resume the devices that have either not gone through
+ * the late suspend, or that did go through it but also
+ * went through the early resume
+ */
 void dpm_resume(void)
 {
 	down(&dpm_list_sem);
@@ -99,10 +121,8 @@ void dpm_power_up(void)
 		struct list_head * entry = dpm_off_irq.next;
 		struct device * dev = to_device(entry);
 
-		get_device(dev);
-		list_move_tail(entry, &dpm_active);
-		resume_device(dev);
-		put_device(dev);
+		list_move_tail(entry, &dpm_off);
+		resume_device_early(dev);
 	}
 }
 
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 69509e0..10e8032 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -65,7 +65,19 @@ int suspend_device(struct device * dev, 
 
 	dev->power.prev_state = dev->power.power_state;
 
-	if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
+	if (dev->class && dev->class->suspend && !dev->power.power_state.event) {
+		dev_dbg(dev, "class %s%s\n",
+			suspend_verb(state.event),
+			((state.event == PM_EVENT_SUSPEND)
+					&& device_may_wakeup(dev))
+				? ", may wakeup"
+				: ""
+			);
+		error = dev->class->suspend(dev, state);
+		suspend_report_result(dev->class->suspend, error);
+	}
+
+	if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
 		dev_dbg(dev, "%s%s\n",
 			suspend_verb(state.event),
 			((state.event == PM_EVENT_SUSPEND)
@@ -81,15 +93,74 @@ int suspend_device(struct device * dev, 
 }
 
 
+/*
+ * This is called with interrupts off, only a single CPU
+ * running. We can't do down() on a semaphore (and we don't
+ * need the protection)
+ */
+static int suspend_device_late(struct device *dev, pm_message_t state)
+{
+	int error = 0;
+
+	if (dev->power.power_state.event) {
+		dev_dbg(dev, "PM: suspend_late %d-->%d\n",
+			dev->power.power_state.event, state.event);
+	}
+
+	if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) {
+		dev_dbg(dev, "LATE %s%s\n",
+			suspend_verb(state.event),
+			((state.event == PM_EVENT_SUSPEND)
+					&& device_may_wakeup(dev))
+				? ", may wakeup"
+				: ""
+			);
+		error = dev->bus->suspend_late(dev, state);
+		suspend_report_result(dev->bus->suspend_late, error);
+	}
+	return error;
+}
+
+/**
+ *	device_prepare_suspend - save state and prepare to suspend
+ *
+ *	NOTE! Devices cannot detach at this point - not only do we
+ *	hold the device list semaphores over the whole prepare, but
+ *	the whole point is to do non-invasive preparatory work, not
+ *	the actual suspend.
+ */
+int device_prepare_suspend(pm_message_t state)
+{
+	int error = 0;
+	struct device * dev;
+
+	down(&dpm_sem);
+	down(&dpm_list_sem);
+	list_for_each_entry_reverse(dev, &dpm_active, power.entry) {
+		if (!dev->bus || !dev->bus->suspend_prepare)
+			continue;
+		error = dev->bus->suspend_prepare(dev, state);
+		if (error)
+			break;
+	}
+	up(&dpm_list_sem);
+	up(&dpm_sem);
+	return error;
+}
+
 /**
  *	device_suspend - Save state and stop all devices in system.
  *	@state:		Power state to put each device in.
  *
  *	Walk the dpm_active list, call ->suspend() for each device, and move
- *	it to dpm_off.
- *	Check the return value for each. If it returns 0, then we move the
- *	the device to the dpm_off list. If it returns -EAGAIN, we move it to
- *	the dpm_off_irq list. If we get a different error, try and back out.
+ *	it to the dpm_off list.
+ *
+ *	(For historical reasons, if it returns -EAGAIN, that used to mean
+ *	that the device would be called again with interrupts disabled.
+ *	These days, we use the "suspend_late()" callback for that, so we
+ *	print a warning and consider it an error).
+ *
+ *	If we get a different error, try and back out.
  *
  *	If we hit a failure with any of the devices, call device_resume()
  *	above to bring the suspended devices back to life.
@@ -115,39 +186,27 @@ int device_suspend(pm_message_t state)
 
 		/* Check if the device got removed */
 		if (!list_empty(&dev->power.entry)) {
-			/* Move it to the dpm_off or dpm_off_irq list */
+			/* Move it to the dpm_off list */
 			if (!error)
 				list_move(&dev->power.entry, &dpm_off);
-			else if (error == -EAGAIN) {
-				list_move(&dev->power.entry, &dpm_off_irq);
-				error = 0;
-			}
 		}
 		if (error)
 			printk(KERN_ERR "Could not suspend device %s: "
-				"error %d\n", kobject_name(&dev->kobj), error);
+				"error %d%s\n",
+				kobject_name(&dev->kobj), error,
+				error == -EAGAIN ? " (please convert to suspend_late)" : "");
 		put_device(dev);
 	}
 	up(&dpm_list_sem);
-	if (error) {
-		/* we failed... before resuming, bring back devices from
-		 * dpm_off_irq list back to main dpm_off list, we do want
-		 * to call resume() on them, in case they partially suspended
-		 * despite returning -EAGAIN
-		 */
-		while (!list_empty(&dpm_off_irq)) {
-			struct list_head * entry = dpm_off_irq.next;
-			list_move(entry, &dpm_off);
-		}
+	if (error)
 		dpm_resume();
-	}
+
 	up(&dpm_sem);
 	return error;
 }
 
 EXPORT_SYMBOL_GPL(device_suspend);
 
-
 /**
  *	device_power_down - Shut down special devices.
  *	@state:		Power state to enter.
@@ -162,14 +221,17 @@ int device_power_down(pm_message_t state
 	int error = 0;
 	struct device * dev;
 
-	list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {
-		if ((error = suspend_device(dev, state)))
-			break;
+	while (!list_empty(&dpm_off)) {
+		struct list_head * entry = dpm_off.prev;
+
+		dev = to_device(entry);
+		error = suspend_device_late(dev, state);
+		if (error)
+			goto Error;
+		list_move(&dev->power.entry, &dpm_off_irq);
 	}
-	if (error)
-		goto Error;
-	if ((error = sysdev_suspend(state)))
-		goto Error;
+
+	error = sysdev_suspend(state);
  Done:
 	return error;
  Error:
diff --git a/include/linux/device.h b/include/linux/device.h
index 8a648cd..b40be6f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -51,8 +51,12 @@ struct bus_type {
 	int		(*probe)(struct device * dev);
 	int		(*remove)(struct device * dev);
 	void		(*shutdown)(struct device * dev);
-	int		(*suspend)(struct device * dev, pm_message_t state);
-	int		(*resume)(struct device * dev);
+
+	int (*suspend_prepare)(struct device * dev, pm_message_t state);
+	int (*suspend)(struct device * dev, pm_message_t state);
+	int (*suspend_late)(struct device * dev, pm_message_t state);
+	int (*resume_early)(struct device * dev);
+	int (*resume)(struct device * dev);
 };
 
 extern int bus_register(struct bus_type * bus);
@@ -154,6 +158,9 @@ struct class {
 
 	void	(*release)(struct class_device *dev);
 	void	(*class_release)(struct class *class);
+
+	int	(*suspend)(struct device *, pm_message_t state);
+	int	(*resume)(struct device *);
 };
 
 extern int class_register(struct class *);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 658c1b9..096fb6f 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -190,6 +190,7 @@ #ifdef CONFIG_PM
 extern suspend_disk_method_t pm_disk_mode;
 
 extern int device_suspend(pm_message_t state);
+extern int device_prepare_suspend(pm_message_t state);
 
 #define device_set_wakeup_enable(dev,val) \
 	((dev)->power.should_wakeup = !!(val))
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 6d295c7..0c3ed6a 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -57,6 +57,10 @@ static int suspend_prepare(suspend_state
 	if (!pm_ops || !pm_ops->enter)
 		return -EPERM;
 
+	error = device_prepare_suspend(PMSG_SUSPEND);
+	if (error)
+		return error;
+
 	pm_prepare_console();
 
 	disable_nonboot_cpus();
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 10/47] Suspend changes for PCI core
  2006-09-26  5:37                 ` [PATCH 9/47] Suspend infrastructure cleanup and extension Greg KH
@ 2006-09-26  5:37                   ` Greg KH
  2006-09-26  5:37                     ` [PATCH 11/47] make suspend quieter Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Linus Torvalds, Greg Kroah-Hartman

From: Linus Torvalds <torvalds@osdl.org>

Changes the PCI core to use the new suspend infrastructure changes.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/pci/pci-driver.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/pci.h      |    3 +++
 2 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 474e9cd..9e7d6ce 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -264,6 +264,19 @@ static int pci_device_remove(struct devi
 	return 0;
 }
 
+static int pci_device_suspend_prepare(struct device * dev, pm_message_t state)
+{
+	struct pci_dev * pci_dev = to_pci_dev(dev);
+	struct pci_driver * drv = pci_dev->driver;
+	int i = 0;
+
+	if (drv && drv->suspend_prepare) {
+		i = drv->suspend_prepare(pci_dev, state);
+		suspend_report_result(drv->suspend_prepare, i);
+	}
+	return i;
+}
+
 static int pci_device_suspend(struct device * dev, pm_message_t state)
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
@@ -279,6 +292,18 @@ static int pci_device_suspend(struct dev
 	return i;
 }
 
+static int pci_device_suspend_late(struct device * dev, pm_message_t state)
+{
+	struct pci_dev * pci_dev = to_pci_dev(dev);
+	struct pci_driver * drv = pci_dev->driver;
+	int i = 0;
+
+	if (drv && drv->suspend_late) {
+		i = drv->suspend_late(pci_dev, state);
+		suspend_report_result(drv->suspend_late, i);
+	}
+	return i;
+}
 
 /*
  * Default resume method for devices that have no driver provided resume,
@@ -313,6 +338,17 @@ static int pci_device_resume(struct devi
 	return error;
 }
 
+static int pci_device_resume_early(struct device * dev)
+{
+	int error = 0;
+	struct pci_dev * pci_dev = to_pci_dev(dev);
+	struct pci_driver * drv = pci_dev->driver;
+
+	if (drv && drv->resume_early)
+		error = drv->resume_early(pci_dev);
+	return error;
+}
+
 static void pci_device_shutdown(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -508,9 +544,12 @@ struct bus_type pci_bus_type = {
 	.uevent		= pci_uevent,
 	.probe		= pci_device_probe,
 	.remove		= pci_device_remove,
+	.suspend_prepare= pci_device_suspend_prepare,
 	.suspend	= pci_device_suspend,
-	.shutdown	= pci_device_shutdown,
+	.suspend_late	= pci_device_suspend_late,
+	.resume_early	= pci_device_resume_early,
 	.resume		= pci_device_resume,
+	.shutdown	= pci_device_shutdown,
 	.dev_attrs	= pci_dev_attrs,
 };
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8565b81..4b2e629 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -345,7 +345,10 @@ struct pci_driver {
 	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	int  (*suspend_prepare) (struct pci_dev *dev, pm_message_t state);
 	int  (*suspend) (struct pci_dev *dev, pm_message_t state);	/* Device suspended */
+	int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
+	int  (*resume_early) (struct pci_dev *dev);
 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
 	int  (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);   /* Enable wake event */
 	void (*shutdown) (struct pci_dev *dev);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 11/47] make suspend quieter
  2006-09-26  5:37                   ` [PATCH 10/47] Suspend changes for PCI core Greg KH
@ 2006-09-26  5:37                     ` Greg KH
  2006-09-26  5:37                       ` [PATCH 12/47] fix broken/dubious driver suspend() methods Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Fix a goof in Linus' recent PM API updates:  don't emit any messages in the
typical NOP "already suspended it" late suspend case.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/suspend.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 10e8032..0bda4a7 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -102,11 +102,6 @@ static int suspend_device_late(struct de
 {
 	int error = 0;
 
-	if (dev->power.power_state.event) {
-		dev_dbg(dev, "PM: suspend_late %d-->%d\n",
-			dev->power.power_state.event, state.event);
-	}
-
 	if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) {
 		dev_dbg(dev, "LATE %s%s\n",
 			suspend_verb(state.event),
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 12/47] fix broken/dubious driver suspend() methods
  2006-09-26  5:37                     ` [PATCH 11/47] make suspend quieter Greg KH
@ 2006-09-26  5:37                       ` Greg KH
  2006-09-26  5:37                         ` [PATCH 13/47] PM: define PM_EVENT_PRETHAW Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Small driver suspend() fixes in preparation for the PRETHAW events:

 - Only compare message events for equality against PM_EVENT_* codes;
   not against integers, or using greater/less-than comparisons.
   (PM_EVENT_* should really become a __bitwise thing.)

 - Explicitly test for SUSPEND events (rather than not-something-else)
   before suspending devices.

 - Removes more of the confusion between a pm_message_t (wraps event code)
   and a "state" ... suspend() originally took a target system state.

These updates are correct and appropriate even without new PM_EVENT codes.

benh: "I think in the Mesh case, we should handle the freeze case as well or
we might get wild DMA."

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Pavel Machek <pavel@ucw.cz>
Cc: Greg KH <greg@kroah.com>
Cc: Paul Mackerras <paulus@samba.org>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/ide/ppc/pmac.c                  |   14 ++++++++------
 drivers/media/dvb/cinergyT2/cinergyT2.c |    2 +-
 drivers/scsi/mesh.c                     |   15 +++++++++++----
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 996c694..31ad79f 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1369,15 +1369,16 @@ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 }
 
 static int
-pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t state)
+pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
 {
 	ide_hwif_t	*hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
 	int		rc = 0;
 
-	if (state.event != mdev->ofdev.dev.power.power_state.event && state.event >= PM_EVENT_SUSPEND) {
+	if (mesg.event != mdev->ofdev.dev.power.power_state.event
+			&& mesg.event == PM_EVENT_SUSPEND) {
 		rc = pmac_ide_do_suspend(hwif);
 		if (rc == 0)
-			mdev->ofdev.dev.power.power_state = state;
+			mdev->ofdev.dev.power.power_state = mesg;
 	}
 
 	return rc;
@@ -1473,15 +1474,16 @@ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 }
 
 static int
-pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
 	ide_hwif_t	*hwif = (ide_hwif_t *)pci_get_drvdata(pdev);
 	int		rc = 0;
 	
-	if (state.event != pdev->dev.power.power_state.event && state.event >= 2) {
+	if (mesg.event != pdev->dev.power.power_state.event
+			&& mesg.event == PM_EVENT_SUSPEND) {
 		rc = pmac_ide_do_suspend(hwif);
 		if (rc == 0)
-			pdev->dev.power.power_state = state;
+			pdev->dev.power.power_state = mesg;
 	}
 
 	return rc;
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 001c71b..410fa6d 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -981,7 +981,7 @@ static int cinergyt2_suspend (struct usb
 	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
-	if (state.event > PM_EVENT_ON) {
+	if (1) {
 		struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
 		cinergyt2_suspend_rc(cinergyt2);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 592b52a..683fc7a 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1756,16 +1756,23 @@ static void set_mesh_power(struct mesh_s
 		pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 0);
 		msleep(10);
 	}
-}			
+}
 
 
 #ifdef CONFIG_PM
-static int mesh_suspend(struct macio_dev *mdev, pm_message_t state)
+static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg)
 {
 	struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
 	unsigned long flags;
 
-	if (state.event == mdev->ofdev.dev.power.power_state.event || state.event < 2)
+	switch (mesg.event) {
+	case PM_EVENT_SUSPEND:
+	case PM_EVENT_FREEZE:
+		break;
+	default:
+		return 0;
+	}
+	if (mesg.event == mdev->ofdev.dev.power.power_state.event)
 		return 0;
 
 	scsi_block_requests(ms->host);
@@ -1780,7 +1787,7 @@ static int mesh_suspend(struct macio_dev
 	disable_irq(ms->meshintr);
 	set_mesh_power(ms, 0);
 
-	mdev->ofdev.dev.power.power_state = state;
+	mdev->ofdev.dev.power.power_state = mesg;
 
 	return 0;
 }
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 13/47] PM: define PM_EVENT_PRETHAW
  2006-09-26  5:37                       ` [PATCH 12/47] fix broken/dubious driver suspend() methods Greg KH
@ 2006-09-26  5:37                         ` Greg KH
  2006-09-26  5:37                           ` [PATCH 14/47] PM: PCI and IDE handle PM_EVENT_PRETHAW Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

This adds a new pm_message_t event type to use when preparing to restore a
swsusp snapshot.  Devices that have been initialized by Linux after resume
(rather than left in power-up-reset state) may need to be reset; this new
event type give drivers the chance to do that.

The drivers that will care about this are those which understand more hardware
states than just "on" and "reset", relying on hardware state during resume()
methods to be either the state left by the preceding suspend(), or a
power-lost reset.  The best current example of this class of drivers are USB
host controller drivers, which currently do not work through swsusp when
they're statically linked.

When the swsusp freeze/thaw mechanism kicks in, a troublesome third state
could exist: one state set up by a different kernel instance, before a
snapshot image is resumed.  This mechanism lets drivers prevent that state.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/pm.h |   62 +++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/include/linux/pm.h b/include/linux/pm.h
index 096fb6f..6b27e07 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -142,29 +142,61 @@ typedef struct pm_message {
 } pm_message_t;
 
 /*
- * There are 4 important states driver can be in:
- * ON     -- driver is working
- * FREEZE -- stop operations and apply whatever policy is applicable to a
- *           suspended driver of that class, freeze queues for block like IDE
- *           does, drop packets for ethernet, etc... stop DMA engine too etc...
- *           so a consistent image can be saved; but do not power any hardware
- *           down.
- * SUSPEND - like FREEZE, but hardware is doing as much powersaving as
- *           possible. Roughly pci D3.
+ * Several driver power state transitions are externally visible, affecting
+ * the state of pending I/O queues and (for drivers that touch hardware)
+ * interrupts, wakeups, DMA, and other hardware state.  There may also be
+ * internal transitions to various low power modes, which are transparent
+ * to the rest of the driver stack (such as a driver that's ON gating off
+ * clocks which are not in active use).
  *
- * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
- * (SUSPEND).  We'll need to fix the drivers. So yes, putting 3 to all different
- * defines is intentional, and will go away as soon as drivers are fixed.  Also
- * note that typedef is neccessary, we'll probably want to switch to
- *   typedef struct pm_message_t { int event; int flags; } pm_message_t
- * or something similar soon.
+ * One transition is triggered by resume(), after a suspend() call; the
+ * message is implicit:
+ *
+ * ON		Driver starts working again, responding to hardware events
+ * 		and software requests.  The hardware may have gone through
+ * 		a power-off reset, or it may have maintained state from the
+ * 		previous suspend() which the driver will rely on while
+ * 		resuming.  On most platforms, there are no restrictions on
+ * 		availability of resources like clocks during resume().
+ *
+ * Other transitions are triggered by messages sent using suspend().  All
+ * these transitions quiesce the driver, so that I/O queues are inactive.
+ * That commonly entails turning off IRQs and DMA; there may be rules
+ * about how to quiesce that are specific to the bus or the device's type.
+ * (For example, network drivers mark the link state.)  Other details may
+ * differ according to the message:
+ *
+ * SUSPEND	Quiesce, enter a low power device state appropriate for
+ * 		the upcoming system state (such as PCI_D3hot), and enable
+ * 		wakeup events as appropriate.
+ *
+ * FREEZE	Quiesce operations so that a consistent image can be saved;
+ * 		but do NOT otherwise enter a low power device state, and do
+ * 		NOT emit system wakeup events.
+ *
+ * PRETHAW	Quiesce as if for FREEZE; additionally, prepare for restoring
+ * 		the system from a snapshot taken after an earlier FREEZE.
+ * 		Some drivers will need to reset their hardware state instead
+ * 		of preserving it, to ensure that it's never mistaken for the
+ * 		state which that earlier snapshot had set up.
+ *
+ * A minimally power-aware driver treats all messages as SUSPEND, fully
+ * reinitializes its device during resume() -- whether or not it was reset
+ * during the suspend/resume cycle -- and can't issue wakeup events.
+ *
+ * More power-aware drivers may also use low power states at runtime as
+ * well as during system sleep states like PM_SUSPEND_STANDBY.  They may
+ * be able to use wakeup events to exit from runtime low-power states,
+ * or from system low-power states such as standby or suspend-to-RAM.
  */
 
 #define PM_EVENT_ON 0
 #define PM_EVENT_FREEZE 1
 #define PM_EVENT_SUSPEND 2
+#define PM_EVENT_PRETHAW 3
 
 #define PMSG_FREEZE	((struct pm_message){ .event = PM_EVENT_FREEZE, })
+#define PMSG_PRETHAW	((struct pm_message){ .event = PM_EVENT_PRETHAW, })
 #define PMSG_SUSPEND	((struct pm_message){ .event = PM_EVENT_SUSPEND, })
 #define PMSG_ON		((struct pm_message){ .event = PM_EVENT_ON, })
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 14/47] PM: PCI and IDE handle PM_EVENT_PRETHAW
  2006-09-26  5:37                         ` [PATCH 13/47] PM: define PM_EVENT_PRETHAW Greg KH
@ 2006-09-26  5:37                           ` Greg KH
  2006-09-26  5:37                             ` [PATCH 15/47] PM: video drivers and PM_EVENT_PRETHAW Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Convert some framework code to handle the new PRETHAW message.

  - IDE just treats it like a FREEZE.

  - The pci_choose_state() thingie still doesn't use PCI_D0 when it gets a
    FREEZE (and now PRETHAW) event, which seems rather buglike but wasn't
    something to change with this patch.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/ide/ide.c |    6 ++++--
 drivers/pci/pci.c |    4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index defd4b4..9c8468d 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1207,7 +1207,7 @@ int system_bus_clock (void)
 
 EXPORT_SYMBOL(system_bus_clock);
 
-static int generic_ide_suspend(struct device *dev, pm_message_t state)
+static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 {
 	ide_drive_t *drive = dev->driver_data;
 	struct request rq;
@@ -1221,7 +1221,9 @@ static int generic_ide_suspend(struct de
 	rq.special = &args;
 	rq.end_io_data = &rqpm;
 	rqpm.pm_step = ide_pm_state_start_suspend;
-	rqpm.pm_state = state.event;
+	if (mesg.event == PM_EVENT_PRETHAW)
+		mesg.event = PM_EVENT_FREEZE;
+	rqpm.pm_state = mesg.event;
 
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9f79dd6..8ab0278 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -432,10 +432,12 @@ pci_power_t pci_choose_state(struct pci_
 	case PM_EVENT_ON:
 		return PCI_D0;
 	case PM_EVENT_FREEZE:
+	case PM_EVENT_PRETHAW:
+		/* REVISIT both freeze and pre-thaw "should" use D0 */
 	case PM_EVENT_SUSPEND:
 		return PCI_D3hot;
 	default:
-		printk("They asked me for state %d\n", state.event);
+		printk("Unrecognized suspend event %d\n", state.event);
 		BUG();
 	}
 	return PCI_D0;
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 15/47] PM: video drivers and PM_EVENT_PRETHAW
  2006-09-26  5:37                           ` [PATCH 14/47] PM: PCI and IDE handle PM_EVENT_PRETHAW Greg KH
@ 2006-09-26  5:37                             ` Greg KH
  2006-09-26  5:37                               ` [PATCH 16/47] PM: USB HCDs use PM_EVENT_PRETHAW Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Video drivers which explicitly test for messages reporting PM_EVENT_FREEZE
will now handle PM_EVENT_PRETHAW the same way.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/video/aty/radeon_pm.c          |   15 +++++++++------
 drivers/video/i810/i810_main.c         |   12 +++++++-----
 drivers/video/nvidia/nvidia.c          |   13 +++++++------
 drivers/video/savage/savagefb_driver.c |   14 +++++++-------
 4 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index e308ed2..365de5d 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2621,25 +2621,28 @@ static int radeon_restore_pci_cfg(struct
 }
 
 
-int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
         struct fb_info *info = pci_get_drvdata(pdev);
         struct radeonfb_info *rinfo = info->par;
 	int i;
 
-	if (state.event == pdev->dev.power.power_state.event)
+	if (mesg.event == pdev->dev.power.power_state.event)
 		return 0;
 
-	printk(KERN_DEBUG "radeonfb (%s): suspending to state: %d...\n",
-	       pci_name(pdev), state.event);
+	printk(KERN_DEBUG "radeonfb (%s): suspending for event: %d...\n",
+	       pci_name(pdev), mesg.event);
 
 	/* For suspend-to-disk, we cheat here. We don't suspend anything and
 	 * let fbcon continue drawing until we are all set. That shouldn't
 	 * really cause any problem at this point, provided that the wakeup
 	 * code knows that any state in memory may not match the HW
 	 */
-	if (state.event == PM_EVENT_FREEZE)
+	switch (mesg.event) {
+	case PM_EVENT_FREEZE:		/* about to take snapshot */
+	case PM_EVENT_PRETHAW:		/* before restoring snapshot */
 		goto done;
+	}
 
 	acquire_console_sem();
 
@@ -2706,7 +2709,7 @@ #endif /* CONFIG_PPC_PMAC */
 	release_console_sem();
 
  done:
-	pdev->dev.power.power_state = state;
+	pdev->dev.power.power_state = mesg;
 
 	return 0;
 }
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index a6ca02f..d42edac 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1554,15 +1554,17 @@ static struct fb_ops i810fb_ops __devini
 /***********************************************************************
  *                         Power Management                            *
  ***********************************************************************/
-static int i810fb_suspend(struct pci_dev *dev, pm_message_t state)
+static int i810fb_suspend(struct pci_dev *dev, pm_message_t mesg)
 {
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct i810fb_par *par = info->par;
 
-	par->cur_state = state.event;
+	par->cur_state = mesg.event;
 
-	if (state.event == PM_EVENT_FREEZE) {
-		dev->dev.power.power_state = state;
+	switch (mesg.event) {
+	case PM_EVENT_FREEZE:
+	case PM_EVENT_PRETHAW:
+		dev->dev.power.power_state = mesg;
 		return 0;
 	}
 
@@ -1578,7 +1580,7 @@ static int i810fb_suspend(struct pci_dev
 
 	pci_save_state(dev);
 	pci_disable_device(dev);
-	pci_set_power_state(dev, pci_choose_state(dev, state));
+	pci_set_power_state(dev, pci_choose_state(dev, mesg));
 	release_console_sem();
 
 	return 0;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index d4f8501..f8cd4c5 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -950,24 +950,25 @@ static struct fb_ops nvidia_fb_ops = {
 };
 
 #ifdef CONFIG_PM
-static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state)
+static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
 {
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct nvidia_par *par = info->par;
 
+	if (mesg.event == PM_EVENT_PRETHAW)
+		mesg.event = PM_EVENT_FREEZE;
 	acquire_console_sem();
-	par->pm_state = state.event;
+	par->pm_state = mesg.event;
 
-	if (state.event == PM_EVENT_FREEZE) {
-		dev->dev.power.power_state = state;
-	} else {
+	if (mesg.event == PM_EVENT_SUSPEND) {
 		fb_set_suspend(info, 1);
 		nvidiafb_blank(FB_BLANK_POWERDOWN, info);
 		nvidia_write_regs(par, &par->SavedReg);
 		pci_save_state(dev);
 		pci_disable_device(dev);
-		pci_set_power_state(dev, pci_choose_state(dev, state));
+		pci_set_power_state(dev, pci_choose_state(dev, mesg));
 	}
+	dev->dev.power.power_state = mesg;
 
 	release_console_sem();
 	return 0;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 461e094..82b3dea 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2323,24 +2323,24 @@ #endif
 	}
 }
 
-static int savagefb_suspend(struct pci_dev* dev, pm_message_t state)
+static int savagefb_suspend(struct pci_dev *dev, pm_message_t mesg)
 {
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct savagefb_par *par = info->par;
 
 	DBG("savagefb_suspend");
 
-
-	par->pm_state = state.event;
+	if (mesg.event == PM_EVENT_PRETHAW)
+		mesg.event = PM_EVENT_FREEZE;
+	par->pm_state = mesg.event;
+	dev->dev.power.power_state = mesg;
 
 	/*
 	 * For PM_EVENT_FREEZE, do not power down so the console
 	 * can remain active.
 	 */
-	if (state.event == PM_EVENT_FREEZE) {
-		dev->dev.power.power_state = state;
+	if (mesg.event == PM_EVENT_FREEZE)
 		return 0;
-	}
 
 	acquire_console_sem();
 	fb_set_suspend(info, 1);
@@ -2353,7 +2353,7 @@ static int savagefb_suspend(struct pci_d
 	savage_disable_mmio(par);
 	pci_save_state(dev);
 	pci_disable_device(dev);
-	pci_set_power_state(dev, pci_choose_state(dev, state));
+	pci_set_power_state(dev, pci_choose_state(dev, mesg));
 	release_console_sem();
 
 	return 0;
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 16/47] PM: USB HCDs use PM_EVENT_PRETHAW
  2006-09-26  5:37                             ` [PATCH 15/47] PM: video drivers and PM_EVENT_PRETHAW Greg KH
@ 2006-09-26  5:37                               ` Greg KH
  2006-09-26  5:37                                 ` [PATCH 17/47] PM: issue PM_EVENT_PRETHAW Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

This teaches several USB host controller drivers to treat PRETHAW as a chip
reset since the controller, and all devices connected to it, are no longer in
states compatible with how the snapshotted suspend() left them.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/usb/core/hcd-pci.c   |    2 +-
 drivers/usb/host/ehci-pci.c  |    6 ++++++
 drivers/usb/host/ohci-pci.c  |    5 +++++
 drivers/usb/host/sl811-hcd.c |    9 +++++++--
 drivers/usb/host/uhci-hcd.c  |    4 ++++
 5 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 5078fb3..fa36391 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -281,7 +281,7 @@ int usb_hcd_pci_suspend (struct pci_dev 
 			(void) usb_hcd_pci_resume (dev);
 		}
 
-	} else {
+	} else if (hcd->state != HC_STATE_HALT) {
 		dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n",
 			hcd->state);
 		WARN_ON(1);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index cadffac..6967ab7 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -238,6 +238,12 @@ static int ehci_pci_suspend(struct usb_h
 	writel (0, &ehci->regs->intr_enable);
 	(void)readl(&ehci->regs->intr_enable);
 
+	/* make sure snapshot being resumed re-enumerates everything */
+	if (message.event == PM_EVENT_PRETHAW) {
+		ehci_halt(ehci);
+		ehci_reset(ehci);
+	}
+
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
  bail:
 	spin_unlock_irqrestore (&ehci->lock, flags);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index b268537..37e1228 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -135,6 +135,11 @@ static int ohci_pci_suspend (struct usb_
 	}
 	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
 	(void)ohci_readl(ohci, &ohci->regs->intrdisable);
+
+	/* make sure snapshot being resumed re-enumerates everything */
+	if (message.event == PM_EVENT_PRETHAW)
+		ohci_usb_reset(ohci);
+
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
  bail:
 	spin_unlock_irqrestore (&ohci->lock, flags);
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index fa34092..9de115d 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1783,10 +1783,15 @@ sl811h_suspend(struct platform_device *d
 	struct sl811	*sl811 = hcd_to_sl811(hcd);
 	int		retval = 0;
 
-	if (state.event == PM_EVENT_FREEZE)
+	switch (state.event) {
+	case PM_EVENT_FREEZE:
 		retval = sl811h_bus_suspend(hcd);
-	else if (state.event == PM_EVENT_SUSPEND)
+		break;
+	case PM_EVENT_SUSPEND:
+	case PM_EVENT_PRETHAW:		/* explicitly discard hw state */
 		port_power(sl811, 0);
+		break;
+	}
 	if (retval == 0)
 		dev->dev.power.power_state = state;
 	return retval;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 4151f61..b7402ce 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -734,6 +734,10 @@ static int uhci_suspend(struct usb_hcd *
 
 	/* FIXME: Enable non-PME# remote wakeup? */
 
+	/* make sure snapshot being resumed re-enumerates everything */
+	if (message.event == PM_EVENT_PRETHAW)
+		uhci_hc_died(uhci);
+
 done_okay:
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 done:
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 17/47] PM: issue PM_EVENT_PRETHAW
  2006-09-26  5:37                               ` [PATCH 16/47] PM: USB HCDs use PM_EVENT_PRETHAW Greg KH
@ 2006-09-26  5:37                                 ` Greg KH
  2006-09-26  5:37                                   ` [PATCH 18/47] updated Documentation/power/devices.txt Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Brownell, David Brownell, Andrew Morton, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

This patch is the first of this series that should actually change any
behavior ...  by issuing the new event, now tha the rest of the kernel is
prepared to receive it.

This converts the PM core to issue the new PRETHAW message, which the rest of
the kernel is now ready to receive.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/suspend.c |    1 +
 kernel/power/disk.c          |    4 ++--
 kernel/power/swsusp.c        |    9 ++++++++-
 kernel/power/user.c          |    2 +-
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 0bda4a7..e86db83 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -34,6 +34,7 @@ static inline char *suspend_verb(u32 eve
 	switch (event) {
 	case PM_EVENT_SUSPEND:	return "suspend";
 	case PM_EVENT_FREEZE:	return "freeze";
+	case PM_EVENT_PRETHAW:	return "prethaw";
 	default:		return "(unknown suspend event)";
 	}
 }
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index e13e740..a3c34fb 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -98,7 +98,7 @@ static void unprepare_processes(void)
 }
 
 /**
- *	pm_suspend_disk - The granpappy of power management.
+ *	pm_suspend_disk - The granpappy of hibernation power management.
  *
  *	If we're going through the firmware, then get it over with quickly.
  *
@@ -207,7 +207,7 @@ static int software_resume(void)
 
 	pr_debug("PM: Preparing devices for restore.\n");
 
-	if ((error = device_suspend(PMSG_FREEZE))) {
+	if ((error = device_suspend(PMSG_PRETHAW))) {
 		printk("Some devices failed to suspend\n");
 		swsusp_free();
 		goto Thaw;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 17f669c..6275289 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -248,6 +248,9 @@ int swsusp_suspend(void)
 	restore_processor_state();
 Restore_highmem:
 	restore_highmem();
+	/* NOTE:  device_power_up() is just a resume() for devices
+	 * that suspended with irqs off ... no overall powerup.
+	 */
 	device_power_up();
 Enable_irqs:
 	local_irq_enable();
@@ -257,8 +260,12 @@ Enable_irqs:
 int swsusp_resume(void)
 {
 	int error;
+
 	local_irq_disable();
-	if (device_power_down(PMSG_FREEZE))
+	/* NOTE:  device_power_down() is just a suspend() with irqs off;
+	 * it has no special "power things down" semantics
+	 */
+	if (device_power_down(PMSG_PRETHAW))
 		printk(KERN_ERR "Some devices failed to power down, very bad\n");
 	/* We'll ignore saved state, but this gets preempt count (etc) right */
 	save_processor_state();
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 3f1539f..5a8d060 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -191,7 +191,7 @@ static int snapshot_ioctl(struct inode *
 		}
 		down(&pm_sem);
 		pm_prepare_console();
-		error = device_suspend(PMSG_FREEZE);
+		error = device_suspend(PMSG_PRETHAW);
 		if (!error) {
 			error = swsusp_resume();
 			device_resume();
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 18/47] updated Documentation/power/devices.txt
  2006-09-26  5:37                                 ` [PATCH 17/47] PM: issue PM_EVENT_PRETHAW Greg KH
@ 2006-09-26  5:37                                   ` Greg KH
  2006-09-26  5:37                                     ` [PATCH 19/47] PM: update docs for writing .../power/state Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

This turned into a rewrite of Documentation/power/devices.txt:

 - Provide more of the "big picture"

 - Fixup some of the horribly ancient/obsolete description of device suspend()
   semantics; lots of text just got deleted.

 - Add a decent description of PM_EVENT_* codes, including the new PRETHAW code
   needed in some swsusp scenarios.

 - Describe the new PM factorization from Linus:
     * class suspend, current suspend, then suspend_late
     * NOT suspend_prepare, it wasn't really usable
     * resume_early, current resume, class resume.

 - Updates power/state docs to be correct, and deprecate its usage except for
   driver testing.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/power/devices.txt |  733 +++++++++++++++++++++++++++++----------
 1 files changed, 539 insertions(+), 194 deletions(-)

diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index fba1e05..d0e79d5 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -1,208 +1,553 @@
+Most of the code in Linux is device drivers, so most of the Linux power
+management code is also driver-specific.  Most drivers will do very little;
+others, especially for platforms with small batteries (like cell phones),
+will do a lot.
+
+This writeup gives an overview of how drivers interact with system-wide
+power management goals, emphasizing the models and interfaces that are
+shared by everything that hooks up to the driver model core.  Read it as
+background for the domain-specific work you'd do with any specific driver.
+
+
+Two Models for Device Power Management
+======================================
+Drivers will use one or both of these models to put devices into low-power
+states:
+
+    System Sleep model:
+	Drivers can enter low power states as part of entering system-wide
+	low-power states like "suspend-to-ram", or (mostly for systems with
+	disks) "hibernate" (suspend-to-disk).
+
+	This is something that device, bus, and class drivers collaborate on
+	by implementing various role-specific suspend and resume methods to
+	cleanly power down hardware and software subsystems, then reactivate
+	them without loss of data.
+
+	Some drivers can manage hardware wakeup events, which make the system
+	leave that low-power state.  This feature may be disabled using the
+	relevant /sys/devices/.../power/wakeup file; enabling it may cost some
+	power usage, but let the whole system enter low power states more often.
+
+    Runtime Power Management model:
+	Drivers may also enter low power states while the system is running,
+	independently of other power management activity.  Upstream drivers
+	will normally not know (or care) if the device is in some low power
+	state when issuing requests; the driver will auto-resume anything
+	that's needed when it gets a request.
+
+	This doesn't have, or need much infrastructure; it's just something you
+	should do when writing your drivers.  For example, clk_disable() unused
+	clocks as part of minimizing power drain for currently-unused hardware.
+	Of course, sometimes clusters of drivers will collaborate with each
+	other, which could involve task-specific power management.
+
+There's not a lot to be said about those low power states except that they
+are very system-specific, and often device-specific.  Also, that if enough
+drivers put themselves into low power states (at "runtime"), the effect may be
+the same as entering some system-wide low-power state (system sleep) ... and
+that synergies exist, so that several drivers using runtime pm might put the
+system into a state where even deeper power saving options are available.
+
+Most suspended devices will have quiesced all I/O:  no more DMA or irqs, no
+more data read or written, and requests from upstream drivers are no longer
+accepted.  A given bus or platform may have different requirements though.
+
+Examples of hardware wakeup events include an alarm from a real time clock,
+network wake-on-LAN packets, keyboard or mouse activity, and media insertion
+or removal (for PCMCIA, MMC/SD, USB, and so on).
+
+
+Interfaces for Entering System Sleep States
+===========================================
+Most of the programming interfaces a device driver needs to know about
+relate to that first model:  entering a system-wide low power state,
+rather than just minimizing power consumption by one device.
+
+
+Bus Driver Methods
+------------------
+The core methods to suspend and resume devices reside in struct bus_type.
+These are mostly of interest to people writing infrastructure for busses
+like PCI or USB, or because they define the primitives that device drivers
+may need to apply in domain-specific ways to their devices:
 
-Device Power Management
-
-
-Device power management encompasses two areas - the ability to save
-state and transition a device to a low-power state when the system is
-entering a low-power state; and the ability to transition a device to
-a low-power state while the system is running (and independently of
-any other power management activity). 
-
-
-Methods
+struct bus_type {
+	...
+	int  (*suspend)(struct device *dev, pm_message_t state);
+	int  (*suspend_late)(struct device *dev, pm_message_t state);
 
-The methods to suspend and resume devices reside in struct bus_type: 
+	int  (*resume_early)(struct device *dev);
+	int  (*resume)(struct device *dev);
+};
 
-struct bus_type {
-       ...
-       int             (*suspend)(struct device * dev, pm_message_t state);
-       int             (*resume)(struct device * dev);
+Bus drivers implement those methods as appropriate for the hardware and
+the drivers using it; PCI works differently from USB, and so on.  Not many
+people write bus drivers; most driver code is a "device driver" that
+builds on top of bus-specific framework code.
+
+For more information on these driver calls, see the description later;
+they are called in phases for every device, respecting the parent-child
+sequencing in the driver model tree.  Note that as this is being written,
+only the suspend() and resume() are widely available; not many bus drivers
+leverage all of those phases, or pass them down to lower driver levels.
+
+
+/sys/devices/.../power/wakeup files
+-----------------------------------
+All devices in the driver model have two flags to control handling of
+wakeup events, which are hardware signals that can force the device and/or
+system out of a low power state.  These are initialized by bus or device
+driver code using device_init_wakeup(dev,can_wakeup).
+
+The "can_wakeup" flag just records whether the device (and its driver) can
+physically support wakeup events.  When that flag is clear, the sysfs
+"wakeup" file is empty, and device_may_wakeup() returns false.
+
+For devices that can issue wakeup events, a separate flag controls whether
+that device should try to use its wakeup mechanism.  The initial value of
+device_may_wakeup() will be true, so that the device's "wakeup" file holds
+the value "enabled".  Userspace can change that to "disabled" so that
+device_may_wakeup() returns false; or change it back to "enabled" (so that
+it returns true again).
+
+
+EXAMPLE:  PCI Device Driver Methods
+-----------------------------------
+PCI framework software calls these methods when the PCI device driver bound
+to a device device has provided them:
+
+struct pci_driver {
+	...
+	int  (*suspend)(struct pci_device *pdev, pm_message_t state);
+	int  (*suspend_late)(struct pci_device *pdev, pm_message_t state);
+
+	int  (*resume_early)(struct pci_device *pdev);
+	int  (*resume)(struct pci_device *pdev);
 };
 
-Each bus driver is responsible implementing these methods, translating
-the call into a bus-specific request and forwarding the call to the
-bus-specific drivers. For example, PCI drivers implement suspend() and
-resume() methods in struct pci_driver. The PCI core is simply
-responsible for translating the pointers to PCI-specific ones and
-calling the low-level driver.
-
-This is done to a) ease transition to the new power management methods
-and leverage the existing PM code in various bus drivers; b) allow
-buses to implement generic and default PM routines for devices, and c)
-make the flow of execution obvious to the reader. 
-
-
-System Power Management
-
-When the system enters a low-power state, the device tree is walked in
-a depth-first fashion to transition each device into a low-power
-state. The ordering of the device tree is guaranteed by the order in
-which devices get registered - children are never registered before
-their ancestors, and devices are placed at the back of the list when
-registered. By walking the list in reverse order, we are guaranteed to
-suspend devices in the proper order. 
-
-Devices are suspended once with interrupts enabled. Drivers are
-expected to stop I/O transactions, save device state, and place the
-device into a low-power state. Drivers may sleep, allocate memory,
-etc. at will. 
-
-Some devices are broken and will inevitably have problems powering
-down or disabling themselves with interrupts enabled. For these
-special cases, they may return -EAGAIN. This will put the device on a
-list to be taken care of later. When interrupts are disabled, before
-we enter the low-power state, their drivers are called again to put
-their device to sleep. 
-
-On resume, the devices that returned -EAGAIN will be called to power
-themselves back on with interrupts disabled. Once interrupts have been
-re-enabled, the rest of the drivers will be called to resume their
-devices. On resume, a driver is responsible for powering back on each
-device, restoring state, and re-enabling I/O transactions for that
-device. 
+Drivers will implement those methods, and call PCI-specific procedures
+like pci_set_power_state(), pci_enable_wake(), pci_save_state(), and
+pci_restore_state() to manage PCI-specific mechanisms.  (PCI config space
+could be saved during driver probe, if it weren't for the fact that some
+systems rely on userspace tweaking using setpci.)  Devices are suspended
+before their bridges enter low power states, and likewise bridges resume
+before their devices.
+
+
+Upper Layers of Driver Stacks
+-----------------------------
+Device drivers generally have at least two interfaces, and the methods
+sketched above are the ones which apply to the lower level (nearer PCI, USB,
+or other bus hardware).  The network and block layers are examples of upper
+level interfaces, as is a character device talking to userspace.
+
+Power management requests normally need to flow through those upper levels,
+which often use domain-oriented requests like "blank that screen".  In
+some cases those upper levels will have power management intelligence that
+relates to end-user activity, or other devices that work in cooperation.
+
+When those interfaces are structured using class interfaces, there is a
+standard way to have the upper layer stop issuing requests to a given
+class device (and restart later):
+
+struct class {
+	...
+	int  (*suspend)(struct device *dev, pm_message_t state);
+	int  (*resume)(struct device *dev);
+};
 
+Those calls are issued in specific phases of the process by which the
+system enters a low power "suspend" state, or resumes from it.
+
+
+Calling Drivers to Enter System Sleep States
+============================================
+When the system enters a low power state, each device's driver is asked
+to suspend the device by putting it into state compatible with the target
+system state.  That's usually some version of "off", but the details are
+system-specific.  Also, wakeup-enabled devices will usually stay partly
+functional in order to wake the system.
+
+When the system leaves that low power state, the device's driver is asked
+to resume it.  The suspend and resume operations always go together, and
+both are multi-phase operations.
+
+For simple drivers, suspend might quiesce the device using the class code
+and then turn its hardware as "off" as possible with late_suspend.  The
+matching resume calls would then completely reinitialize the hardware
+before reactivating its class I/O queues.
+
+More power-aware drivers drivers will use more than one device low power
+state, either at runtime or during system sleep states, and might trigger
+system wakeup events.
+
+
+Call Sequence Guarantees
+------------------------
+To ensure that bridges and similar links needed to talk to a device are
+available when the device is suspended or resumed, the device tree is
+walked in a bottom-up order to suspend devices.  A top-down order is
+used to resume those devices.
+
+The ordering of the device tree is defined by the order in which devices
+get registered:  a child can never be registered, probed or resumed before
+its parent; and can't be removed or suspended after that parent.
+
+The policy is that the device tree should match hardware bus topology.
+(Or at least the control bus, for devices which use multiple busses.)
+
+
+Suspending Devices
+------------------
+Suspending a given device is done in several phases.  Suspending the
+system always includes every phase, executing calls for every device
+before the next phase begins.  Not all busses or classes support all
+these callbacks; and not all drivers use all the callbacks.
+
+The phases are seen by driver notifications issued in this order:
+
+   1	class.suspend(dev, message) is called after tasks are frozen, for
+	devices associated with a class that has such a method.  This
+	method may sleep.
+
+	Since I/O activity usually comes from such higher layers, this is
+	a good place to quiesce all drivers of a given type (and keep such
+	code out of those drivers).
+
+   2	bus.suspend(dev, message) is called next.  This method may sleep,
+	and is often morphed into a device driver call with bus-specific
+	parameters and/or rules.
+
+	This call should handle parts of device suspend logic that require
+	sleeping.  It probably does work to quiesce the device which hasn't
+	been abstracted into class.suspend() or bus.suspend_late().
+
+   3	bus.suspend_late(dev, message) is called with IRQs disabled, and
+	with only one CPU active.  Until the bus.resume_early() phase
+	completes (see later), IRQs are not enabled again.  This method
+	won't be exposed by all busses; for message based busses like USB,
+	I2C, or SPI, device interactions normally require IRQs.  This bus
+	call may be morphed into a driver call with bus-specific parameters.
+
+	This call might save low level hardware state that might otherwise
+	be lost in the upcoming low power state, and actually put the
+	device into a low power state ... so that in some cases the device
+	may stay partly usable until this late.  This "late" call may also
+	help when coping with hardware that behaves badly.
+
+The pm_message_t parameter is currently used to refine those semantics
+(described later).
+
+At the end of those phases, drivers should normally have stopped all I/O
+transactions (DMA, IRQs), saved enough state that they can re-initialize
+or restore previous state (as needed by the hardware), and placed the
+device into a low-power state.  On many platforms they will also use
+clk_disable() to gate off one or more clock sources; sometimes they will
+also switch off power supplies, or reduce voltages.  Drivers which have
+runtime PM support may already have performed some or all of the steps
+needed to prepare for the upcoming system sleep state.
+
+When any driver sees that its device_can_wakeup(dev), it should make sure
+to use the relevant hardware signals to trigger a system wakeup event.
+For example, enable_irq_wake() might identify GPIO signals hooked up to
+a switch or other external hardware, and pci_enable_wake() does something
+similar for PCI's PME# signal.
+
+If a driver (or bus, or class) fails it suspend method, the system won't
+enter the desired low power state; it will resume all the devices it's
+suspended so far.
+
+Note that drivers may need to perform different actions based on the target
+system lowpower/sleep state.  At this writing, there are only platform
+specific APIs through which drivers could determine those target states.
+
+
+Device Low Power (suspend) States
+---------------------------------
+Device low-power states aren't very standard.  One device might only handle
+"on" and "off, while another might support a dozen different versions of
+"on" (how many engines are active?), plus a state that gets back to "on"
+faster than from a full "off".
+
+Some busses define rules about what different suspend states mean.  PCI
+gives one example:  after the suspend sequence completes, a non-legacy
+PCI device may not perform DMA or issue IRQs, and any wakeup events it
+issues would be issued through the PME# bus signal.  Plus, there are
+several PCI-standard device states, some of which are optional.
+
+In contrast, integrated system-on-chip processors often use irqs as the
+wakeup event sources (so drivers would call enable_irq_wake) and might
+be able to treat DMA completion as a wakeup event (sometimes DMA can stay
+active too, it'd only be the CPU and some peripherals that sleep).
+
+Some details here may be platform-specific.  Systems may have devices that
+can be fully active in certain sleep states, such as an LCD display that's
+refreshed using DMA while most of the system is sleeping lightly ... and
+its frame buffer might even be updated by a DSP or other non-Linux CPU while
+the Linux control processor stays idle.
+
+Moreover, the specific actions taken may depend on the target system state.
+One target system state might allow a given device to be very operational;
+another might require a hard shut down with re-initialization on resume.
+And two different target systems might use the same device in different
+ways; the aforementioned LCD might be active in one product's "standby",
+but a different product using the same SOC might work differently.
+
+
+Meaning of pm_message_t.event
+-----------------------------
+Parameters to suspend calls include the device affected and a message of
+type pm_message_t, which has one field:  the event.  If driver does not
+recognize the event code, suspend calls may abort the request and return
+a negative errno.  However, most drivers will be fine if they implement
+PM_EVENT_SUSPEND semantics for all messages.
+
+The event codes are used to refine the goal of suspending the device, and
+mostly matter when creating or resuming system memory image snapshots, as
+used with suspend-to-disk:
+
+    PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power
+	state.  When used with system sleep states like "suspend-to-RAM" or
+	"standby", the upcoming resume() call will often be able to rely on
+	state kept in hardware, or issue system wakeup events.  When used
+	instead with suspend-to-disk, few devices support this capability;
+	most are completely powered off.
+
+    PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into
+	any low power mode.  A system snapshot is about to be taken, often
+	followed by a call to the driver's resume() method.  Neither wakeup
+	events nor DMA are allowed.
+
+    PM_EVENT_PRETHAW -- quiesce the driver, knowing that the upcoming resume()
+	will restore a suspend-to-disk snapshot from a different kernel image.
+	Drivers that are smart enough to look at their hardware state during
+	resume() processing need that state to be correct ... a PRETHAW could
+	be used to invalidate that state (by resetting the device), like a
+	shutdown() invocation would before a kexec() or system halt.  Other
+	drivers might handle this the same way as PM_EVENT_FREEZE.  Neither
+	wakeup events nor DMA are allowed.
+
+To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or
+the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend
+to Disk" (STD, hibernate, ACPI S4), all of those event codes are used.
+
+There's also PM_EVENT_ON, a value which never appears as a suspend event
+but is sometimes used to record the "not suspended" device state.
+
+
+Resuming Devices
+----------------
+Resuming is done in multiple phases, much like suspending, with all
+devices processing each phase's calls before the next phase begins.
+
+The phases are seen by driver notifications issued in this order:
+
+   1	bus.resume_early(dev) is called with IRQs disabled, and with
+   	only one CPU active.  As with bus.suspend_late(), this method
+	won't be supported on busses that require IRQs in order to
+	interact with devices.
+
+	This reverses the effects of bus.suspend_late().
+
+   2	bus.resume(dev) is called next.  This may be morphed into a device
+   	driver call with bus-specific parameters; implementations may sleep.
+
+	This reverses the effects of bus.suspend().
+
+   3	class.resume(dev) is called for devices associated with a class
+	that has such a method.  Implementations may sleep.
+
+	This reverses the effects of class.suspend(), and would usually
+	reactivate the device's I/O queue.
+
+At the end of those phases, drivers should normally be as functional as
+they were before suspending:  I/O can be performed using DMA and IRQs, and
+the relevant clocks are gated on.  The device need not be "fully on"; it
+might be in a runtime lowpower/suspend state that acts as if it were.
+
+However, the details here may again be platform-specific.  For example,
+some systems support multiple "run" states, and the mode in effect at
+the end of resume() might not be the one which preceded suspension.
+That means availability of certain clocks or power supplies changed,
+which could easily affect how a driver works.
+
+
+Drivers need to be able to handle hardware which has been reset since the
+suspend methods were called, for example by complete reinitialization.
+This may be the hardest part, and the one most protected by NDA'd documents
+and chip errata.  It's simplest if the hardware state hasn't changed since
+the suspend() was called, but that can't always be guaranteed.
+
+Drivers must also be prepared to notice that the device has been removed
+while the system was powered off, whenever that's physically possible.
+PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses
+where common Linux platforms will see such removal.  Details of how drivers
+will notice and handle such removals are currently bus-specific, and often
+involve a separate thread.
+
+
+Note that the bus-specific runtime PM wakeup mechanism can exist, and might
+be defined to share some of the same driver code as for system wakeup.  For
+example, a bus-specific device driver's resume() method might be used there,
+so it wouldn't only be called from bus.resume() during system-wide wakeup.
+See bus-specific information about how runtime wakeup events are handled.
+
+
+System Devices
+--------------
 System devices follow a slightly different API, which can be found in
 
 	include/linux/sysdev.h
 	drivers/base/sys.c
 
-System devices will only be suspended with interrupts disabled, and
-after all other devices have been suspended. On resume, they will be
-resumed before any other devices, and also with interrupts disabled.
+System devices will only be suspended with interrupts disabled, and after
+all other devices have been suspended.  On resume, they will be resumed
+before any other devices, and also with interrupts disabled.
 
+That is, IRQs are disabled, the suspend_late() phase begins, then the
+sysdev_driver.suspend() phase, and the system enters a sleep state.  Then
+the sysdev_driver.resume() phase begins, followed by the resume_early()
+phase, after which IRQs are enabled.
 
-Runtime Power Management
+Code to actually enter and exit the system-wide low power state sometimes
+involves hardware details that are only known to the boot firmware, and
+may leave a CPU running software (from SRAM or flash memory) that monitors
+the system and manages its wakeup sequence.
 
-Many devices are able to dynamically power down while the system is
-still running. This feature is useful for devices that are not being
-used, and can offer significant power savings on a running system. 
-
-In each device's directory, there is a 'power' directory, which
-contains at least a 'state' file. Reading from this file displays what
-power state the device is currently in. Writing to this file initiates
-a transition to the specified power state, which must be a decimal in
-the range 1-3, inclusive; or 0 for 'On'.
-
-The PM core will call the ->suspend() method in the bus_type object
-that the device belongs to if the specified state is not 0, or
-->resume() if it is. 
-
-Nothing will happen if the specified state is the same state the
-device is currently in. 
-
-If the device is already in a low-power state, and the specified state
-is another, but different, low-power state, the ->resume() method will
-first be called to power the device back on, then ->suspend() will be
-called again with the new state. 
-
-The driver is responsible for saving the working state of the device
-and putting it into the low-power state specified. If this was
-successful, it returns 0, and the device's power_state field is
-updated. 
-
-The driver must take care to know whether or not it is able to
-properly resume the device, including all step of reinitialization
-necessary. (This is the hardest part, and the one most protected by
-NDA'd documents). 
-
-The driver must also take care not to suspend a device that is
-currently in use. It is their responsibility to provide their own
-exclusion mechanisms.
-
-The runtime power transition happens with interrupts enabled. If a
-device cannot support being powered down with interrupts, it may
-return -EAGAIN (as it would during a system power management
-transition),  but it will _not_ be called again, and the transaction
-will fail.
-
-There is currently no way to know what states a device or driver
-supports a priori. This will change in the future. 
-
-pm_message_t meaning
-
-pm_message_t has two fields. event ("major"), and flags.  If driver
-does not know event code, it aborts the request, returning error. Some
-drivers may need to deal with special cases based on the actual type
-of suspend operation being done at the system level. This is why
-there are flags.
-
-Event codes are:
-
-ON -- no need to do anything except special cases like broken
-HW.
-
-# NOTIFICATION -- pretty much same as ON?
-
-FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
-scratch. That probably means stop accepting upstream requests, the
-actual policy of what to do with them being specific to a given
-driver. It's acceptable for a network driver to just drop packets
-while a block driver is expected to block the queue so no request is
-lost. (Use IDE as an example on how to do that). FREEZE requires no
-power state change, and it's expected for drivers to be able to
-quickly transition back to operating state.
-
-SUSPEND -- like FREEZE, but also put hardware into low-power state. If
-there's need to distinguish several levels of sleep, additional flag
-is probably best way to do that.
-
-Transitions are only from a resumed state to a suspended state, never
-between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
-FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
-
-All events are:
-
-[NOTE NOTE NOTE: If you are driver author, you should not care; you
-should only look at event, and ignore flags.]
-
-#Prepare for suspend -- userland is still running but we are going to
-#enter suspend state. This gives drivers chance to load firmware from
-#disk and store it in memory, or do other activities taht require
-#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
-#are forbiden once the suspend dance is started.. event = ON, flags =
-#PREPARE_TO_SUSPEND
-
-Apm standby -- prepare for APM event. Quiesce devices to make life
-easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
-
-Apm suspend -- same as APM_STANDBY, but it we should probably avoid
-spinning down disks. event = FREEZE, flags = APM_SUSPEND
-
-System halt, reboot -- quiesce devices to make life easier for BIOS. event
-= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
-
-System shutdown -- at least disks need to be spun down, or data may be
-lost. Quiesce devices, just to make life easier for BIOS. event =
-FREEZE, flags = SYSTEM_SHUTDOWN
-
-Kexec    -- turn off DMAs and put hardware into some state where new
-kernel can take over. event = FREEZE, flags = KEXEC
-
-Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
-may need to be enabled on some devices. This actually has at least 3
-subtypes, system can reboot, enter S4 and enter S5 at the end of
-swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
-SYSTEM_SHUTDOWN, SYSTEM_S4
-
-Suspend to ram  -- put devices into low power state. event = SUSPEND,
-flags = SUSPEND_TO_RAM
-
-Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
-devices into low power mode, but you must be able to reinitialize
-device from scratch in resume method. This has two flavors, its done
-once on suspending kernel, once on resuming kernel. event = FREEZE,
-flags = DURING_SUSPEND or DURING_RESUME
-
-Device detach requested from /sys -- deinitialize device; proably same as
-SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
-= FREEZE, flags = DEV_DETACH.
-
-#These are not really events sent:
-#
-#System fully on -- device is working normally; this is probably never
-#passed to suspend() method... event = ON, flags = 0
-#
-#Ready after resume -- userland is now running, again. Time to free any
-#memory you ate during prepare to suspend... event = ON, flags =
-#READY_AFTER_RESUME
-#
+
+Runtime Power Management
+========================
+Many devices are able to dynamically power down while the system is still
+running. This feature is useful for devices that are not being used, and
+can offer significant power savings on a running system.  These devices
+often support a range of runtime power states, which might use names such
+as "off", "sleep", "idle", "active", and so on.  Those states will in some
+cases (like PCI) be partially constrained by a bus the device uses, and will
+usually include hardware states that are also used in system sleep states.
+
+However, note that if a driver puts a device into a runtime low power state
+and the system then goes into a system-wide sleep state, it normally ought
+to resume into that runtime low power state rather than "full on".  Such
+distinctions would be part of the driver-internal state machine for that
+hardware; the whole point of runtime power management is to be sure that
+drivers are decoupled in that way from the state machine governing phases
+of the system-wide power/sleep state transitions.
+
+
+Power Saving Techniques
+-----------------------
+Normally runtime power management is handled by the drivers without specific
+userspace or kernel intervention, by device-aware use of techniques like:
+
+    Using information provided by other system layers
+	- stay deeply "off" except between open() and close()
+	- if transceiver/PHY indicates "nobody connected", stay "off"
+	- application protocols may include power commands or hints
+
+    Using fewer CPU cycles
+	- using DMA instead of PIO
+	- removing timers, or making them lower frequency
+	- shortening "hot" code paths
+	- eliminating cache misses
+	- (sometimes) offloading work to device firmware
+
+    Reducing other resource costs
+	- gating off unused clocks in software (or hardware)
+	- switching off unused power supplies
+	- eliminating (or delaying/merging) IRQs
+	- tuning DMA to use word and/or burst modes
+
+    Using device-specific low power states
+	- using lower voltages
+	- avoiding needless DMA transfers
+
+Read your hardware documentation carefully to see the opportunities that
+may be available.  If you can, measure the actual power usage and check
+it against the budget established for your project.
+
+
+Examples:  USB hosts, system timer, system CPU
+----------------------------------------------
+USB host controllers make interesting, if complex, examples.  In many cases
+these have no work to do:  no USB devices are connected, or all of them are
+in the USB "suspend" state.  Linux host controller drivers can then disable
+periodic DMA transfers that would otherwise be a constant power drain on the
+memory subsystem, and enter a suspend state.  In power-aware controllers,
+entering that suspend state may disable the clock used with USB signaling,
+saving a certain amount of power.
+
+The controller will be woken from that state (with an IRQ) by changes to the
+signal state on the data lines of a given port, for example by an existing
+peripheral requesting "remote wakeup" or by plugging a new peripheral.  The
+same wakeup mechanism usually works from "standby" sleep states, and on some
+systems also from "suspend to RAM" (or even "suspend to disk") states.
+(Except that ACPI may be involved instead of normal IRQs, on some hardware.)
+
+System devices like timers and CPUs may have special roles in the platform
+power management scheme.  For example, system timers using a "dynamic tick"
+approach don't just save CPU cycles (by eliminating needless timer IRQs),
+but they may also open the door to using lower power CPU "idle" states that
+cost more than a jiffie to enter and exit.  On x86 systems these are states
+like "C3"; note that periodic DMA transfers from a USB host controller will
+also prevent entry to a C3 state, much like a periodic timer IRQ.
+
+That kind of runtime mechanism interaction is common.  "System On Chip" (SOC)
+processors often have low power idle modes that can't be entered unless
+certain medium-speed clocks (often 12 or 48 MHz) are gated off.  When the
+drivers gate those clocks effectively, then the system idle task may be able
+to use the lower power idle modes and thereby increase battery life.
+
+If the CPU can have a "cpufreq" driver, there also may be opportunities
+to shift to lower voltage settings and reduce the power cost of executing
+a given number of instructions.  (Without voltage adjustment, it's rare
+for cpufreq to save much power; the cost-per-instruction must go down.)
+
+
+/sys/devices/.../power/state files
+==================================
+For now you can also test some of this functionality using sysfs.
+
+	DEPRECATED:  USE "power/state" ONLY FOR DRIVER TESTING, AND
+	AVOID USING dev->power.power_state IN DRIVERS.
+
+	THESE WILL BE REMOVED.  IF THE "power/state" FILE GETS REPLACED,
+	IT WILL BECOME SOMETHING COUPLED TO THE BUS OR DRIVER.
+
+In each device's directory, there is a 'power' directory, which contains
+at least a 'state' file.  The value of this field is effectively boolean,
+PM_EVENT_ON or PM_EVENT_SUSPEND.
+
+   *	Reading from this file displays a value corresponding to
+	the power.power_state.event field.  All nonzero values are
+	displayed as "2", corresponding to a low power state; zero
+	is displayed as "0", corresponding to normal operation.
+
+   *	Writing to this file initiates a transition using the
+   	specified event code number; only '0', '2', and '3' are
+	accepted (without a newline); '2' and '3' are both
+	mapped to PM_EVENT_SUSPEND.
+
+On writes, the PM core relies on that recorded event code and the device/bus
+capabilities to determine whether it uses a partial suspend() or resume()
+sequence to change things so that the recorded event corresponds to the
+numeric parameter.
+
+   -	If the bus requires the irqs-disabled suspend_late()/resume_early()
+	phases, writes fail because those operations are not supported here.
+
+   -	If the recorded value is the expected value, nothing is done.
+
+   -	If the recorded value is nonzero, the device is partially resumed,
+	using the bus.resume() and/or class.resume() methods.
+
+   -	If the target value is nonzero, the device is partially suspended,
+	using the class.suspend() and/or bus.suspend() methods and the
+	PM_EVENT_SUSPEND message.
+
+Drivers have no way to tell whether their suspend() and resume() calls
+have come through the sysfs power/state file or as part of entering a
+system sleep state, except that when accessed through sysfs the normal
+parent/child sequencing rules are ignored.  Drivers (such as bus, bridge,
+or hub drivers) which expose child devices may need to enforce those rules
+on their own.
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 19/47] PM: update docs for writing .../power/state
  2006-09-26  5:37                                   ` [PATCH 18/47] updated Documentation/power/devices.txt Greg KH
@ 2006-09-26  5:37                                     ` Greg KH
  2006-09-26  5:37                                       ` [PATCH 20/47] PM: add kconfig option for deprecated .../power/state files Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Updates to match current code:

 - Make writes to the /sys/devices/.../power/state files fail cleanly
   if the device requires the irqs-off call variants.

 - Fix comments describing the /sys/devices/.../power/state file writes
   to match the code; the last several releases have invalidated the
   previous text.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/sysfs.c |   29 +++++++++++++++++++----------
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 40d7242..e55b3c2 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -11,18 +11,23 @@ #include "power.h"
  *	state - Control current power state of device
  *
  *	show() returns the current power state of the device. '0' indicates
- *	the device is on. Other values (1-3) indicate the device is in a low
+ *	the device is on. Other values (2) indicate the device is in some low
  *	power state.
  *
- *	store() sets the current power state, which is an integer value
- *	between 0-3. If the device is on ('0'), and the value written is
- *	greater than 0, then the device is placed directly into the low-power
- *	state (via its driver's ->suspend() method).
- *	If the device is currently in a low-power state, and the value is 0,
- *	the device is powered back on (via the ->resume() method).
- *	If the device is in a low-power state, and a different low-power state
- *	is requested, the device is first resumed, then suspended into the new
- *	low-power state.
+ *	store() sets the current power state, which is an integer valued
+ *	0, 2, or 3.  Devices with bus.suspend_late(), or bus.resume_early()
+ *	methods fail this operation; those methods couldn't be called.
+ *	Otherwise,
+ *
+ *	- If the recorded dev->power.power_state.event matches the
+ *	  target value, nothing is done.
+ *	- If the recorded event code is nonzero, the device is reactivated
+ *	  by calling bus.resume() and/or class.resume().
+ *	- If the target value is nonzero, the device is suspended by
+ *	  calling class.suspend() and/or bus.suspend() with event code
+ *	  PM_EVENT_SUSPEND.
+ *
+ *	This mechanism is DEPRECATED and should only be used for testing.
  */
 
 static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
@@ -38,6 +43,10 @@ static ssize_t state_store(struct device
 	pm_message_t state;
 	int error = -EINVAL;
 
+	/* disallow incomplete suspend sequences */
+	if (dev->bus && (dev->bus->suspend_late || dev->bus->resume_early))
+		return error;
+
 	state.event = PM_EVENT_SUSPEND;
 	/* Older apps expected to write "3" here - confused with PCI D3 */
 	if ((n == 1) && !strcmp(buf, "3"))
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 20/47] PM: add kconfig option for deprecated .../power/state files
  2006-09-26  5:37                                     ` [PATCH 19/47] PM: update docs for writing .../power/state Greg KH
@ 2006-09-26  5:37                                       ` Greg KH
  2006-09-26  5:37                                         ` [PATCH 21/47] PM: schedule /sys/devices/.../power/state for removal Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Add a new PM_SYSFS_DEPRECATED config option to control whether or
not the /sys/devices/.../power/state files are provided.  This will
make it easier to get rid of that mechanism when the time comes,
and to verify that userspace tools work right without it.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/sysfs.c |    6 ++++++
 kernel/power/Kconfig       |   11 +++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index e55b3c2..2d47517 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -7,6 +7,8 @@ #include <linux/string.h>
 #include "power.h"
 
 
+#ifdef	CONFIG_PM_SYSFS_DEPRECATED
+
 /**
  *	state - Control current power state of device
  *
@@ -66,6 +68,8 @@ static ssize_t state_store(struct device
 static DEVICE_ATTR(state, 0644, state_show, state_store);
 
 
+#endif	/* CONFIG_PM_SYSFS_DEPRECATED */
+
 /*
  *	wakeup - Report/change current wakeup option for device
  *
@@ -139,7 +143,9 @@ static DEVICE_ATTR(wakeup, 0644, wake_sh
 
 
 static struct attribute * power_attrs[] = {
+#ifdef	CONFIG_PM_SYSFS_DEPRECATED
 	&dev_attr_state.attr,
+#endif
 	&dev_attr_wakeup.attr,
 	NULL,
 };
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 619ecab..1ed9720 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -53,6 +53,17 @@ config PM_TRACE
 	CAUTION: this option will cause your machine's real-time clock to be
 	set to an invalid time after a resume.
 
+config PM_SYSFS_DEPRECATED
+	bool "Driver model /sys/devices/.../power/state files (DEPRECATED)"
+	depends on PM && SYSFS
+	default n
+	help
+	  The driver model started out with a sysfs file intended to provide
+	  a userspace hook for device power management.  This feature has never
+	  worked very well, except for limited testing purposes, and so it will
+	  be removed.   It's not clear that a generic mechanism could really
+	  handle the wide variability of device power states; any replacements
+	  are likely to be bus or driver specific.
 
 config SOFTWARE_SUSPEND
 	bool "Software Suspend"
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 21/47] PM: schedule /sys/devices/.../power/state for removal
  2006-09-26  5:37                                       ` [PATCH 20/47] PM: add kconfig option for deprecated .../power/state files Greg KH
@ 2006-09-26  5:37                                         ` Greg KH
  2006-09-26  5:37                                           ` [PATCH 22/47] PM: no suspend_prepare() phase Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Pavel Machek, David Brownell, Greg Kroah-Hartman

From: Pavel Machek <pavel@suse.cz>

This lists the /sys/devices/.../power/state file, and its internal support,
as due for removal next year.

Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/feature-removal-schedule.txt |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a89a1b7..611acc3 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,21 @@ be removed from this file.
 
 ---------------------------
 
+What:	/sys/devices/.../power/state
+	dev->power.power_state
+	dpm_runtime_{suspend,resume)()
+When:	July 2007
+Why:	Broken design for runtime control over driver power states, confusing
+	driver-internal runtime power management with:  mechanisms to support
+	system-wide sleep state transitions; event codes that distinguish
+	different phases of swsusp "sleep" transitions; and userspace policy
+	inputs.  This framework was never widely used, and most attempts to
+	use it were broken.  Drivers should instead be exposing domain-specific
+	interfaces either to kernel or to userspace.
+Who:	Pavel Machek <pavel@suse.cz>
+
+---------------------------
+
 What:	RAW driver (CONFIG_RAW_DRIVER)
 When:	December 2005
 Why:	declared obsolete since kernel 2.6.3
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 22/47] PM: no suspend_prepare() phase
  2006-09-26  5:37                                         ` [PATCH 21/47] PM: schedule /sys/devices/.../power/state for removal Greg KH
@ 2006-09-26  5:37                                           ` Greg KH
  2006-09-26  5:37                                             ` [PATCH 23/47] PM: add /sys/power documentation to Documentation/ABI Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Remove the new suspend_prepare() phase.  It doesn't seem very usable,
has never been tested, doesn't address fault cleanup, and would need
a sibling resume_complete(); plus there are no real use cases.  It
could be restored later if those issues get resolved.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/suspend.c |   27 ---------------------------
 drivers/pci/pci-driver.c     |   14 --------------
 include/linux/device.h       |    1 -
 include/linux/pci.h          |    1 -
 kernel/power/main.c          |    4 ----
 5 files changed, 0 insertions(+), 47 deletions(-)

diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index e86db83..6453c25 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -118,33 +118,6 @@ static int suspend_device_late(struct de
 }
 
 /**
- *	device_prepare_suspend - save state and prepare to suspend
- *
- *	NOTE! Devices cannot detach at this point - not only do we
- *	hold the device list semaphores over the whole prepare, but
- *	the whole point is to do non-invasive preparatory work, not
- *	the actual suspend.
- */
-int device_prepare_suspend(pm_message_t state)
-{
-	int error = 0;
-	struct device * dev;
-
-	down(&dpm_sem);
-	down(&dpm_list_sem);
-	list_for_each_entry_reverse(dev, &dpm_active, power.entry) {
-		if (!dev->bus || !dev->bus->suspend_prepare)
-			continue;
-		error = dev->bus->suspend_prepare(dev, state);
-		if (error)
-			break;
-	}
-	up(&dpm_list_sem);
-	up(&dpm_sem);
-	return error;
-}
-
-/**
  *	device_suspend - Save state and stop all devices in system.
  *	@state:		Power state to put each device in.
  *
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 9e7d6ce..8948ac9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -264,19 +264,6 @@ static int pci_device_remove(struct devi
 	return 0;
 }
 
-static int pci_device_suspend_prepare(struct device * dev, pm_message_t state)
-{
-	struct pci_dev * pci_dev = to_pci_dev(dev);
-	struct pci_driver * drv = pci_dev->driver;
-	int i = 0;
-
-	if (drv && drv->suspend_prepare) {
-		i = drv->suspend_prepare(pci_dev, state);
-		suspend_report_result(drv->suspend_prepare, i);
-	}
-	return i;
-}
-
 static int pci_device_suspend(struct device * dev, pm_message_t state)
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
@@ -544,7 +531,6 @@ struct bus_type pci_bus_type = {
 	.uevent		= pci_uevent,
 	.probe		= pci_device_probe,
 	.remove		= pci_device_remove,
-	.suspend_prepare= pci_device_suspend_prepare,
 	.suspend	= pci_device_suspend,
 	.suspend_late	= pci_device_suspend_late,
 	.resume_early	= pci_device_resume_early,
diff --git a/include/linux/device.h b/include/linux/device.h
index b40be6f..b364646 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -52,7 +52,6 @@ struct bus_type {
 	int		(*remove)(struct device * dev);
 	void		(*shutdown)(struct device * dev);
 
-	int (*suspend_prepare)(struct device * dev, pm_message_t state);
 	int (*suspend)(struct device * dev, pm_message_t state);
 	int (*suspend_late)(struct device * dev, pm_message_t state);
 	int (*resume_early)(struct device * dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4b2e629..9514bbf 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -345,7 +345,6 @@ struct pci_driver {
 	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
-	int  (*suspend_prepare) (struct pci_dev *dev, pm_message_t state);
 	int  (*suspend) (struct pci_dev *dev, pm_message_t state);	/* Device suspended */
 	int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
 	int  (*resume_early) (struct pci_dev *dev);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 0c3ed6a..6d295c7 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -57,10 +57,6 @@ static int suspend_prepare(suspend_state
 	if (!pm_ops || !pm_ops->enter)
 		return -EPERM;
 
-	error = device_prepare_suspend(PMSG_SUSPEND);
-	if (error)
-		return error;
-
 	pm_prepare_console();
 
 	disable_nonboot_cpus();
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 23/47] PM: add /sys/power documentation to Documentation/ABI
  2006-09-26  5:37                                           ` [PATCH 22/47] PM: no suspend_prepare() phase Greg KH
@ 2006-09-26  5:37                                             ` Greg KH
  2006-09-26  5:37                                               ` [PATCH 24/47] PM: device_suspend/resume may sleep Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Greg Kroah-Hartman

From: Rafael J. Wysocki <rjw@sisk.pl>

The file sysfs-power that documents the interface in the /sys/power/ directory
is added to Documentation/ABI/testing.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 Documentation/ABI/testing/sysfs-power |   88 +++++++++++++++++++++++++++++++++
 1 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power
new file mode 100644
index 0000000..d882f80
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-power
@@ -0,0 +1,88 @@
+What:		/sys/power/
+Date:		August 2006
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power directory will contain files that will
+		provide a unified interface to the power management
+		subsystem.
+
+What:		/sys/power/state
+Date:		August 2006
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/state file controls the system power state.
+		Reading from this file returns what states are supported,
+		which is hard-coded to 'standby' (Power-On Suspend), 'mem'
+		(Suspend-to-RAM), and 'disk' (Suspend-to-Disk).
+
+		Writing to this file one of these strings causes the system to
+		transition into that state. Please see the file
+		Documentation/power/states.txt for a description of each of
+		these states.
+
+What:		/sys/power/disk
+Date:		August 2006
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/disk file controls the operating mode of the
+		suspend-to-disk mechanism.  Reading from this file returns
+		the name of the method by which the system will be put to
+		sleep on the next suspend.  There are four methods supported:
+		'firmware' - means that the memory image will be saved to disk
+		by some firmware, in which case we also assume that the
+		firmware will handle the system suspend.
+		'platform' - the memory image will be saved by the kernel and
+		the system will be put to sleep by the platform driver (e.g.
+		ACPI or other PM registers).
+		'shutdown' - the memory image will be saved by the kernel and
+		the system will be powered off.
+		'reboot' - the memory image will be saved by the kernel and
+		the system will be rebooted.
+
+		The suspend-to-disk method may be chosen by writing to this
+		file one of the accepted strings:
+
+		'firmware'
+		'platform'
+		'shutdown'
+		'reboot'
+
+		It will only change to 'firmware' or 'platform' if the system
+		supports that.
+
+What:		/sys/power/image_size
+Date:		August 2006
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/image_size file controls the size of the image
+		created by the suspend-to-disk mechanism.  It can be written a
+		string representing a non-negative integer that will be used
+		as an upper limit of the image size, in bytes.  The kernel's
+		suspend-to-disk code will do its best to ensure the image size
+		will not exceed this number.  However, if it turns out to be
+		impossible, the kernel will try to suspend anyway using the
+		smallest image possible.  In particular, if "0" is written to
+		this file, the suspend image will be as small as possible.
+
+		Reading from this file will display the current image size
+		limit, which is set to 500 MB by default.
+
+What:		/sys/power/pm_trace
+Date:		August 2006
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/pm_trace file controls the code which saves the
+		last PM event point in the RTC across reboots, so that you can
+		debug a machine that just hangs during suspend (or more
+		commonly, during resume).  Namely, the RTC is only used to save
+		the last PM event point if this file contains '1'.  Initially
+		it contains '0' which may be changed to '1' by writing a
+		string representing a nonzero integer into it.
+
+		To use this debugging feature you should attempt to suspend
+		the machine, then reboot it and run
+
+		dmesg -s 1000000 | grep 'hash matches'
+
+		CAUTION: Using it will cause your machine's real-time (CMOS)
+		clock to be set to a random invalid time after a resume.
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 24/47] PM: device_suspend/resume may sleep
  2006-09-26  5:37                                             ` [PATCH 23/47] PM: add /sys/power documentation to Documentation/ABI Greg KH
@ 2006-09-26  5:37                                               ` Greg KH
  2006-09-26  5:37                                                 ` [PATCH 25/47] PM: platform_bus and late_suspend/early_resume Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Pavel Machek, Andrew Morton, Greg Kroah-Hartman

From: Pavel Machek <pavel@suse.cz>

This adds warning when someone tries them from atomic context.

Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/resume.c  |    1 +
 drivers/base/power/suspend.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 48e3d49..7cb62d6 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -96,6 +96,7 @@ void dpm_resume(void)
 
 void device_resume(void)
 {
+	might_sleep();
 	down(&dpm_sem);
 	dpm_resume();
 	up(&dpm_sem);
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 6453c25..ece136b 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -140,6 +140,7 @@ int device_suspend(pm_message_t state)
 {
 	int error = 0;
 
+	might_sleep();
 	down(&dpm_sem);
 	down(&dpm_list_sem);
 	while (!list_empty(&dpm_active) && error == 0) {
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 25/47] PM: platform_bus and late_suspend/early_resume
  2006-09-26  5:37                                               ` [PATCH 24/47] PM: device_suspend/resume may sleep Greg KH
@ 2006-09-26  5:37                                                 ` Greg KH
  2006-09-26  5:37                                                   ` [PATCH 26/47] Driver core: add groups support to struct device Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Brownell, David Brownell, Greg Kroah-Hartman

From: David Brownell <david-b@pacbell.net>

Teach platform_bus about the new suspend_late/resume_early PM calls,
issued with IRQs off.  Do we really need sysdev and friends any more,
or can janitors start switching its users over to platform_device so
we can do a minor code-ectomy?

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/platform.c         |   30 ++++++++++++++++++++++++++++--
 include/linux/platform_device.h |    2 ++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 2b8755d..940ce41 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -505,12 +505,36 @@ static int platform_match(struct device 
 	return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
 }
 
-static int platform_suspend(struct device * dev, pm_message_t state)
+static int platform_suspend(struct device *dev, pm_message_t mesg)
 {
 	int ret = 0;
 
 	if (dev->driver && dev->driver->suspend)
-		ret = dev->driver->suspend(dev, state);
+		ret = dev->driver->suspend(dev, mesg);
+
+	return ret;
+}
+
+static int platform_suspend_late(struct device *dev, pm_message_t mesg)
+{
+	struct platform_driver *drv = to_platform_driver(dev->driver);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	int ret = 0;
+
+	if (dev->driver && drv->suspend_late)
+		ret = drv->suspend_late(pdev, mesg);
+
+	return ret;
+}
+
+static int platform_resume_early(struct device *dev)
+{
+	struct platform_driver *drv = to_platform_driver(dev->driver);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	int ret = 0;
+
+	if (dev->driver && drv->resume_early)
+		ret = drv->resume_early(pdev);
 
 	return ret;
 }
@@ -531,6 +555,8 @@ struct bus_type platform_bus_type = {
 	.match		= platform_match,
 	.uevent		= platform_uevent,
 	.suspend	= platform_suspend,
+	.suspend_late	= platform_suspend_late,
+	.resume_early	= platform_resume_early,
 	.resume		= platform_resume,
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 782090c..29cd6de 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -49,6 +49,8 @@ struct platform_driver {
 	int (*remove)(struct platform_device *);
 	void (*shutdown)(struct platform_device *);
 	int (*suspend)(struct platform_device *, pm_message_t state);
+	int (*suspend_late)(struct platform_device *, pm_message_t state);
+	int (*resume_early)(struct platform_device *);
 	int (*resume)(struct platform_device *);
 	struct device_driver driver;
 };
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26  5:37                                                 ` [PATCH 25/47] PM: platform_bus and late_suspend/early_resume Greg KH
@ 2006-09-26  5:37                                                   ` Greg KH
  2006-09-26  5:37                                                     ` [PATCH 27/47] Driver core: allow devices in classes to have no parent Greg KH
  2006-09-26 13:20                                                     ` [PATCH 26/47] Driver core: add groups support to struct device Dmitry Torokhov
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This is needed for the network class devices in order to be able to
convert over to use struct device.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c    |   34 ++++++++++++++++++++++++++++++++++
 include/linux/device.h |    1 +
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5d4b7e0..641c0c4 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -197,6 +197,35 @@ static ssize_t store_uevent(struct devic
 	return count;
 }
 
+static int device_add_groups(struct device *dev)
+{
+	int i;
+	int error = 0;
+
+	if (dev->groups) {
+		for (i = 0; dev->groups[i]; i++) {
+			error = sysfs_create_group(&dev->kobj, dev->groups[i]);
+			if (error) {
+				while (--i >= 0)
+					sysfs_remove_group(&dev->kobj, dev->groups[i]);
+				goto out;
+			}
+		}
+	}
+out:
+	return error;
+}
+
+static void device_remove_groups(struct device *dev)
+{
+	int i;
+	if (dev->groups) {
+		for (i = 0; dev->groups[i]; i++) {
+			sysfs_remove_group(&dev->kobj, dev->groups[i]);
+		}
+	}
+}
+
 static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
 			char *buf)
 {
@@ -350,6 +379,8 @@ int device_add(struct device *dev)
 		sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
 	}
 
+	if ((error = device_add_groups(dev)))
+		goto GroupError;
 	if ((error = device_pm_add(dev)))
 		goto PMError;
 	if ((error = bus_add_device(dev)))
@@ -376,6 +407,8 @@ int device_add(struct device *dev)
  BusError:
 	device_pm_remove(dev);
  PMError:
+	device_remove_groups(dev);
+ GroupError:
 	if (dev->devt_attr) {
 		device_remove_file(dev, dev->devt_attr);
 		kfree(dev->devt_attr);
@@ -470,6 +503,7 @@ void device_del(struct device * dev)
 		up(&dev->class->sem);
 	}
 	device_remove_file(dev, &dev->uevent_attr);
+	device_remove_groups(dev);
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
diff --git a/include/linux/device.h b/include/linux/device.h
index b364646..994d3eb 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -344,6 +344,7 @@ struct device {
 	struct list_head	node;
 	struct class		*class;		/* optional*/
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
+	struct attribute_group	**groups;	/* optional groups */
 
 	void	(*release)(struct device * dev);
 };
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 27/47] Driver core: allow devices in classes to have no parent
  2006-09-26  5:37                                                   ` [PATCH 26/47] Driver core: add groups support to struct device Greg KH
@ 2006-09-26  5:37                                                     ` Greg KH
  2006-09-26  5:37                                                       ` [PATCH 28/47] Driver core: add ability for classes to handle devices properly Greg KH
  2006-09-26 13:20                                                     ` [PATCH 26/47] Driver core: add groups support to struct device Dmitry Torokhov
  1 sibling, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This fixes an oops when a device is attached to a class, yet has no
"parent" device.  An example of this would be the "lo" device in the
network core.

We should create a "virtual" subdirectory under /sys/devices/ for these,
but no one seems to agree on a proper name for it yet...

Oh, and update my copyright on the driver core.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 641c0c4..5c91d0d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3,6 +3,8 @@
  *
  * Copyright (c) 2002-3 Patrick Mochel
  * Copyright (c) 2002-3 Open Source Development Labs
+ * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2006 Novell, Inc.
  *
  * This file is released under the GPLv2
  *
@@ -373,10 +375,11 @@ int device_add(struct device *dev)
 				  "subsystem");
 		sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
 				  dev->bus_id);
-
-		sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
-		class_name = make_class_name(dev->class->name, &dev->kobj);
-		sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
+		if (parent) {
+			sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
+			class_name = make_class_name(dev->class->name, &dev->kobj);
+			sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
+		}
 	}
 
 	if ((error = device_add_groups(dev)))
@@ -495,8 +498,10 @@ void device_del(struct device * dev)
 		sysfs_remove_link(&dev->kobj, "subsystem");
 		sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
 		class_name = make_class_name(dev->class->name, &dev->kobj);
-		sysfs_remove_link(&dev->kobj, "device");
-		sysfs_remove_link(&dev->parent->kobj, class_name);
+		if (parent) {
+			sysfs_remove_link(&dev->kobj, "device");
+			sysfs_remove_link(&dev->parent->kobj, class_name);
+		}
 		kfree(class_name);
 		down(&dev->class->sem);
 		list_del_init(&dev->node);
@@ -625,10 +630,6 @@ struct device *device_create(struct clas
 
 	if (class == NULL || IS_ERR(class))
 		goto error;
-	if (parent == NULL) {
-		printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__);
-		goto error;
-	}
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 28/47] Driver core: add ability for classes to handle devices properly
  2006-09-26  5:37                                                     ` [PATCH 27/47] Driver core: allow devices in classes to have no parent Greg KH
@ 2006-09-26  5:37                                                       ` Greg KH
  2006-09-26  5:37                                                         ` [PATCH 29/47] Driver core: add device_rename function Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This adds two new callbacks to the class structure:
	int	(*dev_uevent)(struct device *dev, char **envp, int num_envp,
			char *buffer, int buffer_size);
	void	(*dev_release)(struct device *dev);

And one pointer:
	struct device_attribute		* dev_attrs;

which all corrispond with the same thing as the "normal" class devices
do, yet this is for when a struct device is bound to a class.

Someday soon, struct class_device will go away, and then the other
fields in this structure can be removed too.  But this is necessary in
order to get the transition to work properly.

Tested out on a network core patch that converted it to use struct
device instead of struct class_device.


Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c    |   53 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/device.h |    4 ++++
 2 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5c91d0d..f1228f2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -94,6 +94,8 @@ static void device_release(struct kobjec
 
 	if (dev->release)
 		dev->release(dev);
+	else if (dev->class && dev->class->dev_release)
+		dev->class->dev_release(dev);
 	else {
 		printk(KERN_ERR "Device '%s' does not have a release() function, "
 			"it is broken and must be fixed.\n",
@@ -183,6 +185,15 @@ static int dev_uevent(struct kset *kset,
 		}
 	}
 
+	if (dev->class && dev->class->dev_uevent) {
+		/* have the class specific function add its stuff */
+		retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
+			if (retval) {
+				pr_debug("%s - dev_uevent() returned %d\n",
+					 __FUNCTION__, retval);
+		}
+	}
+
 	return retval;
 }
 
@@ -228,6 +239,43 @@ static void device_remove_groups(struct 
 	}
 }
 
+static int device_add_attrs(struct device *dev)
+{
+	struct class *class = dev->class;
+	int error = 0;
+	int i;
+
+	if (!class)
+		return 0;
+
+	if (class->dev_attrs) {
+		for (i = 0; attr_name(class->dev_attrs[i]); i++) {
+			error = device_create_file(dev, &class->dev_attrs[i]);
+			if (error)
+				break;
+		}
+	}
+	if (error)
+		while (--i >= 0)
+			device_remove_file(dev, &class->dev_attrs[i]);
+	return error;
+}
+
+static void device_remove_attrs(struct device *dev)
+{
+	struct class *class = dev->class;
+	int i;
+
+	if (!class)
+		return;
+
+	if (class->dev_attrs) {
+		for (i = 0; attr_name(class->dev_attrs[i]); i++)
+			device_remove_file(dev, &class->dev_attrs[i]);
+	}
+}
+
+
 static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
 			char *buf)
 {
@@ -382,6 +430,8 @@ int device_add(struct device *dev)
 		}
 	}
 
+	if ((error = device_add_attrs(dev)))
+		goto AttrsError;
 	if ((error = device_add_groups(dev)))
 		goto GroupError;
 	if ((error = device_pm_add(dev)))
@@ -412,6 +462,8 @@ int device_add(struct device *dev)
  PMError:
 	device_remove_groups(dev);
  GroupError:
+ 	device_remove_attrs(dev);
+ AttrsError:
 	if (dev->devt_attr) {
 		device_remove_file(dev, dev->devt_attr);
 		kfree(dev->devt_attr);
@@ -509,6 +561,7 @@ void device_del(struct device * dev)
 	}
 	device_remove_file(dev, &dev->uevent_attr);
 	device_remove_groups(dev);
+	device_remove_attrs(dev);
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
diff --git a/include/linux/device.h b/include/linux/device.h
index 994d3eb..3122bd2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -151,12 +151,16 @@ struct class {
 
 	struct class_attribute		* class_attrs;
 	struct class_device_attribute	* class_dev_attrs;
+	struct device_attribute		* dev_attrs;
 
 	int	(*uevent)(struct class_device *dev, char **envp,
 			   int num_envp, char *buffer, int buffer_size);
+	int	(*dev_uevent)(struct device *dev, char **envp, int num_envp,
+				char *buffer, int buffer_size);
 
 	void	(*release)(struct class_device *dev);
 	void	(*class_release)(struct class *class);
+	void	(*dev_release)(struct device *dev);
 
 	int	(*suspend)(struct device *, pm_message_t state);
 	int	(*resume)(struct device *);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 29/47] Driver core: add device_rename function
  2006-09-26  5:37                                                       ` [PATCH 28/47] Driver core: add ability for classes to handle devices properly Greg KH
@ 2006-09-26  5:37                                                         ` Greg KH
  2006-09-26  5:37                                                           ` [PATCH 30/47] Driver core: create devices/virtual/ tree Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

The network layer needs this to convert to using struct device instead
of a struct class_device.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c    |   55 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/device.h |    1 +
 2 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index f1228f2..0db4756 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -736,3 +736,58 @@ void device_destroy(struct class *class,
 		device_unregister(dev);
 }
 EXPORT_SYMBOL_GPL(device_destroy);
+
+/**
+ * device_rename - renames a device
+ * @dev: the pointer to the struct device to be renamed
+ * @new_name: the new name of the device
+ */
+int device_rename(struct device *dev, char *new_name)
+{
+	char *old_class_name = NULL;
+	char *new_class_name = NULL;
+	char *old_symlink_name = NULL;
+	int error;
+
+	dev = get_device(dev);
+	if (!dev)
+		return -EINVAL;
+
+	pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name);
+
+	if ((dev->class) && (dev->parent))
+		old_class_name = make_class_name(dev->class->name, &dev->kobj);
+
+	if (dev->class) {
+		old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+		if (!old_symlink_name)
+			return -ENOMEM;
+		strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
+	}
+
+	strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
+
+	error = kobject_rename(&dev->kobj, new_name);
+
+	if (old_class_name) {
+		new_class_name = make_class_name(dev->class->name, &dev->kobj);
+		if (new_class_name) {
+			sysfs_create_link(&dev->parent->kobj, &dev->kobj,
+					  new_class_name);
+			sysfs_remove_link(&dev->parent->kobj, old_class_name);
+		}
+	}
+	if (dev->class) {
+		sysfs_remove_link(&dev->class->subsys.kset.kobj,
+				  old_symlink_name);
+		sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
+				  dev->bus_id);
+	}
+	put_device(dev);
+
+	kfree(old_class_name);
+	kfree(new_class_name);
+	kfree(old_symlink_name);
+
+	return error;
+}
diff --git a/include/linux/device.h b/include/linux/device.h
index 3122bd2..3400e09 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -380,6 +380,7 @@ extern int device_add(struct device * de
 extern void device_del(struct device * dev);
 extern int device_for_each_child(struct device *, void *,
 		     int (*fn)(struct device *, void *));
+extern int device_rename(struct device *dev, char *new_name);
 
 /*
  * Manual binding of a device to driver. See drivers/base/bus.c
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26  5:37                                                         ` [PATCH 29/47] Driver core: add device_rename function Greg KH
@ 2006-09-26  5:37                                                           ` Greg KH
  2006-09-26  5:37                                                             ` [PATCH 31/47] Class: add support for class interfaces for devices Greg KH
  2006-09-26 13:24                                                             ` [PATCH 30/47] Driver core: create devices/virtual/ tree Dmitry Torokhov
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This change creates a devices/virtual/CLASS_NAME tree for struct devices
that belong to a class, yet do not have a "real" struct device for a
parent.  It automatically creates the directories on the fly as needed.


Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/class.c   |   17 +++++++++++++++++
 drivers/base/core.c    |    7 +++++++
 include/linux/device.h |    5 ++++-
 3 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index e078bc2..cbdf47c 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -19,6 +19,8 @@ #include <linux/err.h>
 #include <linux/slab.h>
 #include "base.h"
 
+extern struct subsystem devices_subsys;
+
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
 #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj)
 
@@ -878,7 +880,22 @@ void class_interface_unregister(struct c
 	class_put(parent);
 }
 
+int virtual_device_parent(struct device *dev)
+{
+	if (!dev->class)
+		return -ENODEV;
+
+	if (!dev->class->virtual_dir) {
+		static struct kobject *virtual_dir = NULL;
 
+		if (!virtual_dir)
+			virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual");
+		dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
+	}
+
+	dev->kobj.parent = dev->class->virtual_dir;
+	return 0;
+}
 
 int __init classes_init(void)
 {
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0db4756..e21a65f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -378,6 +378,13 @@ int device_add(struct device *dev)
 	if (!dev || !strlen(dev->bus_id))
 		goto Error;
 
+	/* if this is a class device, and has no parent, create one */
+	if ((dev->class) && (dev->parent == NULL)) {
+		error = virtual_device_parent(dev);
+		if (error)
+			goto Error;
+	}
+
 	parent = get_device(dev->parent);
 
 	pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
diff --git a/include/linux/device.h b/include/linux/device.h
index 3400e09..bbb0d6b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -149,6 +149,8 @@ struct class {
 	struct list_head	interfaces;
 	struct semaphore	sem;	/* locks both the children and interfaces lists */
 
+	struct kobject		*virtual_dir;
+
 	struct class_attribute		* class_attrs;
 	struct class_device_attribute	* class_dev_attrs;
 	struct device_attribute		* dev_attrs;
@@ -291,7 +293,6 @@ extern struct class_device *class_device
 					__attribute__((format(printf,5,6)));
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
-
 /* interface for exporting device attributes */
 struct device_attribute {
 	struct attribute	attr;
@@ -400,6 +401,8 @@ extern struct device *device_create(stru
 				    __attribute__((format(printf,4,5)));
 extern void device_destroy(struct class *cls, dev_t devt);
 
+extern int virtual_device_parent(struct device *dev);
+
 /*
  * Platform "fixup" functions - allow the platform to have their say
  * about devices and actions that the general device layer doesn't
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 31/47] Class: add support for class interfaces for devices
  2006-09-26  5:37                                                           ` [PATCH 30/47] Driver core: create devices/virtual/ tree Greg KH
@ 2006-09-26  5:37                                                             ` Greg KH
  2006-09-26  5:37                                                               ` [PATCH 32/47] Driver core: add ability for devices to create and remove bin files Greg KH
  2006-09-26 13:24                                                             ` [PATCH 30/47] Driver core: create devices/virtual/ tree Dmitry Torokhov
  1 sibling, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

When moving class_device usage over to device, we need to handle
class_interfaces properly with devices.  This patch adds that support.


Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/class.c   |   10 ++++++++++
 drivers/base/core.c    |   14 +++++++++++++-
 include/linux/device.h |    2 ++
 3 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index cbdf47c..b06b0e2 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -842,6 +842,7 @@ int class_interface_register(struct clas
 {
 	struct class *parent;
 	struct class_device *class_dev;
+	struct device *dev;
 
 	if (!class_intf || !class_intf->class)
 		return -ENODEV;
@@ -856,6 +857,10 @@ int class_interface_register(struct clas
 		list_for_each_entry(class_dev, &parent->children, node)
 			class_intf->add(class_dev, class_intf);
 	}
+	if (class_intf->add_dev) {
+		list_for_each_entry(dev, &parent->devices, node)
+			class_intf->add_dev(dev, class_intf);
+	}
 	up(&parent->sem);
 
 	return 0;
@@ -865,6 +870,7 @@ void class_interface_unregister(struct c
 {
 	struct class * parent = class_intf->class;
 	struct class_device *class_dev;
+	struct device *dev;
 
 	if (!parent)
 		return;
@@ -875,6 +881,10 @@ void class_interface_unregister(struct c
 		list_for_each_entry(class_dev, &parent->children, node)
 			class_intf->remove(class_dev, class_intf);
 	}
+	if (class_intf->remove_dev) {
+		list_for_each_entry(dev, &parent->devices, node)
+			class_intf->remove_dev(dev, class_intf);
+	}
 	up(&parent->sem);
 
 	class_put(parent);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e21a65f..1d3d358 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -372,6 +372,7 @@ int device_add(struct device *dev)
 {
 	struct device *parent = NULL;
 	char *class_name = NULL;
+	struct class_interface *class_intf;
 	int error = -EINVAL;
 
 	dev = get_device(dev);
@@ -451,9 +452,14 @@ int device_add(struct device *dev)
 		klist_add_tail(&dev->knode_parent, &parent->klist_children);
 
 	if (dev->class) {
-		/* tie the class to the device */
 		down(&dev->class->sem);
+		/* tie the class to the device */
 		list_add_tail(&dev->node, &dev->class->devices);
+
+		/* notify any interfaces that the device is here */
+		list_for_each_entry(class_intf, &dev->class->interfaces, node)
+			if (class_intf->add_dev)
+				class_intf->add_dev(dev, class_intf);
 		up(&dev->class->sem);
 	}
 
@@ -548,6 +554,7 @@ void device_del(struct device * dev)
 {
 	struct device * parent = dev->parent;
 	char *class_name = NULL;
+	struct class_interface *class_intf;
 
 	if (parent)
 		klist_del(&dev->knode_parent);
@@ -563,6 +570,11 @@ void device_del(struct device * dev)
 		}
 		kfree(class_name);
 		down(&dev->class->sem);
+		/* notify any interfaces that the device is now gone */
+		list_for_each_entry(class_intf, &dev->class->interfaces, node)
+			if (class_intf->remove_dev)
+				class_intf->remove_dev(dev, class_intf);
+		/* remove the device from the class list */
 		list_del_init(&dev->node);
 		up(&dev->class->sem);
 	}
diff --git a/include/linux/device.h b/include/linux/device.h
index bbb0d6b..e0fae0e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -278,6 +278,8 @@ struct class_interface {
 
 	int (*add)	(struct class_device *, struct class_interface *);
 	void (*remove)	(struct class_device *, struct class_interface *);
+	int (*add_dev)		(struct device *, struct class_interface *);
+	void (*remove_dev)	(struct device *, struct class_interface *);
 };
 
 extern int class_interface_register(struct class_interface *);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 32/47] Driver core: add ability for devices to create and remove bin files
  2006-09-26  5:37                                                             ` [PATCH 31/47] Class: add support for class interfaces for devices Greg KH
@ 2006-09-26  5:37                                                               ` Greg KH
  2006-09-26  5:37                                                                 ` [PATCH 33/47] kobject: must_check fixes Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

Makes it easier for devices to create and remove binary attribute files
so they don't have to call directly into sysfs.  This is needed to help
with the conversion from struct class_device to struct device.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c    |   26 ++++++++++++++++++++++++++
 include/linux/device.h |    4 ++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 1d3d358..bc9f35c 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -319,6 +319,32 @@ void device_remove_file(struct device * 
 	}
 }
 
+/**
+ * device_create_bin_file - create sysfs binary attribute file for device.
+ * @dev: device.
+ * @attr: device binary attribute descriptor.
+ */
+int device_create_bin_file(struct device *dev, struct bin_attribute *attr)
+{
+	int error = -EINVAL;
+	if (dev)
+		error = sysfs_create_bin_file(&dev->kobj, attr);
+	return error;
+}
+EXPORT_SYMBOL_GPL(device_create_bin_file);
+
+/**
+ * device_remove_bin_file - remove sysfs binary attribute file
+ * @dev: device.
+ * @attr: device binary attribute descriptor.
+ */
+void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
+{
+	if (dev)
+		sysfs_remove_bin_file(&dev->kobj, attr);
+}
+EXPORT_SYMBOL_GPL(device_remove_bin_file);
+
 static void klist_children_get(struct klist_node *n)
 {
 	struct device *dev = container_of(n, struct device, knode_parent);
diff --git a/include/linux/device.h b/include/linux/device.h
index e0fae0e..7d447d7 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -309,6 +309,10 @@ struct device_attribute dev_attr_##_name
 
 extern int device_create_file(struct device *device, struct device_attribute * entry);
 extern void device_remove_file(struct device * dev, struct device_attribute * attr);
+extern int __must_check device_create_bin_file(struct device *dev,
+					       struct bin_attribute *attr);
+extern void device_remove_bin_file(struct device *dev,
+				   struct bin_attribute *attr);
 struct device {
 	struct klist		klist_children;
 	struct klist_node	knode_parent;		/* node in sibling list */
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 33/47] kobject: must_check fixes
  2006-09-26  5:37                                                               ` [PATCH 32/47] Driver core: add ability for devices to create and remove bin files Greg KH
@ 2006-09-26  5:37                                                                 ` Greg KH
  2006-09-26  5:37                                                                   ` [PATCH 34/47] sysfs_remove_bin_file: no return value, dump_stack on error Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, Greg Kroah-Hartman

From: Randy Dunlap <rdunlap@xenotime.net>

Check all __must_check warnings in lib/kobject.c

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 lib/kobject.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/lib/kobject.c b/lib/kobject.c
index 8e7c719..1699eb9 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -407,6 +407,7 @@ static struct kobj_type dir_ktype = {
 struct kobject *kobject_add_dir(struct kobject *parent, const char *name)
 {
 	struct kobject *k;
+	int ret;
 
 	if (!parent)
 		return NULL;
@@ -418,7 +419,13 @@ struct kobject *kobject_add_dir(struct k
 	k->parent = parent;
 	k->ktype = &dir_ktype;
 	kobject_set_name(k, name);
-	kobject_register(k);
+	ret = kobject_register(k);
+	if (ret < 0) {
+		printk(KERN_WARNING "kobject_add_dir: "
+			"kobject_register error: %d\n", ret);
+		kobject_del(k);
+		return NULL;
+	}
 
 	return k;
 }
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 34/47] sysfs_remove_bin_file: no return value, dump_stack on error
  2006-09-26  5:37                                                                 ` [PATCH 33/47] kobject: must_check fixes Greg KH
@ 2006-09-26  5:37                                                                   ` Greg KH
  2006-09-26  5:37                                                                     ` [PATCH 35/47] Driver core: fix comments in drivers/base/power/resume.c Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Randy Dunlap, Greg Kroah-Hartman

From: Randy.Dunlap <rdunlap@xenotime.net>

Make sysfs_remove_bin_file() void.  If it detects an error,
printk the file name and call dump_stack().

sysfs_hash_and_remove() now returns an error code indicating
its success or failure so that sysfs_remove_bin_file() can
know success/failure.

Convert the only driver that checked the return value of
sysfs_remove_bin_file().

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/pci/hotplug/acpiphp_ibm.c |    4 +---
 fs/sysfs/bin.c                    |   13 ++++++++-----
 fs/sysfs/inode.c                  |   11 ++++++++---
 fs/sysfs/sysfs.h                  |    2 +-
 include/linux/sysfs.h             |    2 +-
 5 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 317457d..d0a07d9 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -487,9 +487,7 @@ static void __exit ibm_acpiphp_exit(void
 	if (ACPI_FAILURE(status))
 		err("%s: Notification handler removal failed\n", __FUNCTION__);
 	/* remove the /sys entries */
-	if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr))
-		err("%s: removal of sysfs file apci_table failed\n",
-				__FUNCTION__);
+	sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr);
 }
 
 module_init(ibm_acpiphp_init);
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index c16a93c..98022e4 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -10,6 +10,7 @@ #undef DEBUG
 
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/kernel.h>
 #include <linux/kobject.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -176,7 +177,6 @@ const struct file_operations bin_fops = 
  *	sysfs_create_bin_file - create binary file for object.
  *	@kobj:	object.
  *	@attr:	attribute descriptor.
- *
  */
 
 int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
@@ -191,13 +191,16 @@ int sysfs_create_bin_file(struct kobject
  *	sysfs_remove_bin_file - remove binary file for object.
  *	@kobj:	object.
  *	@attr:	attribute descriptor.
- *
  */
 
-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
+void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 {
-	sysfs_hash_and_remove(kobj->dentry,attr->attr.name);
-	return 0;
+	if (sysfs_hash_and_remove(kobj->dentry, attr->attr.name) < 0) {
+		printk(KERN_ERR "%s: "
+			"bad dentry or inode or no such file: \"%s\"\n",
+			__FUNCTION__, attr->attr.name);
+		dump_stack();
+	}
 }
 
 EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 9889e54..fd7cd5f 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -12,6 +12,7 @@ #include <linux/pagemap.h>
 #include <linux/namei.h>
 #include <linux/backing-dev.h>
 #include <linux/capability.h>
+#include <linux/errno.h>
 #include "sysfs.h"
 
 extern struct super_block * sysfs_sb;
@@ -234,17 +235,18 @@ void sysfs_drop_dentry(struct sysfs_dire
 	}
 }
 
-void sysfs_hash_and_remove(struct dentry * dir, const char * name)
+int sysfs_hash_and_remove(struct dentry * dir, const char * name)
 {
 	struct sysfs_dirent * sd;
 	struct sysfs_dirent * parent_sd;
+	int found = 0;
 
 	if (!dir)
-		return;
+		return -ENOENT;
 
 	if (dir->d_inode == NULL)
 		/* no inode means this hasn't been made visible yet */
-		return;
+		return -ENOENT;
 
 	parent_sd = dir->d_fsdata;
 	mutex_lock(&dir->d_inode->i_mutex);
@@ -255,8 +257,11 @@ void sysfs_hash_and_remove(struct dentry
 			list_del_init(&sd->s_sibling);
 			sysfs_drop_dentry(sd, dir);
 			sysfs_put(sd);
+			found = 1;
 			break;
 		}
 	}
 	mutex_unlock(&dir->d_inode->i_mutex);
+
+	return found ? 0 : -ENOENT;
 }
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 3651ffb..6f3d6bd 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -10,7 +10,7 @@ extern int sysfs_make_dirent(struct sysf
 				umode_t, int);
 
 extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
-extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
+extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
 extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
 
 extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 1ea5d3c..95f6db5 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -114,7 +114,7 @@ extern void
 sysfs_remove_link(struct kobject *, const char * name);
 
 int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
 
 int sysfs_create_group(struct kobject *, const struct attribute_group *);
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 35/47] Driver core: fix comments in drivers/base/power/resume.c
  2006-09-26  5:37                                                                   ` [PATCH 34/47] sysfs_remove_bin_file: no return value, dump_stack on error Greg KH
@ 2006-09-26  5:37                                                                     ` Greg KH
  2006-09-26  5:37                                                                       ` [PATCH 36/47] Driver core: fixed add_bind_files() definition Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dmitry Torokhov, Dmitry Torokhov, Greg Kroah-Hartman

From: Dmitry Torokhov <dtor@insightbb.com>

Driver core: fix comments in drivers/base/power/resume.c

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/power/resume.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 7cb62d6..020be36 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -106,12 +106,12 @@ EXPORT_SYMBOL_GPL(device_resume);
 
 
 /**
- *	device_power_up_irq - Power on some devices.
+ *	dpm_power_up - Power on some devices.
  *
  *	Walk the dpm_off_irq list and power each device up. This
  *	is used for devices that required they be powered down with
- *	interrupts disabled. As devices are powered on, they are moved to
- *	the dpm_suspended list.
+ *	interrupts disabled. As devices are powered on, they are moved
+ *	to the dpm_active list.
  *
  *	Interrupts must be disabled when calling this.
  */
@@ -129,7 +129,7 @@ void dpm_power_up(void)
 
 
 /**
- *	device_pm_power_up - Turn on all devices that need special attention.
+ *	device_power_up - Turn on all devices that need special attention.
  *
  *	Power on system devices then devices that required we shut them down
  *	with interrupts disabled.
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 36/47] Driver core: fixed add_bind_files() definition
  2006-09-26  5:37                                                                     ` [PATCH 35/47] Driver core: fix comments in drivers/base/power/resume.c Greg KH
@ 2006-09-26  5:37                                                                       ` Greg KH
  2006-09-26  5:37                                                                         ` [PATCH 37/47] add __must_check to device management code Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Yoichi Yuasa, Greg Kroah-Hartman

From: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>

When CONFIG_HOTPLUG is n, add_bind_files() definition is wrong.
This patch has fixed it.

Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/bus.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 2e954d0..4d22a1d 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -467,7 +467,7 @@ static void remove_bind_files(struct dev
 	driver_remove_file(drv, &driver_attr_unbind);
 }
 #else
-static inline void add_bind_files(struct device_driver *drv) {}
+static inline int add_bind_files(struct device_driver *drv) { return 0; }
 static inline void remove_bind_files(struct device_driver *drv) {}
 #endif
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 37/47] add __must_check to device management code
  2006-09-26  5:37                                                                       ` [PATCH 36/47] Driver core: fixed add_bind_files() definition Greg KH
@ 2006-09-26  5:37                                                                         ` Greg KH
  2006-09-26  5:37                                                                           ` [PATCH 38/47] add CONFIG_ENABLE_MUST_CHECK Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Greg Kroah-Hartman

From: Andrew Morton <akpm@osdl.org>

We're getting a lot of crashes in the sysfs/kobject/device/bus/class code and
they're very hard to diagnose.

I'm suspecting that in some cases this is because drivers aren't checking
return values and aren't handling errors correctly.  So the code blithely
blunders on and crashes later in very obscure ways.

There's just no reason to ignore errors which can and do occur.  So the patch
sprinkles __must_check all over these APIs.

Causes 1,513 new warnings.  Heh.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/device.h  |   52 +++++++++++++++++++++++++----------------------
 include/linux/kobject.h |   16 ++++++++------
 include/linux/pci.h     |   34 ++++++++++++++++---------------
 include/linux/sysfs.h   |   19 ++++++++++-------
 4 files changed, 66 insertions(+), 55 deletions(-)

diff --git a/include/linux/device.h b/include/linux/device.h
index 7d447d7..ad4db72 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -15,6 +15,7 @@ #include <linux/ioport.h>
 #include <linux/kobject.h>
 #include <linux/klist.h>
 #include <linux/list.h>
+#include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/pm.h>
@@ -58,7 +59,7 @@ struct bus_type {
 	int (*resume)(struct device * dev);
 };
 
-extern int bus_register(struct bus_type * bus);
+extern int __must_check bus_register(struct bus_type * bus);
 extern void bus_unregister(struct bus_type * bus);
 
 extern void bus_rescan_devices(struct bus_type * bus);
@@ -70,9 +71,9 @@ int bus_for_each_dev(struct bus_type * b
 struct device * bus_find_device(struct bus_type *bus, struct device *start,
 				void *data, int (*match)(struct device *, void *));
 
-int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 
-		     void * data, int (*fn)(struct device_driver *, void *));
-
+int __must_check bus_for_each_drv(struct bus_type *bus,
+		struct device_driver *start, void *data,
+		int (*fn)(struct device_driver *, void *));
 
 /* driverfs interface for exporting bus attributes */
 
@@ -85,7 +86,8 @@ struct bus_attribute {
 #define BUS_ATTR(_name,_mode,_show,_store)	\
 struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
 
-extern int bus_create_file(struct bus_type *, struct bus_attribute *);
+extern int __must_check bus_create_file(struct bus_type *,
+					struct bus_attribute *);
 extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
 
 struct device_driver {
@@ -107,14 +109,13 @@ struct device_driver {
 };
 
 
-extern int driver_register(struct device_driver * drv);
+extern int __must_check driver_register(struct device_driver * drv);
 extern void driver_unregister(struct device_driver * drv);
 
 extern struct device_driver * get_driver(struct device_driver * drv);
 extern void put_driver(struct device_driver * drv);
 extern struct device_driver *driver_find(const char *name, struct bus_type *bus);
 
-
 /* driverfs interface for exporting driver attributes */
 
 struct driver_attribute {
@@ -126,16 +127,17 @@ struct driver_attribute {
 #define DRIVER_ATTR(_name,_mode,_show,_store)	\
 struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
 
-extern int driver_create_file(struct device_driver *, struct driver_attribute *);
+extern int __must_check driver_create_file(struct device_driver *,
+					struct driver_attribute *);
 extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
 
-extern int driver_for_each_device(struct device_driver * drv, struct device * start,
-				  void * data, int (*fn)(struct device *, void *));
+extern int __must_check driver_for_each_device(struct device_driver * drv,
+		struct device *start, void *data,
+		int (*fn)(struct device *, void *));
 struct device * driver_find_device(struct device_driver *drv,
 				   struct device *start, void *data,
 				   int (*match)(struct device *, void *));
 
-
 /*
  * device classes
  */
@@ -168,7 +170,7 @@ struct class {
 	int	(*resume)(struct device *);
 };
 
-extern int class_register(struct class *);
+extern int __must_check class_register(struct class *);
 extern void class_unregister(struct class *);
 
 
@@ -181,7 +183,8 @@ struct class_attribute {
 #define CLASS_ATTR(_name,_mode,_show,_store)			\
 struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store) 
 
-extern int class_create_file(struct class *, const struct class_attribute *);
+extern int __must_check class_create_file(struct class *,
+					const struct class_attribute *);
 extern void class_remove_file(struct class *, const struct class_attribute *);
 
 struct class_device_attribute {
@@ -194,7 +197,7 @@ #define CLASS_DEVICE_ATTR(_name,_mode,_s
 struct class_device_attribute class_device_attr_##_name = 	\
 	__ATTR(_name,_mode,_show,_store)
 
-extern int class_device_create_file(struct class_device *,
+extern int __must_check class_device_create_file(struct class_device *,
 				    const struct class_device_attribute *);
 
 /**
@@ -254,10 +257,10 @@ class_set_devdata (struct class_device *
 }
 
 
-extern int class_device_register(struct class_device *);
+extern int __must_check class_device_register(struct class_device *);
 extern void class_device_unregister(struct class_device *);
 extern void class_device_initialize(struct class_device *);
-extern int class_device_add(struct class_device *);
+extern int __must_check class_device_add(struct class_device *);
 extern void class_device_del(struct class_device *);
 
 extern int class_device_rename(struct class_device *, char *);
@@ -267,7 +270,7 @@ extern void class_device_put(struct clas
 
 extern void class_device_remove_file(struct class_device *, 
 				     const struct class_device_attribute *);
-extern int class_device_create_bin_file(struct class_device *,
+extern int __must_check class_device_create_bin_file(struct class_device *,
 					struct bin_attribute *);
 extern void class_device_remove_bin_file(struct class_device *,
 					 struct bin_attribute *);
@@ -282,7 +285,7 @@ struct class_interface {
 	void (*remove_dev)	(struct device *, struct class_interface *);
 };
 
-extern int class_interface_register(struct class_interface *);
+extern int __must_check class_interface_register(struct class_interface *);
 extern void class_interface_unregister(struct class_interface *);
 
 extern struct class *class_create(struct module *owner, const char *name);
@@ -307,7 +310,8 @@ struct device_attribute {
 #define DEVICE_ATTR(_name,_mode,_show,_store) \
 struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
 
-extern int device_create_file(struct device *device, struct device_attribute * entry);
+extern int __must_check device_create_file(struct device *device,
+					struct device_attribute * entry);
 extern void device_remove_file(struct device * dev, struct device_attribute * attr);
 extern int __must_check device_create_bin_file(struct device *dev,
 					       struct bin_attribute *attr);
@@ -380,12 +384,12 @@ static inline int device_is_registered(s
 /*
  * High level routines for use by the bus drivers
  */
-extern int device_register(struct device * dev);
+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_add(struct device * dev);
+extern int __must_check device_add(struct device * dev);
 extern void device_del(struct device * dev);
-extern int device_for_each_child(struct device *, void *,
+extern int __must_check device_for_each_child(struct device *, void *,
 		     int (*fn)(struct device *, void *));
 extern int device_rename(struct device *dev, char *new_name);
 
@@ -395,7 +399,7 @@ extern int device_rename(struct device *
  */
 extern void device_bind_driver(struct device * dev);
 extern void device_release_driver(struct device * dev);
-extern int  device_attach(struct device * dev);
+extern int  __must_check device_attach(struct device * dev);
 extern void driver_attach(struct device_driver * drv);
 extern void device_reprobe(struct device *dev);
 
@@ -433,7 +437,7 @@ extern void device_shutdown(void);
 
 
 /* drivers/base/firmware.c */
-extern int firmware_register(struct subsystem *);
+extern int __must_check firmware_register(struct subsystem *);
 extern void firmware_unregister(struct subsystem *);
 
 /* debugging and troubleshooting/diagnostic helpers. */
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 2d22932..bcd9cd1 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -20,6 +20,7 @@ #ifdef __KERNEL__
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/sysfs.h>
+#include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 #include <linux/kref.h>
@@ -71,12 +72,12 @@ static inline const char * kobject_name(
 extern void kobject_init(struct kobject *);
 extern void kobject_cleanup(struct kobject *);
 
-extern int kobject_add(struct kobject *);
+extern int __must_check kobject_add(struct kobject *);
 extern void kobject_del(struct kobject *);
 
-extern int kobject_rename(struct kobject *, const char *new_name);
+extern int __must_check kobject_rename(struct kobject *, const char *new_name);
 
-extern int kobject_register(struct kobject *);
+extern int __must_check kobject_register(struct kobject *);
 extern void kobject_unregister(struct kobject *);
 
 extern struct kobject * kobject_get(struct kobject *);
@@ -128,8 +129,8 @@ struct kset {
 
 
 extern void kset_init(struct kset * k);
-extern int kset_add(struct kset * k);
-extern int kset_register(struct kset * k);
+extern int __must_check kset_add(struct kset * k);
+extern int __must_check kset_register(struct kset * k);
 extern void kset_unregister(struct kset * k);
 
 static inline struct kset * to_kset(struct kobject * kobj)
@@ -239,7 +240,7 @@ #define subsys_set_kset(obj,_subsys) \
 	(obj)->subsys.kset.kobj.kset = &(_subsys).kset
 
 extern void subsystem_init(struct subsystem *);
-extern int subsystem_register(struct subsystem *);
+extern int __must_check subsystem_register(struct subsystem *);
 extern void subsystem_unregister(struct subsystem *);
 
 static inline struct subsystem * subsys_get(struct subsystem * s)
@@ -258,7 +259,8 @@ struct subsys_attribute {
 	ssize_t (*store)(struct subsystem *, const char *, size_t); 
 };
 
-extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
+extern int __must_check subsys_create_file(struct subsystem * ,
+					struct subsys_attribute *);
 
 #if defined(CONFIG_HOTPLUG)
 void kobject_uevent(struct kobject *kobj, enum kobject_action action);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9514bbf..3ec7255 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -49,6 +49,7 @@ #include <linux/mod_devicetable.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/list.h>
+#include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/device.h>
 
@@ -403,7 +404,7 @@ extern struct list_head pci_root_buses;	
 extern struct list_head pci_devices;	/* list of all devices */
 
 void pcibios_fixup_bus(struct pci_bus *);
-int pcibios_enable_device(struct pci_dev *, int mask);
+int __must_check pcibios_enable_device(struct pci_dev *, int mask);
 char *pcibios_setup (char *str);
 
 /* Used only when drivers/pci/setup.c is used */
@@ -490,19 +491,19 @@ static inline int pci_write_config_dword
 	return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val);
 }
 
-int pci_enable_device(struct pci_dev *dev);
-int pci_enable_device_bars(struct pci_dev *dev, int mask);
+int __must_check pci_enable_device(struct pci_dev *dev);
+int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask);
 void pci_disable_device(struct pci_dev *dev);
 void pci_set_master(struct pci_dev *dev);
 #define HAVE_PCI_SET_MWI
-int pci_set_mwi(struct pci_dev *dev);
+int __must_check pci_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
 void pci_intx(struct pci_dev *dev, int enable);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
-int pci_assign_resource(struct pci_dev *dev, int i);
-int pci_assign_resource_fixed(struct pci_dev *dev, int i);
+int __must_check pci_assign_resource(struct pci_dev *dev, int i);
+int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
 void pci_restore_bars(struct pci_dev *dev);
 
 /* ROM control related routines */
@@ -528,23 +529,24 @@ void pdev_sort_resources(struct pci_dev 
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
 		    int (*)(struct pci_dev *, u8, u8));
 #define HAVE_PCI_REQ_REGIONS	2
-int pci_request_regions(struct pci_dev *, const char *);
+int __must_check pci_request_regions(struct pci_dev *, const char *);
 void pci_release_regions(struct pci_dev *);
-int pci_request_region(struct pci_dev *, int, const char *);
+int __must_check pci_request_region(struct pci_dev *, int, const char *);
 void pci_release_region(struct pci_dev *, int);
 
 /* drivers/pci/bus.c */
-int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
-			   resource_size_t size, resource_size_t align,
-			   resource_size_t min, unsigned int type_mask,
-			   void (*alignf)(void *, struct resource *,
-					  resource_size_t, resource_size_t),
-			   void *alignf_data);
+int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
+			struct resource *res, resource_size_t size,
+			resource_size_t align, resource_size_t min,
+			unsigned int type_mask,
+			void (*alignf)(void *, struct resource *,
+				resource_size_t, resource_size_t),
+			void *alignf_data);
 void pci_enable_bridges(struct pci_bus *bus);
 
 /* Proper probing supporting hot-pluggable devices */
-int __pci_register_driver(struct pci_driver *, struct module *);
-static inline int pci_register_driver(struct pci_driver *driver)
+int __must_check __pci_register_driver(struct pci_driver *, struct module *);
+static inline int __must_check pci_register_driver(struct pci_driver *driver)
 {
 	return __pci_register_driver(driver, THIS_MODULE);
 }
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 95f6db5..02ad790 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -10,6 +10,7 @@
 #ifndef _SYSFS_H_
 #define _SYSFS_H_
 
+#include <linux/compiler.h>
 #include <asm/atomic.h>
 
 struct kobject;
@@ -86,37 +87,39 @@ #define SYSFS_NOT_PINNED	(SYSFS_KOBJ_ATT
 
 #ifdef CONFIG_SYSFS
 
-extern int
+extern int __must_check
 sysfs_create_dir(struct kobject *);
 
 extern void
 sysfs_remove_dir(struct kobject *);
 
-extern int
+extern int __must_check
 sysfs_rename_dir(struct kobject *, const char *new_name);
 
-extern int
+extern int __must_check
 sysfs_create_file(struct kobject *, const struct attribute *);
 
-extern int
+extern int __must_check
 sysfs_update_file(struct kobject *, const struct attribute *);
 
-extern int
+extern int __must_check
 sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode);
 
 extern void
 sysfs_remove_file(struct kobject *, const struct attribute *);
 
-extern int
+extern int __must_check
 sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name);
 
 extern void
 sysfs_remove_link(struct kobject *, const char * name);
 
-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+int __must_check sysfs_create_bin_file(struct kobject *kobj,
+					struct bin_attribute *attr);
 void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
 
-int sysfs_create_group(struct kobject *, const struct attribute_group *);
+int __must_check sysfs_create_group(struct kobject *,
+					const struct attribute_group *);
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
 void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 38/47] add CONFIG_ENABLE_MUST_CHECK
  2006-09-26  5:37                                                                         ` [PATCH 37/47] add __must_check to device management code Greg KH
@ 2006-09-26  5:37                                                                           ` Greg KH
  2006-09-26  5:37                                                                             ` [PATCH 39/47] v4l-dev2: handle __must_check Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Greg Kroah-Hartman

From: Andrew Morton <akpm@osdl.org>

Those 1500 warnings can be a bit of a pain.  Add a config option to shut them
up.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/compiler.h |    5 +++++
 lib/Kconfig.debug        |    7 +++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 9b4f110..060b961 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -99,6 +99,11 @@ #ifndef __must_check
 #define __must_check
 #endif
 
+#ifndef CONFIG_ENABLE_MUST_CHECK
+#undef __must_check
+#define __must_check
+#endif
+
 /*
  * Allow us to avoid 'defined but not used' warnings on functions and data,
  * as well as force them to be emitted to the assembly file.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 554ee68..5c114c3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -8,6 +8,13 @@ config PRINTK_TIME
 	  operations.  This is useful for identifying long delays
 	  in kernel startup.
 
+config ENABLE_MUST_CHECK
+	bool "Enable __must_check logic"
+	default y
+	help
+	  Enable the __must_check logic in the kernel build.  Disable this to
+	  suppress the "warning: ignoring return value of 'foo', declared with
+	  attribute warn_unused_result" messages.
 
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 39/47] v4l-dev2: handle __must_check
  2006-09-26  5:37                                                                           ` [PATCH 38/47] add CONFIG_ENABLE_MUST_CHECK Greg KH
@ 2006-09-26  5:37                                                                             ` Greg KH
  2006-09-26  5:38                                                                               ` [PATCH 40/47] drivers/base: Platform notify needs to occur before drivers attach to the device Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Greg Kroah-Hartman

From: Andrew Morton <akpm@osdl.org>

We get hundreds of these:

include/media/v4l2-dev.h:348: warning: ignoring return value of 'class_device_create_file', declared with attribute warn_unused_result

Handle it, and propagate the __must_check back a level.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/media/v4l2-dev.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 810462f..bb495b7 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -341,7 +341,7 @@ #include <linux/mm.h>
 extern struct video_device* video_devdata(struct file*);
 
 #define to_video_device(cd) container_of(cd, struct video_device, class_dev)
-static inline int
+static inline int __must_check
 video_device_create_file(struct video_device *vfd,
 			 struct class_device_attribute *attr)
 {
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 40/47] drivers/base: Platform notify needs to occur before drivers attach to the device
  2006-09-26  5:37                                                                             ` [PATCH 39/47] v4l-dev2: handle __must_check Greg KH
@ 2006-09-26  5:38                                                                               ` Greg KH
  2006-09-26  5:38                                                                                 ` [PATCH 41/47] drivers/base: check errors Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Brian Walsh, Andrew Morton, Greg Kroah-Hartman

From: Brian Walsh <brian@walsh.ws>

The platform_notify call for Arm and PPC architectures needs to be called
before the driver attaches to the device.  The problem only presents itself
when hotplugging certain devices while the driver is already loaded.

Signed-off-by: Brian Walsh <brian@walsh.ws>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/core.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index bc9f35c..b224bb4 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -424,6 +424,10 @@ int device_add(struct device *dev)
 	if ((error = kobject_add(&dev->kobj)))
 		goto Error;
 
+	/* notify platform of device entry */
+	if (platform_notify)
+		platform_notify(dev);
+
 	dev->uevent_attr.attr.name = "uevent";
 	dev->uevent_attr.attr.mode = S_IWUSR;
 	if (dev->driver)
@@ -488,10 +492,6 @@ int device_add(struct device *dev)
 				class_intf->add_dev(dev, class_intf);
 		up(&dev->class->sem);
 	}
-
-	/* notify platform of device entry */
-	if (platform_notify)
-		platform_notify(dev);
  Done:
  	kfree(class_name);
 	put_device(dev);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 41/47] drivers/base: check errors
  2006-09-26  5:38                                                                               ` [PATCH 40/47] drivers/base: Platform notify needs to occur before drivers attach to the device Greg KH
@ 2006-09-26  5:38                                                                                 ` Greg KH
  2006-09-26  5:38                                                                                   ` [PATCH 42/47] sysfs: add proper sysfs_init() prototype Greg KH
  2006-09-26 17:23                                                                                   ` [PATCH 41/47] drivers/base: check errors Dmitry Torokhov
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Cornelia Huck, Greg Kroah-Hartman

From: Andrew Morton <akpm@osdl.org>

Add lots of return-value checking.

<pcornelia.huck@de.ibm.com>: fix bus_rescan_devices()]
Cc: "Randy.Dunlap" <rdunlap@xenotime.net>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/base.h    |    2 -
 drivers/base/bus.c     |  107 ++++++++++++++++++++++++++++++++----------------
 drivers/base/dd.c      |   37 ++++++++++++-----
 include/linux/device.h |    8 ++--
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index c3b8dc9..d26644a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -16,7 +16,7 @@ extern int cpu_dev_init(void);
 extern int attribute_container_init(void);
 
 extern int bus_add_device(struct device * dev);
-extern void bus_attach_device(struct device * dev);
+extern int bus_attach_device(struct device * dev);
 extern void bus_remove_device(struct device * dev);
 extern struct bus_type *get_bus(struct bus_type * bus);
 extern void put_bus(struct bus_type * bus);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 4d22a1d..aa685a2 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -371,12 +371,20 @@ int bus_add_device(struct device * dev)
 	if (bus) {
 		pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
 		error = device_add_attrs(bus, dev);
-		if (!error) {
-			sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
-			sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem");
-			sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
-		}
+		if (error)
+			goto out;
+		error = sysfs_create_link(&bus->devices.kobj,
+						&dev->kobj, dev->bus_id);
+		if (error)
+			goto out;
+		error = sysfs_create_link(&dev->kobj,
+				&dev->bus->subsys.kset.kobj, "subsystem");
+		if (error)
+			goto out;
+		error = sysfs_create_link(&dev->kobj,
+				&dev->bus->subsys.kset.kobj, "bus");
 	}
+out:
 	return error;
 }
 
@@ -386,14 +394,19 @@ int bus_add_device(struct device * dev)
  *
  *	- Try to attach to driver.
  */
-void bus_attach_device(struct device * dev)
+int bus_attach_device(struct device * dev)
 {
-	struct bus_type * bus = dev->bus;
+	struct bus_type *bus = dev->bus;
+	int ret = 0;
 
 	if (bus) {
-		device_attach(dev);
-		klist_add_tail(&dev->knode_bus, &bus->klist_devices);
+		ret = device_attach(dev);
+		if (ret >= 0) {
+			klist_add_tail(&dev->knode_bus, &bus->klist_devices);
+			ret = 0;
+		}
 	}
+	return ret;
 }
 
 /**
@@ -455,10 +468,17 @@ #ifdef CONFIG_HOTPLUG
  * Thanks to drivers making their tables __devinit, we can't allow manual
  * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
  */
-static void add_bind_files(struct device_driver *drv)
+static int __must_check add_bind_files(struct device_driver *drv)
 {
-	driver_create_file(drv, &driver_attr_unbind);
-	driver_create_file(drv, &driver_attr_bind);
+	int ret;
+
+	ret = driver_create_file(drv, &driver_attr_unbind);
+	if (ret == 0) {
+		ret = driver_create_file(drv, &driver_attr_bind);
+		if (ret)
+			driver_remove_file(drv, &driver_attr_unbind);
+	}
+	return ret;
 }
 
 static void remove_bind_files(struct device_driver *drv)
@@ -476,7 +496,7 @@ #endif
  *	@drv:	driver.
  *
  */
-int bus_add_driver(struct device_driver * drv)
+int bus_add_driver(struct device_driver *drv)
 {
 	struct bus_type * bus = get_bus(drv->bus);
 	int error = 0;
@@ -484,27 +504,39 @@ int bus_add_driver(struct device_driver 
 	if (bus) {
 		pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
 		error = kobject_set_name(&drv->kobj, "%s", drv->name);
-		if (error) {
-			put_bus(bus);
-			return error;
-		}
+		if (error)
+			goto out_put_bus;
 		drv->kobj.kset = &bus->drivers;
-		if ((error = kobject_register(&drv->kobj))) {
-			put_bus(bus);
-			return error;
-		}
+		if ((error = kobject_register(&drv->kobj)))
+			goto out_put_bus;
 
-		driver_attach(drv);
+		error = driver_attach(drv);
+		if (error)
+			goto out_unregister;
 		klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
 		module_add_driver(drv->owner, drv);
 
-		driver_add_attrs(bus, drv);
-		add_bind_files(drv);
+		error = driver_add_attrs(bus, drv);
+		if (error) {
+			/* How the hell do we get out of this pickle? Give up */
+			printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
+				__FUNCTION__, drv->name);
+		}
+		error = add_bind_files(drv);
+		if (error) {
+			/* Ditto */
+			printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
+				__FUNCTION__, drv->name);
+		}
 	}
 	return error;
+out_unregister:
+	kobject_unregister(&drv->kobj);
+out_put_bus:
+	put_bus(bus);
+	return error;
 }
 
-
 /**
  *	bus_remove_driver - delete driver from bus's knowledge.
  *	@drv:	driver.
@@ -530,16 +562,21 @@ void bus_remove_driver(struct device_dri
 
 
 /* Helper for bus_rescan_devices's iter */
-static int bus_rescan_devices_helper(struct device *dev, void *data)
+static int __must_check bus_rescan_devices_helper(struct device *dev,
+						void *data)
 {
+	int ret = 0;
+
 	if (!dev->driver) {
 		if (dev->parent)	/* Needed for USB */
 			down(&dev->parent->sem);
-		device_attach(dev);
+		ret = device_attach(dev);
 		if (dev->parent)
 			up(&dev->parent->sem);
+		if (ret > 0)
+			ret = 0;
 	}
-	return 0;
+	return ret < 0 ? ret : 0;
 }
 
 /**
@@ -550,9 +587,9 @@ static int bus_rescan_devices_helper(str
  * attached and rescan it against existing drivers to see if it matches
  * any by calling device_attach() for the unbound devices.
  */
-void bus_rescan_devices(struct bus_type * bus)
+int bus_rescan_devices(struct bus_type * bus)
 {
-	bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
+	return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
 }
 
 /**
@@ -564,7 +601,7 @@ void bus_rescan_devices(struct bus_type 
  * to use if probing criteria changed during a devices lifetime and
  * driver attachment should change accordingly.
  */
-void device_reprobe(struct device *dev)
+int device_reprobe(struct device *dev)
 {
 	if (dev->driver) {
 		if (dev->parent)        /* Needed for USB */
@@ -573,14 +610,14 @@ void device_reprobe(struct device *dev)
 		if (dev->parent)
 			up(&dev->parent->sem);
 	}
-
-	bus_rescan_devices_helper(dev, NULL);
+	return bus_rescan_devices_helper(dev, NULL);
 }
 EXPORT_SYMBOL_GPL(device_reprobe);
 
-struct bus_type * get_bus(struct bus_type * bus)
+struct bus_type *get_bus(struct bus_type *bus)
 {
-	return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL;
+	return bus ? container_of(subsys_get(&bus->subsys),
+				struct bus_type, subsys) : NULL;
 }
 
 void put_bus(struct bus_type * bus)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 889c711..9f6f11c 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -38,17 +38,29 @@ #define to_drv(node) container_of(node, 
  *
  *	This function must be called with @dev->sem held.
  */
-void device_bind_driver(struct device * dev)
+int device_bind_driver(struct device *dev)
 {
-	if (klist_node_attached(&dev->knode_driver))
-		return;
+	int ret;
+
+	if (klist_node_attached(&dev->knode_driver)) {
+		printk(KERN_WARNING "%s: device %s already bound\n",
+			__FUNCTION__, kobject_name(&dev->kobj));
+		return 0;
+	}
 
 	pr_debug("bound device '%s' to driver '%s'\n",
 		 dev->bus_id, dev->driver->name);
 	klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
-	sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+	ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
 			  kobject_name(&dev->kobj));
-	sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+	if (ret == 0) {
+		ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj,
+					"driver");
+		if (ret)
+			sysfs_remove_link(&dev->driver->kobj,
+					kobject_name(&dev->kobj));
+	}
+	return ret;
 }
 
 /**
@@ -91,7 +103,11 @@ int driver_probe_device(struct device_dr
 			goto ProbeFailed;
 		}
 	}
-	device_bind_driver(dev);
+	if (device_bind_driver(dev)) {
+		printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
+			__FUNCTION__, dev->bus_id);
+		/* How does undo a ->probe?  We're screwed. */
+	}
 	ret = 1;
 	pr_debug("%s: Bound Device %s to Driver %s\n",
 		 drv->bus->name, dev->bus_id, drv->name);
@@ -139,8 +155,9 @@ int device_attach(struct device * dev)
 
 	down(&dev->sem);
 	if (dev->driver) {
-		device_bind_driver(dev);
-		ret = 1;
+		ret = device_bind_driver(dev);
+		if (ret == 0)
+			ret = 1;
 	} else
 		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
 	up(&dev->sem);
@@ -182,9 +199,9 @@ static int __driver_attach(struct device
  *	returns 0 and the @dev->driver is set, we've found a
  *	compatible pair.
  */
-void driver_attach(struct device_driver * drv)
+int driver_attach(struct device_driver * drv)
 {
-	bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
+	return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
 }
 
 /**
diff --git a/include/linux/device.h b/include/linux/device.h
index ad4db72..b3da9a8 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -62,7 +62,7 @@ struct bus_type {
 extern int __must_check bus_register(struct bus_type * bus);
 extern void bus_unregister(struct bus_type * bus);
 
-extern void bus_rescan_devices(struct bus_type * bus);
+extern int __must_check bus_rescan_devices(struct bus_type * bus);
 
 /* iterator helpers for buses */
 
@@ -397,11 +397,11 @@ extern int device_rename(struct device *
  * Manual binding of a device to driver. See drivers/base/bus.c
  * for information on use.
  */
-extern void device_bind_driver(struct device * dev);
+extern int __must_check device_bind_driver(struct device *dev);
 extern void device_release_driver(struct device * dev);
 extern int  __must_check device_attach(struct device * dev);
-extern void driver_attach(struct device_driver * drv);
-extern void device_reprobe(struct device *dev);
+extern int __must_check driver_attach(struct device_driver *drv);
+extern int __must_check device_reprobe(struct device *dev);
 
 /*
  * Easy functions for dynamically creating devices on the fly
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 42/47] sysfs: add proper sysfs_init() prototype
  2006-09-26  5:38                                                                                 ` [PATCH 41/47] drivers/base: check errors Greg KH
@ 2006-09-26  5:38                                                                                   ` Greg KH
  2006-09-26  5:38                                                                                     ` [PATCH 43/47] Driver Core: add ability for drivers to do a threaded probe Greg KH
  2006-09-26 17:23                                                                                   ` [PATCH 41/47] drivers/base: check errors Dmitry Torokhov
  1 sibling, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Greg Kroah-Hartman

From: Andrew Morton <akpm@osdl.org>

Don't be crufty.  Mark it __must_check too.

Cc: "Randy.Dunlap" <rdunlap@xenotime.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 fs/namespace.c        |   10 +---------
 include/linux/sysfs.h |    7 +++++++
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index fa7ed6a..36d1808 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -17,6 +17,7 @@ #include <linux/quotaops.h>
 #include <linux/acct.h>
 #include <linux/capability.h>
 #include <linux/module.h>
+#include <linux/sysfs.h>
 #include <linux/seq_file.h>
 #include <linux/namespace.h>
 #include <linux/namei.h>
@@ -28,15 +29,6 @@ #include "pnode.h"
 
 extern int __init init_rootfs(void);
 
-#ifdef CONFIG_SYSFS
-extern int __init sysfs_init(void);
-#else
-static inline int sysfs_init(void)
-{
-	return 0;
-}
-#endif
-
 /* spinlock for vfsmount related operations, inplace of dcache_lock */
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
 
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 02ad790..6d5c43d 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -123,6 +123,8 @@ int __must_check sysfs_create_group(stru
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
 void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
+extern int __must_check sysfs_init(void);
+
 #else /* CONFIG_SYSFS */
 
 static inline int sysfs_create_dir(struct kobject * k)
@@ -194,6 +196,11 @@ static inline void sysfs_notify(struct k
 {
 }
 
+static inline int __must_check sysfs_init(void)
+{
+	return 0;
+}
+
 #endif /* CONFIG_SYSFS */
 
 #endif /* _SYSFS_H_ */
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 43/47] Driver Core: add ability for drivers to do a threaded probe
  2006-09-26  5:38                                                                                   ` [PATCH 42/47] sysfs: add proper sysfs_init() prototype Greg KH
@ 2006-09-26  5:38                                                                                     ` Greg KH
  2006-09-26  5:38                                                                                       ` [PATCH 44/47] PCI: enable driver multi-threaded probe Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This adds the infrastructure for drivers to do a threaded probe, and
waits at init time for all currently outstanding probes to complete.

A new kernel thread will be created when the probe() function for the
driver is called, if the multithread_probe bit is set in the driver
saying it can support this kind of operation.

I have tested this with USB and PCI, and it works, and shaves off a lot
of time in the boot process, but there are issues with finding root boot
disks, and some USB drivers assume that this can never happen, so it is
currently not enabled for any bus type.  Individual drivers can enable
this right now if they wish, and bus authors can selectivly turn it on
as well, once they determine that their subsystem will work properly
with it.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/dd.c      |  108 ++++++++++++++++++++++++++++++++++++------------
 include/linux/device.h |    3 +
 init/do_mounts.c       |    5 ++
 3 files changed, 89 insertions(+), 27 deletions(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9f6f11c..319a73b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -17,6 +17,7 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/kthread.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -63,44 +64,35 @@ int device_bind_driver(struct device *de
 	return ret;
 }
 
-/**
- *	driver_probe_device - attempt to bind device & driver.
- *	@drv:	driver.
- *	@dev:	device.
- *
- *	First, we call the bus's match function, if one present, which
- *	should compare the device IDs the driver supports with the
- *	device IDs of the device. Note we don't do this ourselves
- *	because we don't know the format of the ID structures, nor what
- *	is to be considered a match and what is not.
- *
- *	This function returns 1 if a match is found, an error if one
- *	occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
- *
- *	This function must be called with @dev->sem held.  When called
- *	for a USB interface, @dev->parent->sem must be held as well.
- */
-int driver_probe_device(struct device_driver * drv, struct device * dev)
+struct stupid_thread_structure {
+	struct device_driver *drv;
+	struct device *dev;
+};
+
+static atomic_t probe_count = ATOMIC_INIT(0);
+static int really_probe(void *void_data)
 {
+	struct stupid_thread_structure *data = void_data;
+	struct device_driver *drv = data->drv;
+	struct device *dev = data->dev;
 	int ret = 0;
 
-	if (drv->bus->match && !drv->bus->match(dev, drv))
-		goto Done;
+	atomic_inc(&probe_count);
+	pr_debug("%s: Probing driver %s with device %s\n",
+		 drv->bus->name, drv->name, dev->bus_id);
 
-	pr_debug("%s: Matched Device %s with Driver %s\n",
-		 drv->bus->name, dev->bus_id, drv->name);
 	dev->driver = drv;
 	if (dev->bus->probe) {
 		ret = dev->bus->probe(dev);
 		if (ret) {
 			dev->driver = NULL;
-			goto ProbeFailed;
+			goto probe_failed;
 		}
 	} else if (drv->probe) {
 		ret = drv->probe(dev);
 		if (ret) {
 			dev->driver = NULL;
-			goto ProbeFailed;
+			goto probe_failed;
 		}
 	}
 	if (device_bind_driver(dev)) {
@@ -111,9 +103,9 @@ int driver_probe_device(struct device_dr
 	ret = 1;
 	pr_debug("%s: Bound Device %s to Driver %s\n",
 		 drv->bus->name, dev->bus_id, drv->name);
-	goto Done;
+	goto done;
 
- ProbeFailed:
+probe_failed:
 	if (ret == -ENODEV || ret == -ENXIO) {
 		/* Driver matched, but didn't support device
 		 * or device not found.
@@ -126,7 +118,69 @@ int driver_probe_device(struct device_dr
 		       "%s: probe of %s failed with error %d\n",
 		       drv->name, dev->bus_id, ret);
 	}
- Done:
+done:
+	kfree(data);
+	atomic_dec(&probe_count);
+	return ret;
+}
+
+/**
+ * driver_probe_done
+ * Determine if the probe sequence is finished or not.
+ *
+ * Should somehow figure out how to use a semaphore, not an atomic variable...
+ */
+int driver_probe_done(void)
+{
+	pr_debug("%s: probe_count = %d\n", __FUNCTION__,
+		 atomic_read(&probe_count));
+	if (atomic_read(&probe_count))
+		return -EBUSY;
+	return 0;
+}
+
+/**
+ * driver_probe_device - attempt to bind device & driver together
+ * @drv: driver to bind a device to
+ * @dev: device to try to bind to the driver
+ *
+ * First, we call the bus's match function, if one present, which should
+ * compare the device IDs the driver supports with the device IDs of the
+ * device. Note we don't do this ourselves because we don't know the
+ * format of the ID structures, nor what is to be considered a match and
+ * what is not.
+ *
+ * This function returns 1 if a match is found, an error if one occurs
+ * (that is not -ENODEV or -ENXIO), and 0 otherwise.
+ *
+ * This function must be called with @dev->sem held.  When called for a
+ * USB interface, @dev->parent->sem must be held as well.
+ */
+int driver_probe_device(struct device_driver * drv, struct device * dev)
+{
+	struct stupid_thread_structure *data;
+	struct task_struct *probe_task;
+	int ret = 0;
+
+	if (drv->bus->match && !drv->bus->match(dev, drv))
+		goto done;
+
+	pr_debug("%s: Matched Device %s with Driver %s\n",
+		 drv->bus->name, dev->bus_id, drv->name);
+
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data->drv = drv;
+	data->dev = dev;
+
+	if (drv->multithread_probe) {
+		probe_task = kthread_run(really_probe, data,
+					 "probe-%s", dev->bus_id);
+		if (IS_ERR(probe_task))
+			ret = PTR_ERR(probe_task);
+	} else
+		ret = really_probe(data);
+
+done:
 	return ret;
 }
 
diff --git a/include/linux/device.h b/include/linux/device.h
index b3da9a8..74246ef 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -106,6 +106,8 @@ struct device_driver {
 	void	(*shutdown)	(struct device * dev);
 	int	(*suspend)	(struct device * dev, pm_message_t state);
 	int	(*resume)	(struct device * dev);
+
+	unsigned int multithread_probe:1;
 };
 
 
@@ -115,6 +117,7 @@ extern void driver_unregister(struct dev
 extern struct device_driver * get_driver(struct device_driver * drv);
 extern void put_driver(struct device_driver * drv);
 extern struct device_driver *driver_find(const char *name, struct bus_type *bus);
+extern int driver_probe_done(void);
 
 /* driverfs interface for exporting driver attributes */
 
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 94aeec7..b290aad 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -8,6 +8,7 @@ #include <linux/root_dev.h>
 #include <linux/security.h>
 #include <linux/delay.h>
 #include <linux/mount.h>
+#include <linux/device.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
@@ -403,6 +404,10 @@ void __init prepare_namespace(void)
 		ssleep(root_delay);
 	}
 
+	/* wait for the known devices to complete their probing */
+	while (driver_probe_done() != 0)
+		msleep(100);
+
 	md_run_setup();
 
 	if (saved_root_name[0]) {
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 44/47] PCI: enable driver multi-threaded probe
  2006-09-26  5:38                                                                                     ` [PATCH 43/47] Driver Core: add ability for drivers to do a threaded probe Greg KH
@ 2006-09-26  5:38                                                                                       ` Greg KH
  2006-09-26  5:38                                                                                         ` [PATCH 45/47] Driver core: Fix potential deadlock in driver core Greg KH
  2006-09-27 18:51                                                                                         ` [PATCH 44/47] PCI: enable driver multi-threaded probe Olaf Hering
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman

From: Greg Kroah-Hartman <gregkh@suse.de>

This provides a build and run-time option to turn on multhreaded probe
for all PCI drivers.  It can cause bad problems on multi-processor
machines that take a while to find their root disks, and play havoc on
machines that don't use persistant device names for block or network
devices.

But it can cause speedups on some machines, my tiny laptop's boot goes
up by 0.4 seconds, and my desktop boots up several seconds faster.

Use at your own risk!!!

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/pci/Kconfig      |   25 +++++++++++++++++++++++++
 drivers/pci/pci-driver.c |   11 +++++++++++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 4d762fc..c27e782 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -17,6 +17,31 @@ config PCI_MSI
 
 	   If you don't know what to do here, say N.
 
+config PCI_MULTITHREAD_PROBE
+	bool "PCI Multi-threaded probe (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL
+	help
+	  Say Y here if you want the PCI core to spawn a new thread for
+	  every PCI device that is probed.  This can cause a huge
+	  speedup in boot times on multiprocessor machines, and even a
+	  smaller speedup on single processor machines.
+
+	  But it can also cause lots of bad things to happen.  A number
+	  of PCI drivers can not properly handle running in this way,
+	  some will just not work properly at all, while others might
+	  decide to blow up power supplies with a huge load all at once,
+	  so use this option at your own risk.
+
+	  It is very unwise to use this option if you are not using a
+	  boot process that can handle devices being created in any
+	  order.  A program that can create persistant block and network
+	  device names (like udev) is a good idea if you wish to use
+	  this option.
+
+	  Again, use this option at your own risk, you have been warned!
+
+	  When in doubt, say N.
+
 config PCI_DEBUG
 	bool "PCI Debugging"
 	depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 8948ac9..d8ace1f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -17,6 +17,16 @@ #include "pci.h"
  *  Registration of PCI drivers and handling of hot-pluggable devices.
  */
 
+/* multithreaded probe logic */
+static int pci_multithread_probe =
+#ifdef CONFIG_PCI_MULTITHREAD_PROBE
+	1;
+#else
+	0;
+#endif
+__module_param_call("", pci_multithread_probe, param_set_bool, param_get_bool, &pci_multithread_probe, 0644);
+
+
 /*
  * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
  */
@@ -408,6 +418,7 @@ int __pci_register_driver(struct pci_dri
 	drv->driver.bus = &pci_bus_type;
 	drv->driver.owner = owner;
 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
+	drv->driver.multithread_probe = pci_multithread_probe;
 
 	spin_lock_init(&drv->dynids.lock);
 	INIT_LIST_HEAD(&drv->dynids.list);
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 45/47] Driver core: Fix potential deadlock in driver core
  2006-09-26  5:38                                                                                       ` [PATCH 44/47] PCI: enable driver multi-threaded probe Greg KH
@ 2006-09-26  5:38                                                                                         ` Greg KH
  2006-09-26  5:38                                                                                           ` [PATCH 46/47] Driver core: Remove unneeded routines from " Greg KH
  2006-09-27 18:51                                                                                         ` [PATCH 44/47] PCI: enable driver multi-threaded probe Olaf Hering
  1 sibling, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Stern, Greg Kroah-Hartman

From: Alan Stern <stern@rowland.harvard.edu>

There is a potential deadlock in the driver core.  It boils down to
the fact that bus_remove_device() calls klist_remove() instead of
klist_del(), thereby waiting until the reference count of the
klist_node in the bus's klist of devices drops to 0.  The refcount
can't reach 0 so long as a modprobe process is trying to bind a new
driver to the device being removed, by calling __driver_attach().  The
problem is that __driver_attach() tries to acquire the device's
parent's semaphore, but the caller of bus_remove_device() is quite
likely to own that semaphore already.

It isn't sufficient just to replace klist_remove() with klist_del().
Doing so runs the risk that the device would remain on the bus's klist
of devices for some time, and so could be bound to another driver even
after it was unregistered.  What's needed is a new way to distinguish
whether or not a device is registered, based on a criterion other than
whether its klist_node is linked into the bus's klist of devices.  That
way driver binding can fail when the device is unregistered, even if
it is still linked into the klist.

This patch (as782) implements the solution, by adding a new bitflag to
indiate when a struct device is registered, by testing the flag before
allowing a driver to bind a device, and by changing the definition of
the device_is_registered() inline.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/bus.c     |    8 ++++++--
 drivers/base/dd.c      |    2 ++
 include/linux/device.h |    3 ++-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index aa685a2..636af53 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -392,6 +392,7 @@ out:
  *	bus_attach_device - add device to bus
  *	@dev:	device tried to attach to a driver
  *
+ *	- Add device to bus's list of devices.
  *	- Try to attach to driver.
  */
 int bus_attach_device(struct device * dev)
@@ -400,11 +401,13 @@ int bus_attach_device(struct device * de
 	int ret = 0;
 
 	if (bus) {
+		dev->is_registered = 1;
 		ret = device_attach(dev);
 		if (ret >= 0) {
 			klist_add_tail(&dev->knode_bus, &bus->klist_devices);
 			ret = 0;
-		}
+		} else
+			dev->is_registered = 0;
 	}
 	return ret;
 }
@@ -425,7 +428,8 @@ void bus_remove_device(struct device * d
 		sysfs_remove_link(&dev->kobj, "bus");
 		sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
 		device_remove_attrs(dev->bus, dev);
-		klist_remove(&dev->knode_bus);
+		dev->is_registered = 0;
+		klist_del(&dev->knode_bus);
 		pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
 		device_release_driver(dev);
 		put_bus(dev->bus);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 319a73b..b5f43c3 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -162,6 +162,8 @@ int driver_probe_device(struct device_dr
 	struct task_struct *probe_task;
 	int ret = 0;
 
+	if (!device_is_registered(dev))
+		return -ENODEV;
 	if (drv->bus->match && !drv->bus->match(dev, drv))
 		goto done;
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 74246ef..662e6a1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -329,6 +329,7 @@ struct device {
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	unsigned		is_registered:1;
 	struct device_attribute uevent_attr;
 	struct device_attribute *devt_attr;
 
@@ -381,7 +382,7 @@ dev_set_drvdata (struct device *dev, voi
 
 static inline int device_is_registered(struct device *dev)
 {
-	return klist_node_attached(&dev->knode_bus);
+	return dev->is_registered;
 }
 
 /*
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 46/47] Driver core: Remove unneeded routines from driver core
  2006-09-26  5:38                                                                                         ` [PATCH 45/47] Driver core: Fix potential deadlock in driver core Greg KH
@ 2006-09-26  5:38                                                                                           ` Greg KH
  2006-09-26  5:38                                                                                             ` [PATCH 47/47] Driver core: Don't call put methods while holding a spinlock Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Stern, Greg Kroah-Hartman

From: Alan Stern <stern@rowland.harvard.edu>

This patch (as783) simplifies the driver core slightly by removing four
unnecessary _get and _put methods.

It is vital that when a driver is removed from its bus's klist of
registered drivers, or when a device is removed from a driver's klist
of bound devices, that the klist updates complete synchronously.
Otherwise the kernel might try binding an unregistered driver to a
newly-registered device, or adding a device to the klist for a new
driver before it has been removed from the old driver's klist.

Since the removals must be synchronous, they don't need to update any
reference counts.  Hence the _get and _put methods can be dispensed
with.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/bus.c    |   18 +-----------------
 drivers/base/driver.c |   16 +---------------
 2 files changed, 2 insertions(+), 32 deletions(-)

diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 636af53..12173d1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -696,22 +696,6 @@ static void klist_devices_put(struct kli
 	put_device(dev);
 }
 
-static void klist_drivers_get(struct klist_node *n)
-{
-	struct device_driver *drv = container_of(n, struct device_driver,
-						 knode_bus);
-
-	get_driver(drv);
-}
-
-static void klist_drivers_put(struct klist_node *n)
-{
-	struct device_driver *drv = container_of(n, struct device_driver,
-						 knode_bus);
-
-	put_driver(drv);
-}
-
 /**
  *	bus_register - register a bus with the system.
  *	@bus:	bus.
@@ -747,7 +731,7 @@ int bus_register(struct bus_type * bus)
 		goto bus_drivers_fail;
 
 	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
-	klist_init(&bus->klist_drivers, klist_drivers_get, klist_drivers_put);
+	klist_init(&bus->klist_drivers, NULL, NULL);
 	bus_add_attrs(bus);
 
 	pr_debug("bus type '%s' registered\n", bus->name);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 562600d..1214cbd 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -142,20 +142,6 @@ void put_driver(struct device_driver * d
 	kobject_put(&drv->kobj);
 }
 
-static void klist_devices_get(struct klist_node *n)
-{
-	struct device *dev = container_of(n, struct device, knode_driver);
-
-	get_device(dev);
-}
-
-static void klist_devices_put(struct klist_node *n)
-{
-	struct device *dev = container_of(n, struct device, knode_driver);
-
-	put_device(dev);
-}
-
 /**
  *	driver_register - register driver with bus
  *	@drv:	driver to register
@@ -175,7 +161,7 @@ int driver_register(struct device_driver
 	    (drv->bus->shutdown && drv->shutdown)) {
 		printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
 	}
-	klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
+	klist_init(&drv->klist_devices, NULL, NULL);
 	init_completion(&drv->unloaded);
 	return bus_add_driver(drv);
 }
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 47/47] Driver core: Don't call put methods while holding a spinlock
  2006-09-26  5:38                                                                                           ` [PATCH 46/47] Driver core: Remove unneeded routines from " Greg KH
@ 2006-09-26  5:38                                                                                             ` Greg KH
  0 siblings, 0 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26  5:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Stern, Greg Kroah-Hartman

From: Alan Stern <stern@rowland.harvard.edu>

The klist utility routines currently call _put methods while holding a
spinlock.  This is of course illegal; a put routine could try to
unregister a device and hence need to sleep.

No problems have arisen until now because in many cases klist removals
were done synchronously, so the _put methods were never actually used.
In other cases we may simply have been lucky.

This patch (as784) reworks the klist routines so that _put methods are
called only _after_ the klist's spinlock has been released.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 lib/klist.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/lib/klist.c b/lib/klist.c
index 9c94f0b..120bd17 100644
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -123,12 +123,10 @@ EXPORT_SYMBOL_GPL(klist_add_tail);
 static void klist_release(struct kref * kref)
 {
 	struct klist_node * n = container_of(kref, struct klist_node, n_ref);
-	void (*put)(struct klist_node *) = n->n_klist->put;
+
 	list_del(&n->n_node);
 	complete(&n->n_removed);
 	n->n_klist = NULL;
-	if (put)
-		put(n);
 }
 
 static int klist_dec_and_del(struct klist_node * n)
@@ -145,10 +143,14 @@ static int klist_dec_and_del(struct klis
 void klist_del(struct klist_node * n)
 {
 	struct klist * k = n->n_klist;
+	void (*put)(struct klist_node *) = k->put;
 
 	spin_lock(&k->k_lock);
-	klist_dec_and_del(n);
+	if (!klist_dec_and_del(n))
+		put = NULL;
 	spin_unlock(&k->k_lock);
+	if (put)
+		put(n);
 }
 
 EXPORT_SYMBOL_GPL(klist_del);
@@ -161,10 +163,7 @@ EXPORT_SYMBOL_GPL(klist_del);
 
 void klist_remove(struct klist_node * n)
 {
-	struct klist * k = n->n_klist;
-	spin_lock(&k->k_lock);
-	klist_dec_and_del(n);
-	spin_unlock(&k->k_lock);
+	klist_del(n);
 	wait_for_completion(&n->n_removed);
 }
 
@@ -260,12 +259,15 @@ static struct klist_node * to_klist_node
 struct klist_node * klist_next(struct klist_iter * i)
 {
 	struct list_head * next;
+	struct klist_node * lnode = i->i_cur;
 	struct klist_node * knode = NULL;
+	void (*put)(struct klist_node *) = i->i_klist->put;
 
 	spin_lock(&i->i_klist->k_lock);
-	if (i->i_cur) {
-		next = i->i_cur->n_node.next;
-		klist_dec_and_del(i->i_cur);
+	if (lnode) {
+		next = lnode->n_node.next;
+		if (!klist_dec_and_del(lnode))
+			put = NULL;
 	} else
 		next = i->i_head->next;
 
@@ -275,6 +277,8 @@ struct klist_node * klist_next(struct kl
 	}
 	i->i_cur = knode;
 	spin_unlock(&i->i_klist->k_lock);
+	if (put && lnode)
+		put(lnode);
 	return knode;
 }
 
-- 
1.4.2.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-26  5:37 [GIT PATCH] Driver Core patches for 2.6.18 Greg KH
  2006-09-26  5:37 ` [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed! Greg KH
@ 2006-09-26 12:34 ` Mike Galbraith
  2006-09-26 20:39   ` Greg KH
  1 sibling, 1 reply; 72+ messages in thread
From: Mike Galbraith @ 2006-09-26 12:34 UTC (permalink / raw)
  To: Greg KH; +Cc: Linus Torvalds, Andrew Morton, linux-kernel

On Mon, 2006-09-25 at 22:37 -0700, Greg KH wrote:
> Here are a bunch of driver core and sysfs patches and fixes for 2.6.18.

Hi,

Just as an fyi, these patches cause a ~regression on my P4/HT box.

Suspend stopped here working after 2.6.17.  I haven't dug into why, but
since then, I get a message "Class driver suspend failed for cpu0", and
the suspend fails, but everything works fine afterward.  If I ignore the
return of drv->suspend(), the box will suspend and resume just fine,
both with this patch set and without.  (which is what I've been doing
while waiting for it to fix itself or for my round toit to turn up)

In the fail case _with_ this set though, all is not well after a failed
suspend.  The box isn't locked up, but it's ding-dong dead.  The GUI
freezes, but I can switch to command line.  I get to a login prompt, but
as I try to login, that VT is toast.  I tried a SysRq-T to see what
everybody's up to, but after the failure, we apparently never get as far
as restoring serial.  SysRq-B works.  SysRq-O don't.

It seems to be just me, (and I apparently don't care very much), but I
figured I should let you know about it.

	Cheers,

	-Mike


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26  5:37                                                   ` [PATCH 26/47] Driver core: add groups support to struct device Greg KH
  2006-09-26  5:37                                                     ` [PATCH 27/47] Driver core: allow devices in classes to have no parent Greg KH
@ 2006-09-26 13:20                                                     ` Dmitry Torokhov
  2006-09-26 13:46                                                       ` Greg KH
  1 sibling, 1 reply; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 13:20 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Linus Torvalds, Andrew Morton

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> From: Greg Kroah-Hartman <gregkh@suse.de>
>
> This is needed for the network class devices in order to be able to
> convert over to use struct device.
>

Greg,

You keep pushing out patches that merge class devices and standard
devices but you still have not shown the usefullness of this process.
Why do you feel the need to change internal kernel structures
(ever-expanding struct device to accomodate everything that is in
struct class_device) when it should be possible to simply adjust sysfs
representation of the kernel tree (moving class devices into
/sys/device/.. part of the tree)  to udev's liking and leave the rest
of the kernel alone. You have seen the patch, only minor changes in
driver/base/class.c are needed to accomplish the move.

I really disappointed that there was no discussion/review of the
implementation at all.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26  5:37                                                           ` [PATCH 30/47] Driver core: create devices/virtual/ tree Greg KH
  2006-09-26  5:37                                                             ` [PATCH 31/47] Class: add support for class interfaces for devices Greg KH
@ 2006-09-26 13:24                                                             ` Dmitry Torokhov
  2006-09-26 13:41                                                               ` Greg KH
  1 sibling, 1 reply; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 13:24 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Kay Sievers

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> From: Greg Kroah-Hartman <gregkh@suse.de>
>
> This change creates a devices/virtual/CLASS_NAME tree for struct devices
> that belong to a class, yet do not have a "real" struct device for a
> parent.  It automatically creates the directories on the fly as needed.
>

Why do you need multiple virtual devices? All parentless class devices
could grow from a single virtual device.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26 13:24                                                             ` [PATCH 30/47] Driver core: create devices/virtual/ tree Dmitry Torokhov
@ 2006-09-26 13:41                                                               ` Greg KH
  2006-09-26 13:51                                                                 ` Dmitry Torokhov
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26 13:41 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Kay Sievers

On Tue, Sep 26, 2006 at 09:24:15AM -0400, Dmitry Torokhov wrote:
> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >From: Greg Kroah-Hartman <gregkh@suse.de>
> >
> >This change creates a devices/virtual/CLASS_NAME tree for struct devices
> >that belong to a class, yet do not have a "real" struct device for a
> >parent.  It automatically creates the directories on the fly as needed.
> >
> 
> Why do you need multiple virtual devices? All parentless class devices
> could grow from a single virtual device.

They could, but it's a mess of a single directory if you do that.
Having /sys/devices/virtual/tty/ as a place for all tty virtual device
is nicer than /sys/devices/virtual/ as a single place for all of them
(mem, network, tty, misc, etc.)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 13:20                                                     ` [PATCH 26/47] Driver core: add groups support to struct device Dmitry Torokhov
@ 2006-09-26 13:46                                                       ` Greg KH
  2006-09-26 14:01                                                         ` Dmitry Torokhov
  2006-09-26 15:18                                                         ` Marcel Holtmann
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26 13:46 UTC (permalink / raw)
  To: Dmitry Torokhov, Kay Sievers; +Cc: linux-kernel, Linus Torvalds, Andrew Morton

On Tue, Sep 26, 2006 at 09:20:17AM -0400, Dmitry Torokhov wrote:
> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >From: Greg Kroah-Hartman <gregkh@suse.de>
> >
> >This is needed for the network class devices in order to be able to
> >convert over to use struct device.
> >
> 
> Greg,
> 
> You keep pushing out patches that merge class devices and standard
> devices but you still have not shown the usefullness of this process.

I have not?  This has been discussed before.

> Why do you feel the need to change internal kernel structures
> (ever-expanding struct device to accomodate everything that is in
> struct class_device) when it should be possible to simply adjust sysfs
> representation of the kernel tree (moving class devices into
> /sys/device/.. part of the tree)  to udev's liking and leave the rest
> of the kernel alone. You have seen the patch, only minor changes in
> driver/base/class.c are needed to accomplish the move.

Think about suspend.  We want a single device tree so that the class
gets called when a device is about to be suspended so that it could shut
down the network queue in a common way, before the physical device is
called.

It's also needed if we want to have a single device tree in general.
class_device was the wrong thing and is really just a duplicate of
struct device in the first place (the driver core code implementing it
is pretty much just a cut and paste job.)  The fact that we were
arbritrary marking it different has caused problems (look at the mess
that input causes to the class_device code, that's just not nice).

Kay also has a long list of the reasons why, I think he's posted it here
before.  Kay, care to send that list again?

> I really disappointed that there was no discussion/review of the
> implementation at all.

There has not been any real implementation yet, only a few patches added
to the core that add a few extra functionality to struct device to allow
class_device to move that way.  The patches that move the subsystems
over will be discussed (and some already have, like networking), when
they are ready.  Right now most of that work is being done by Kay and
myself as a proof of concept to make sure that we can do this properly
and that userspace can handle it well.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26 13:41                                                               ` Greg KH
@ 2006-09-26 13:51                                                                 ` Dmitry Torokhov
  2006-09-26 14:26                                                                   ` Greg KH
  0 siblings, 1 reply; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 13:51 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Kay Sievers

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> On Tue, Sep 26, 2006 at 09:24:15AM -0400, Dmitry Torokhov wrote:
> > On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >From: Greg Kroah-Hartman <gregkh@suse.de>
> > >
> > >This change creates a devices/virtual/CLASS_NAME tree for struct devices
> > >that belong to a class, yet do not have a "real" struct device for a
> > >parent.  It automatically creates the directories on the fly as needed.
> > >
> >
> > Why do you need multiple virtual devices? All parentless class devices
> > could grow from a single virtual device.
>
> They could, but it's a mess of a single directory if you do that.
> Having /sys/devices/virtual/tty/ as a place for all tty virtual device
> is nicer than /sys/devices/virtual/ as a single place for all of them
> (mem, network, tty, misc, etc.)
>

You supposed to use classes for classification, and devices to
represent the tree so that would be /sys/class/tty/...

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 13:46                                                       ` Greg KH
@ 2006-09-26 14:01                                                         ` Dmitry Torokhov
  2006-09-26 14:23                                                           ` Greg KH
  2006-09-26 15:18                                                         ` Marcel Holtmann
  1 sibling, 1 reply; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 14:01 UTC (permalink / raw)
  To: Greg KH; +Cc: Kay Sievers, linux-kernel, Linus Torvalds, Andrew Morton

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> On Tue, Sep 26, 2006 at 09:20:17AM -0400, Dmitry Torokhov wrote:
> > On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >From: Greg Kroah-Hartman <gregkh@suse.de>
> > >
> > >This is needed for the network class devices in order to be able to
> > >convert over to use struct device.
> > >
> >
> > Greg,
> >
> > You keep pushing out patches that merge class devices and standard
> > devices but you still have not shown the usefullness of this process.
>
> I have not?  This has been discussed before.
>

Care to send me a pointer?

> > Why do you feel the need to change internal kernel structures
> > (ever-expanding struct device to accomodate everything that is in
> > struct class_device) when it should be possible to simply adjust sysfs
> > representation of the kernel tree (moving class devices into
> > /sys/device/.. part of the tree)  to udev's liking and leave the rest
> > of the kernel alone. You have seen the patch, only minor changes in
> > driver/base/class.c are needed to accomplish the move.
>
> Think about suspend.  We want a single device tree so that the class
> gets called when a device is about to be suspended so that it could shut
> down the network queue in a common way, before the physical device is
> called.

Why can't the device itself manage it? If you want to stub out the
common parts just create a function like netdev_suspend and call it at
appropriate time.

>
> It's also needed if we want to have a single device tree in general.
> class_device was the wrong thing and is really just a duplicate of
> struct device in the first place (the driver core code implementing it
> is pretty much just a cut and paste job.)

They complement each other. They are different and need different
methods to operate.

>  The fact that we were
> arbritrary marking it different has caused problems (look at the mess
> that input causes to the class_device code, that's just not nice).
>

The only mess is that you refused to deepen the classification (i.e.
have sub-classes). If input could be a parent class and
mice/event/js/ts would grow from it it won't be such a mess.
Alternatively we could go with input vs input_intf classes if flat
classification is a must. Anyway, I don't think we want to break udev
again.

> Kay also has a long list of the reasons why, I think he's posted it here
> before.  Kay, care to send that list again?
>

Kay did send it and I agree with all his reasons as to why we need the
move. However I do not agree with your implementation.

> > I really disappointed that there was no discussion/review of the
> > implementation at all.
>
> There has not been any real implementation yet, only a few patches added
> to the core that add a few extra functionality to struct device to allow
> class_device to move that way.

If there was no real discussion why you requesting these changes to be
pulled in the mainline?

>  The patches that move the subsystems
> over will be discussed (and some already have, like networking), when
> they are ready.  Right now most of that work is being done by Kay and
> myself as a proof of concept to make sure that we can do this properly
> and that userspace can handle it well.
>
> thanks,
>
> greg k-h
>


-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 14:01                                                         ` Dmitry Torokhov
@ 2006-09-26 14:23                                                           ` Greg KH
  2006-09-26 17:10                                                             ` Dmitry Torokhov
  2006-09-27 14:40                                                             ` Pavel Machek
  0 siblings, 2 replies; 72+ messages in thread
From: Greg KH @ 2006-09-26 14:23 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Kay Sievers, linux-kernel, Linus Torvalds, Andrew Morton

On Tue, Sep 26, 2006 at 10:01:06AM -0400, Dmitry Torokhov wrote:
> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >On Tue, Sep 26, 2006 at 09:20:17AM -0400, Dmitry Torokhov wrote:
> >> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >> >From: Greg Kroah-Hartman <gregkh@suse.de>
> >> >
> >> >This is needed for the network class devices in order to be able to
> >> >convert over to use struct device.
> >> >
> >>
> >> Greg,
> >>
> >> You keep pushing out patches that merge class devices and standard
> >> devices but you still have not shown the usefullness of this process.
> >
> >I have not?  This has been discussed before.
> >
> 
> Care to send me a pointer?

Ugh, somewhere back in the lkml archives, sorry for not being more
specific...

> >> Why do you feel the need to change internal kernel structures
> >> (ever-expanding struct device to accomodate everything that is in
> >> struct class_device) when it should be possible to simply adjust sysfs
> >> representation of the kernel tree (moving class devices into
> >> /sys/device/.. part of the tree)  to udev's liking and leave the rest
> >> of the kernel alone. You have seen the patch, only minor changes in
> >> driver/base/class.c are needed to accomplish the move.
> >
> >Think about suspend.  We want a single device tree so that the class
> >gets called when a device is about to be suspended so that it could shut
> >down the network queue in a common way, before the physical device is
> >called.
> 
> Why can't the device itself manage it? If you want to stub out the
> common parts just create a function like netdev_suspend and call it at
> appropriate time.

Because you would then need to add that function call to _every_ network
device driver.  This way, we do not need to do that as the class gets
called in the proper place before the device driver does.

In short, it makes it much simpler for the device driver writer, as it
is one less thing for them to get wrong (you can implement it once in
the input core, and have it work for all input devices, no need to touch
every input driver too.)

> >It's also needed if we want to have a single device tree in general.
> >class_device was the wrong thing and is really just a duplicate of
> >struct device in the first place (the driver core code implementing it
> >is pretty much just a cut and paste job.)
> 
> They complement each other. They are different and need different
> methods to operate.

Not they are not.  They really are just the same thing.

> > The fact that we were
> >arbritrary marking it different has caused problems (look at the mess
> >that input causes to the class_device code, that's just not nice).
> >
> 
> The only mess is that you refused to deepen the classification (i.e.
> have sub-classes). If input could be a parent class and
> mice/event/js/ts would grow from it it won't be such a mess.

But that is what we are now allowing you to do with devices.  The whole
sub-class stuff was tried and failed.  But in the end, it would almost
work with input devices, but then why not just make it a real device, so
you can use whatever heirachy you want to.  I would think that you would
welcome this change.

> Alternatively we could go with input vs input_intf classes if flat
> classification is a must. Anyway, I don't think we want to break udev
> again.

Flat classification is not a must at all, and with these changes, you
don't need it.  As an example, here's what the input tree looks like
when changed over:
$ tree /sys/class/input/
/sys/class/input/
|-- event0 -> ../../devices/platform/pcspkr/input0/event0
|-- event1 -> ../../devices/platform/i8042/serio4/input1/event1
|-- event2 -> ../../devices/platform/i8042/serio3/input2/event2
|-- input0 -> ../../devices/platform/pcspkr/input0
|-- input1 -> ../../devices/platform/i8042/serio4/input1
|-- input2 -> ../../devices/platform/i8042/serio3/input2
|-- mice -> ../../devices/virtual/input/mice
|-- mouse0 -> ../../devices/platform/i8042/serio3/input2/mouse0
`-- ts0 -> ../../devices/platform/i8042/serio3/input2/ts0

If you want, you can move any of these input devices anywhere in the
heirchay that you wish to do so.  A symlink will be automatically
created in /sys/class/input so that userspace tools like udev can find
all of the input devices (which is something that is needed), but there
is no more rigid heirachy being imposed on any one.  You are free to
move them at will, and no userspace tools will break as they will be
following the symlink instead.

> >Kay also has a long list of the reasons why, I think he's posted it here
> >before.  Kay, care to send that list again?
> >
> 
> Kay did send it and I agree with all his reasons as to why we need the
> move.

Great, they why are you objecting to these driver core patches?

> However I do not agree with your implementation.

Which implementation?  The one I did for the class subsystem?  Ok,
that's fine, your patch is still in my queue to look at, I'm not
ignoring it at all (had a bunch of "real life" work to get through this
last week and weekend, sorry, am still catching up.)

Don't worry, I'm not going to be pushing any input subsystem changes
wihout going through you first :)

These driver core patches are merely the needed functions for us to do
those input and other subsystem changes, they should not affect anything
of yours at all.

> >> I really disappointed that there was no discussion/review of the
> >> implementation at all.
> >
> >There has not been any real implementation yet, only a few patches added
> >to the core that add a few extra functionality to struct device to allow
> >class_device to move that way.
> 
> If there was no real discussion why you requesting these changes to be
> pulled in the mainline?

I didn't think these patches were controversial at all.  They have been
in -mm for a few months now and work just fine.

Is there anything specfic in these patches that you object to?  Becides
the virtual thing (I tried it with a flat /sys/devices/virtual/ tree,
and it was a mess, I like the extra directory for classification, but in
the end, it doesn't matter, we can change it with no problem, as no
userspace tool will break if you move devices around the /sys/devices/
tree.)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26 13:51                                                                 ` Dmitry Torokhov
@ 2006-09-26 14:26                                                                   ` Greg KH
  2006-09-26 17:15                                                                     ` Dmitry Torokhov
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26 14:26 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Kay Sievers

On Tue, Sep 26, 2006 at 09:51:04AM -0400, Dmitry Torokhov wrote:
> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >On Tue, Sep 26, 2006 at 09:24:15AM -0400, Dmitry Torokhov wrote:
> >> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >> >From: Greg Kroah-Hartman <gregkh@suse.de>
> >> >
> >> >This change creates a devices/virtual/CLASS_NAME tree for struct devices
> >> >that belong to a class, yet do not have a "real" struct device for a
> >> >parent.  It automatically creates the directories on the fly as needed.
> >> >
> >>
> >> Why do you need multiple virtual devices? All parentless class devices
> >> could grow from a single virtual device.
> >
> >They could, but it's a mess of a single directory if you do that.
> >Having /sys/devices/virtual/tty/ as a place for all tty virtual device
> >is nicer than /sys/devices/virtual/ as a single place for all of them
> >(mem, network, tty, misc, etc.)
> >
> 
> You supposed to use classes for classification, and devices to
> represent the tree so that would be /sys/class/tty/...

Yes, the symlink is still in /sys/class/tty, that hasn't gone away:
$ tree /sys/class/tty/
/sys/class/tty/
|-- console -> ../../devices/virtual/tty/console
|-- ptmx -> ../../devices/virtual/tty/ptmx
|-- tty -> ../../devices/virtual/tty/tty
|-- tty0 -> ../../devices/virtual/tty/tty0
|-- tty1 -> ../../devices/virtual/tty/tty1
|-- tty10 -> ../../devices/virtual/tty/tty10
...

It's just that /sys/devices/virtual would look very messy otherwise:
$ ls /sys/devices/virtual/
cpuid  input  mem  misc  msr  net  pci_bus  ppp  sound  tty  vc vtconsole

$ ls /sys/devices/virtual/*/ | wc -l
133

Also, that would mean that we could not have the name of a device
associated with a class to be the same as any other device associated
with any other class.  In the future that might be a problem, as our
namespace is only so big :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 13:46                                                       ` Greg KH
  2006-09-26 14:01                                                         ` Dmitry Torokhov
@ 2006-09-26 15:18                                                         ` Marcel Holtmann
  1 sibling, 0 replies; 72+ messages in thread
From: Marcel Holtmann @ 2006-09-26 15:18 UTC (permalink / raw)
  To: Greg KH
  Cc: Dmitry Torokhov, Kay Sievers, linux-kernel, Linus Torvalds,
	Andrew Morton

Hi Greg,

> > I really disappointed that there was no discussion/review of the
> > implementation at all.
> 
> There has not been any real implementation yet, only a few patches added
> to the core that add a few extra functionality to struct device to allow
> class_device to move that way.  The patches that move the subsystems
> over will be discussed (and some already have, like networking), when
> they are ready.  Right now most of that work is being done by Kay and
> myself as a proof of concept to make sure that we can do this properly
> and that userspace can handle it well.

if you look at the Bluetooth subsystem, it became real devices in the
2.6.18 release. I was using a platform device for the virtual and UART
based adapters with no parent, but I am gonna change this to the virtual
devices once it is upstream. It works beautiful and the /sys/class is
now only a fast entry point to find the devices.

Regards

Marcel



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 14:23                                                           ` Greg KH
@ 2006-09-26 17:10                                                             ` Dmitry Torokhov
  2006-09-27 14:40                                                             ` Pavel Machek
  1 sibling, 0 replies; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 17:10 UTC (permalink / raw)
  To: Greg KH; +Cc: Kay Sievers, linux-kernel, Linus Torvalds, Andrew Morton

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> On Tue, Sep 26, 2006 at 10:01:06AM -0400, Dmitry Torokhov wrote:
> > On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >On Tue, Sep 26, 2006 at 09:20:17AM -0400, Dmitry Torokhov wrote:
> > >> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >> Why do you feel the need to change internal kernel structures
> > >> (ever-expanding struct device to accomodate everything that is in
> > >> struct class_device) when it should be possible to simply adjust sysfs
> > >> representation of the kernel tree (moving class devices into
> > >> /sys/device/.. part of the tree)  to udev's liking and leave the rest
> > >> of the kernel alone. You have seen the patch, only minor changes in
> > >> driver/base/class.c are needed to accomplish the move.
> > >
> > >Think about suspend.  We want a single device tree so that the class
> > >gets called when a device is about to be suspended so that it could shut
> > >down the network queue in a common way, before the physical device is
> > >called.
> >
> > Why can't the device itself manage it? If you want to stub out the
> > common parts just create a function like netdev_suspend and call it at
> > appropriate time.
>
> Because you would then need to add that function call to _every_ network
> device driver.  This way, we do not need to do that as the class gets
> called in the proper place before the device driver does.
>
> In short, it makes it much simpler for the device driver writer, as it
> is one less thing for them to get wrong

Ok, you convinced me here, we might want to add start/pause methods to
the class devices.

> (you can implement it once in
> the input core, and have it work for all input devices, no need to touch
> every input driver too.)
>

I don't need it for input ;)

> > >It's also needed if we want to have a single device tree in general.
> > >class_device was the wrong thing and is really just a duplicate of
> > >struct device in the first place (the driver core code implementing it
> > >is pretty much just a cut and paste job.)
> >
> > They complement each other. They are different and need different
> > methods to operate.
>
> Not they are not.  They really are just the same thing.

I do not think so. struct device manages real hardware and converts
data flow into in-kernel format. class device represent abstractions
the kernel presents to userspace. They normally have a dev_t number
associated with them and a specific (or several) protocol/interface
for accessing them. You are trying to mix it all together. Why does a
PCI device need a dev_t? Or i8042? They don't. Do they need multiple
interfaces? No, they don't. Does a network device needs to know about
multiple power management levels? No, it does not.

I am pretty sure there is a way of getting class devices into suspend
without merging these 2 abstractions. In fact, why can't we have all
class devices stopped first and then suspend all "real" devices? Then
we'd have 2 lists, one for class devices and another for devices.

>
> > > The fact that we were
> > >arbritrary marking it different has caused problems (look at the mess
> > >that input causes to the class_device code, that's just not nice).
> > >
> >
> > The only mess is that you refused to deepen the classification (i.e.
> > have sub-classes). If input could be a parent class and
> > mice/event/js/ts would grow from it it won't be such a mess.
>
> But that is what we are now allowing you to do with devices.  The whole
> sub-class stuff was tried and failed.

Define failed? You just said you did not like it and ended up with
current code where individual class devices override in-kernel
interface (methods, attributes) specified by the class itself. In the
end we had to require updated version of udev anyway ;(

>  But in the end, it would almost
> work with input devices, but then why not just make it a real device, so
> you can use whatever heirachy you want to.  I would think that you would
> welcome this change.
>
> > Alternatively we could go with input vs input_intf classes if flat
> > classification is a must. Anyway, I don't think we want to break udev
> > again.
>
> Flat classification is not a must at all, and with these changes, you
> don't need it.  As an example, here's what the input tree looks like
> when changed over:
> $ tree /sys/class/input/
> /sys/class/input/
> |-- event0 -> ../../devices/platform/pcspkr/input0/event0
> |-- event1 -> ../../devices/platform/i8042/serio4/input1/event1
> |-- event2 -> ../../devices/platform/i8042/serio3/input2/event2
> |-- input0 -> ../../devices/platform/pcspkr/input0
> |-- input1 -> ../../devices/platform/i8042/serio4/input1
> |-- input2 -> ../../devices/platform/i8042/serio3/input2
> |-- mice -> ../../devices/virtual/input/mice
> |-- mouse0 -> ../../devices/platform/i8042/serio3/input2/mouse0
> `-- ts0 -> ../../devices/platform/i8042/serio3/input2/ts0
>
> If you want, you can move any of these input devices anywhere in the
> heirchay that you wish to do so.  A symlink will be automatically
> created in /sys/class/input so that userspace tools like udev can find
> all of the input devices (which is something that is needed), but there
> is no more rigid heirachy being imposed on any one.  You are free to
> move them at will, and no userspace tools will break as they will be
> following the symlink instead.
>

The classification is still flat. You are allowing to move and stack
devices within /sys/devices/... subtree but the /sys/class/... is
flat.

> > >Kay also has a long list of the reasons why, I think he's posted it here
> > >before.  Kay, care to send that list again?
> > >
> >
> > Kay did send it and I agree with all his reasons as to why we need the
> > move.
>
> Great, they why are you objecting to these driver core patches?
>

I do not agree with implementation that's why I object to the patches.

> > However I do not agree with your implementation.
>
> Which implementation?  The one I did for the class subsystem?  Ok,
> that's fine, your patch is still in my queue to look at, I'm not
> ignoring it at all (had a bunch of "real life" work to get through this
> last week and weekend, sorry, am still catching up.)
>
> Don't worry, I'm not going to be pushing any input subsystem changes
> wihout going through you first :)
>
> These driver core patches are merely the needed functions for us to do
> those input and other subsystem changes, they should not affect anything
> of yours at all.
>

I am not concerned with you making changes to input system, I question
the need of such sweeping changes throughout all subsystems. If my
patch (plus possibly adding 2nd list for class devices for
suspend/resume) is sufficient then we do not need these core patches
in mainline and don't need to change subsystems.

> > >> I really disappointed that there was no discussion/review of the
> > >> implementation at all.
> > >
> > >There has not been any real implementation yet, only a few patches added
> > >to the core that add a few extra functionality to struct device to allow
> > >class_device to move that way.
> >
> > If there was no real discussion why you requesting these changes to be
> > pulled in the mainline?
>
> I didn't think these patches were controversial at all.  They have been
> in -mm for a few months now and work just fine.
>

I do not think being in -mm is enough justification for changes to the
driver core design. they do not appear to break stuff, here I agree,
but it does not mean that the design is proper.

> Is there anything specfic in these patches that you object to?

Yes, everyting involving merging calss_device and device is a bit premature IMO.

>  Becides
> the virtual thing (I tried it with a flat /sys/devices/virtual/ tree,
> and it was a mess, I like the extra directory for classification, but in
> the end, it doesn't matter, we can change it with no problem, as no
> userspace tool will break if you move devices around the /sys/devices/
> tree.)
>

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 30/47] Driver core: create devices/virtual/ tree
  2006-09-26 14:26                                                                   ` Greg KH
@ 2006-09-26 17:15                                                                     ` Dmitry Torokhov
  0 siblings, 0 replies; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 17:15 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Kay Sievers

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> On Tue, Sep 26, 2006 at 09:51:04AM -0400, Dmitry Torokhov wrote:
> > On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >On Tue, Sep 26, 2006 at 09:24:15AM -0400, Dmitry Torokhov wrote:
> > >> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> > >> >From: Greg Kroah-Hartman <gregkh@suse.de>
> > >> >
> > >> >This change creates a devices/virtual/CLASS_NAME tree for struct devices
> > >> >that belong to a class, yet do not have a "real" struct device for a
> > >> >parent.  It automatically creates the directories on the fly as needed.
> > >> >
> > >>
> > >> Why do you need multiple virtual devices? All parentless class devices
> > >> could grow from a single virtual device.
> > >
> > >They could, but it's a mess of a single directory if you do that.
> > >Having /sys/devices/virtual/tty/ as a place for all tty virtual device
> > >is nicer than /sys/devices/virtual/ as a single place for all of them
> > >(mem, network, tty, misc, etc.)
> > >
> >
> > You supposed to use classes for classification, and devices to
> > represent the tree so that would be /sys/class/tty/...
>
> Yes, the symlink is still in /sys/class/tty, that hasn't gone away:
> $ tree /sys/class/tty/
> /sys/class/tty/
> |-- console -> ../../devices/virtual/tty/console
> |-- ptmx -> ../../devices/virtual/tty/ptmx
> |-- tty -> ../../devices/virtual/tty/tty
> |-- tty0 -> ../../devices/virtual/tty/tty0
> |-- tty1 -> ../../devices/virtual/tty/tty1
> |-- tty10 -> ../../devices/virtual/tty/tty10
> ...
>
> It's just that /sys/devices/virtual would look very messy otherwise:

It is supposed to be messy - it shows "physical" connections. If you
want to have nice separation look in /dev/class...

> $ ls /sys/devices/virtual/
> cpuid  input  mem  misc  msr  net  pci_bus  ppp  sound  tty  vc vtconsole
>
> $ ls /sys/devices/virtual/*/ | wc -l
> 133
>
> Also, that would mean that we could not have the name of a device
> associated with a class to be the same as any other device associated
> with any other class.  In the future that might be a problem, as our
> namespace is only so big :)
>

That is a better reason for separating it but I don;t think we have
clashes right now and as we converting more and more drivers to the
driver model your virtual directory should start shrinking, not
growing.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 41/47] drivers/base: check errors
  2006-09-26  5:38                                                                                 ` [PATCH 41/47] drivers/base: check errors Greg KH
  2006-09-26  5:38                                                                                   ` [PATCH 42/47] sysfs: add proper sysfs_init() prototype Greg KH
@ 2006-09-26 17:23                                                                                   ` Dmitry Torokhov
  2006-09-27  4:33                                                                                     ` Greg KH
  1 sibling, 1 reply; 72+ messages in thread
From: Dmitry Torokhov @ 2006-09-26 17:23 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Andrew Morton, Cornelia Huck, Greg Kroah-Hartman

On 9/26/06, Greg KH <greg@kroah.com> wrote:
> From: Andrew Morton <akpm@osdl.org>
>
> Add lots of return-value checking.
>
> +               if (error)
> +                       goto out;
> +               error = sysfs_create_link(&bus->devices.kobj,
> +                                               &dev->kobj, dev->bus_id);
> +               if (error)
> +                       goto out;
> +               error = sysfs_create_link(&dev->kobj,
> +                               &dev->bus->subsys.kset.kobj, "subsystem");
> +               if (error)
> +                       goto out;
> +               error = sysfs_create_link(&dev->kobj,
> +                               &dev->bus->subsys.kset.kobj, "bus");
>        }
> +out:
>        return error;

What about removing the links that were created if one of these calls fails?

-- 
Dmitry

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-26 12:34 ` [GIT PATCH] Driver Core patches for 2.6.18 Mike Galbraith
@ 2006-09-26 20:39   ` Greg KH
  2006-09-27  8:47     ` Mike Galbraith
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-26 20:39 UTC (permalink / raw)
  To: Mike Galbraith; +Cc: Linus Torvalds, Andrew Morton, linux-kernel

On Tue, Sep 26, 2006 at 12:34:05PM +0000, Mike Galbraith wrote:
> On Mon, 2006-09-25 at 22:37 -0700, Greg KH wrote:
> > Here are a bunch of driver core and sysfs patches and fixes for 2.6.18.
> 
> Hi,
> 
> Just as an fyi, these patches cause a ~regression on my P4/HT box.
> 
> Suspend stopped here working after 2.6.17.

Does 2.6.18 also have these problems?

If so, it's not due to these patches :)

> I haven't dug into why, but
> since then, I get a message "Class driver suspend failed for cpu0", and
> the suspend fails, but everything works fine afterward.  If I ignore the
> return of drv->suspend(), the box will suspend and resume just fine,
> both with this patch set and without.  (which is what I've been doing
> while waiting for it to fix itself or for my round toit to turn up)

What driver is controling cpu0?
What driver is failing the suspend?
What line did you have to change?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 41/47] drivers/base: check errors
  2006-09-26 17:23                                                                                   ` [PATCH 41/47] drivers/base: check errors Dmitry Torokhov
@ 2006-09-27  4:33                                                                                     ` Greg KH
  0 siblings, 0 replies; 72+ messages in thread
From: Greg KH @ 2006-09-27  4:33 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Greg KH, linux-kernel, Andrew Morton, Cornelia Huck

On Tue, Sep 26, 2006 at 01:23:34PM -0400, Dmitry Torokhov wrote:
> On 9/26/06, Greg KH <greg@kroah.com> wrote:
> >From: Andrew Morton <akpm@osdl.org>
> >
> >Add lots of return-value checking.
> >
> >+               if (error)
> >+                       goto out;
> >+               error = sysfs_create_link(&bus->devices.kobj,
> >+                                               &dev->kobj, dev->bus_id);
> >+               if (error)
> >+                       goto out;
> >+               error = sysfs_create_link(&dev->kobj,
> >+                               &dev->bus->subsys.kset.kobj, "subsystem");
> >+               if (error)
> >+                       goto out;
> >+               error = sysfs_create_link(&dev->kobj,
> >+                               &dev->bus->subsys.kset.kobj, "bus");
> >       }
> >+out:
> >       return error;
> 
> What about removing the links that were created if one of these calls fails?

Yes, that would be good, I think I have a patch in my queue that handles
that properly...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-27  8:47     ` Mike Galbraith
@ 2006-09-27  6:58       ` Rafael J. Wysocki
  2006-09-27 10:48         ` Mike Galbraith
  0 siblings, 1 reply; 72+ messages in thread
From: Rafael J. Wysocki @ 2006-09-27  6:58 UTC (permalink / raw)
  To: Mike Galbraith; +Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel

On Wednesday, 27 September 2006 10:47, Mike Galbraith wrote:
> On Tue, 2006-09-26 at 13:39 -0700, Greg KH wrote: 
> > On Tue, Sep 26, 2006 at 12:34:05PM +0000, Mike Galbraith wrote:
> > > On Mon, 2006-09-25 at 22:37 -0700, Greg KH wrote:
> > > > Here are a bunch of driver core and sysfs patches and fixes for 2.6.18.
> > > 
> > > Hi,
> > > 
> > > Just as an fyi, these patches cause a ~regression on my P4/HT box.
> > > 
> > > Suspend stopped here working after 2.6.17.
> > 
> > Does 2.6.18 also have these problems?
> 
> Suspend failure, yes, kill box on failure, no.
> 
> > If so, it's not due to these patches :)
> 
> The 'Mikie's box' killer is definitely somewhere in these patches.  I
> decided to test them after having just happened to have tried
> 2.6.18-rc7-mm1 to see if it the mm tree had fixed my suspend problem for
> me, and then seeing your post.  Since 2.6.18 with these patches went
> from ho-hum broke to ding-dong dead, I figured I should mention it.
> 
> > > I haven't dug into why, but
> > > since then, I get a message "Class driver suspend failed for cpu0", and
> > > the suspend fails, but everything works fine afterward.  If I ignore the
> > > return of drv->suspend(), the box will suspend and resume just fine,
> > > both with this patch set and without.  (which is what I've been doing
> > > while waiting for it to fix itself or for my round toit to turn up)
> > 
> > What driver is controling cpu0?
> > What driver is failing the suspend?
> 
> Dunno, see below.   
> 
> > What line did you have to change?
> 
> drivers/base/sys.c:409
> 
> Adding a WARN_ON() there wasn't particularly illuminating.  I enabled
> debugging (this is virgin 2.6.18), and get the following.  I see a
> problem I didn't notice before, see 'Hmm' below.  I have no idea if it
> has anything to do with box killer problem with patchset applied.

Please try to remove the acpi_cpufreq driver before the suspend.

If that works, please add your system configuration to the bugzilla entry at
http://bugzilla.kernel.org/show_bug.cgi?id=7188

Greetings,
Rafael


-- 
You never change things by fighting the existing reality.
		R. Buckminster Fuller

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-26 20:39   ` Greg KH
@ 2006-09-27  8:47     ` Mike Galbraith
  2006-09-27  6:58       ` Rafael J. Wysocki
  0 siblings, 1 reply; 72+ messages in thread
From: Mike Galbraith @ 2006-09-27  8:47 UTC (permalink / raw)
  To: Greg KH; +Cc: Linus Torvalds, Andrew Morton, linux-kernel

On Tue, 2006-09-26 at 13:39 -0700, Greg KH wrote: 
> On Tue, Sep 26, 2006 at 12:34:05PM +0000, Mike Galbraith wrote:
> > On Mon, 2006-09-25 at 22:37 -0700, Greg KH wrote:
> > > Here are a bunch of driver core and sysfs patches and fixes for 2.6.18.
> > 
> > Hi,
> > 
> > Just as an fyi, these patches cause a ~regression on my P4/HT box.
> > 
> > Suspend stopped here working after 2.6.17.
> 
> Does 2.6.18 also have these problems?

Suspend failure, yes, kill box on failure, no.

> If so, it's not due to these patches :)

The 'Mikie's box' killer is definitely somewhere in these patches.  I
decided to test them after having just happened to have tried
2.6.18-rc7-mm1 to see if it the mm tree had fixed my suspend problem for
me, and then seeing your post.  Since 2.6.18 with these patches went
from ho-hum broke to ding-dong dead, I figured I should mention it.

> > I haven't dug into why, but
> > since then, I get a message "Class driver suspend failed for cpu0", and
> > the suspend fails, but everything works fine afterward.  If I ignore the
> > return of drv->suspend(), the box will suspend and resume just fine,
> > both with this patch set and without.  (which is what I've been doing
> > while waiting for it to fix itself or for my round toit to turn up)
> 
> What driver is controling cpu0?
> What driver is failing the suspend?

Dunno, see below.   

> What line did you have to change?

drivers/base/sys.c:409

Adding a WARN_ON() there wasn't particularly illuminating.  I enabled
debugging (this is virgin 2.6.18), and get the following.  I see a
problem I didn't notice before, see 'Hmm' below.  I have no idea if it
has anything to do with box killer problem with patchset applied.

SysRq : Emergency Sync
Emergency Sync complete
ieee1394: Node removed: ID:BUS[0-00:1023]  GUID[000010dc003bb526]
PM: Removing info for ieee1394:000010dc003bb526-0
PM: Removing info for ieee1394:000010dc003bb526
PM: Removing info for ieee1394:fw-host0
eth1: removing device
ACPI: PCI interrupt for device 0000:02:00.0 disabled
Unloaded prism54 driver
PM: suspend-to-disk mode set to 'platform'
Stopping tasks: ==================================================================================================================|
Shrinking memory...  \b-\bdone (0 pages freed)
eeprom 2-0051: freeze
eeprom 0-0053: freeze
eeprom 0-0052: freeze
eeprom 0-0051: freeze
eeprom 0-0050: freeze
tuner 2-0060: freeze
tuner 2-0043: freeze
tveeprom 2-0050: freeze
ac97 0-0:CMI9761: freeze
ir-kbd-i2c 1-001a: freeze
sd 0:0:0:3: freeze
sd 0:0:0:2: freeze
sd 0:0:0:1: freeze
sd 0:0:0:0: freeze
i8042 i8042: freeze
usbhid 3-2:1.0: freeze
usb 3-2: freeze
usb-storage 3-1:1.0: freeze
usb 3-1: freeze
hub 5-0:1.0: freeze
usb usb5: freeze
hub 4-0:1.0: freeze
usb usb4: freeze
hub 3-0:1.0: freeze
usb usb3: freeze
hub 2-0:1.0: freeze
usb usb2: freeze
hub 1-0:1.0: freeze
usb usb1: freeze
ide-cdrom 1.1: freeze
ide-disk 1.0: freeze
ide-disk 0.0: freeze
serial8250 serial8250: freeze
vesafb vesafb.0: freeze
platform pcspkr: freeze
system 00:0c: freeze
system 00:0b: freeze
mpu401 00:0a: freeze
pnp: Device 00:0a disabled.
i8042 kbd 00:09: freeze
pnp 00:08: freeze
serial 00:07: freeze
pnp: Device 00:07 disabled.
pnp 00:06: freeze
pnp 00:05: freeze
pnp 00:04: freeze
pnp 00:03: freeze
pnp 00:02: freeze
system 00:01: freeze
pnp 00:00: freeze
pci 0000:02:0a.0: freeze
via-rhine 0000:02:09.0: freeze
saa7134 0000:02:03.0: freeze
bt878 0000:02:02.1: freeze
bttv 0000:02:02.0: freeze
pci 0000:02:00.0: freeze
pci 0000:01:00.1: freeze
pci 0000:01:00.0: freeze
Intel ICH 0000:00:1f.5: freeze
ACPI: PCI interrupt for device 0000:00:1f.5 disabled
i801_smbus 0000:00:1f.3: freeze
PIIX_IDE 0000:00:1f.1: freeze
pci 0000:00:1f.0: freeze
pci 0000:00:1e.0: freeze
ehci_hcd 0000:00:1d.7: freeze
ACPI: PCI interrupt for device 0000:00:1d.7 disabled
uhci_hcd 0000:00:1d.3: freeze
ACPI: PCI interrupt for device 0000:00:1d.3 disabled
uhci_hcd 0000:00:1d.2: freeze
ACPI: PCI interrupt for device 0000:00:1d.2 disabled
uhci_hcd 0000:00:1d.1: freeze
ACPI: PCI interrupt for device 0000:00:1d.1 disabled
uhci_hcd 0000:00:1d.0: freeze
ACPI: PCI interrupt for device 0000:00:1d.0 disabled
pci 0000:00:01.0: freeze
agpgart-intel 0000:00:00.0: freeze
acpi acpi: freeze
PM: snapshotting memory.
BUG: warning at drivers/base/sys.c:409/sysdev_suspend()
 [<b1003f65>] show_trace_log_lvl+0x179/0x18f
 [<b10045f4>] show_trace+0x12/0x14
 [<b1004690>] dump_stack+0x19/0x1b
 [<b124540f>] sysdev_suspend+0x282/0x2a1
 [<b1249798>] device_power_down+0x89/0x99
 [<b1037cd0>] swsusp_suspend+0x1b/0x95
 [<b10382c6>] pm_suspend_disk+0x5e/0x11a
 [<b1037244>] enter_state+0xe1/0x1b3
 [<b10373b9>] state_store+0xa3/0xac
 [<b10a2270>] subsys_attr_store+0x20/0x25
 [<b10a2594>] sysfs_write_file+0x82/0xbf
 [<b1063888>] vfs_write+0xa6/0x170
 [<b1063e65>] sys_write+0x3d/0x64
 [<b1002f17>] syscall_call+0x7/0xb
 [<a7e74b8e>] 0xa7e74b8e
Class driver suspend failed for cpu0
Could not power down device à^]H±: error -22
Hmm-------------------------^^^^^
(I had to edit this funky name out and copy/paste it back to convince evolution insert the file)
Some devices failed to power down, aborting suspend
acpi acpi: resuming
ACPI: Unable to turn cooling device [dfff5b80] 'on'
agpgart-intel 0000:00:00.0: resuming
pci 0000:00:01.0: resuming
uhci_hcd 0000:00:1d.0: resuming
PCI: Enabling device 0000:00:1d.0 (0000 -> 0001)
ACPI: PCI Interrupt 0000:00:1d.0[A] -> GSI 16 (level, low) -> IRQ 19
PCI: Setting latency timer of device 0000:00:1d.0 to 64
uhci_hcd 0000:00:1d.1: resuming
PCI: Enabling device 0000:00:1d.1 (0000 -> 0001)
ACPI: PCI Interrupt 0000:00:1d.1[B] -> GSI 19 (level, low) -> IRQ 20
PCI: Setting latency timer of device 0000:00:1d.1 to 64
uhci_hcd 0000:00:1d.2: resuming
PCI: Enabling device 0000:00:1d.2 (0000 -> 0001)
ACPI: PCI Interrupt 0000:00:1d.2[C] -> GSI 18 (level, low) -> IRQ 17
PCI: Setting latency timer of device 0000:00:1d.2 to 64
uhci_hcd 0000:00:1d.3: resuming
PCI: Enabling device 0000:00:1d.3 (0000 -> 0001)
ACPI: PCI Interrupt 0000:00:1d.3[A] -> GSI 16 (level, low) -> IRQ 19
PCI: Setting latency timer of device 0000:00:1d.3 to 64
ehci_hcd 0000:00:1d.7: resuming
PCI: Enabling device 0000:00:1d.7 (0000 -> 0002)
ACPI: PCI Interrupt 0000:00:1d.7[D] -> GSI 23 (level, low) -> IRQ 18
PCI: Setting latency timer of device 0000:00:1d.7 to 64
PM: Writing back config space on device 0000:00:1d.7 at offset f (was 400, writing 403)
PM: Writing back config space on device 0000:00:1d.7 at offset 4 (was 0, writing ea200000)
pci 0000:00:1e.0: resuming
PCI: Setting latency timer of device 0000:00:1e.0 to 64
pci 0000:00:1f.0: resuming
PIIX_IDE 0000:00:1f.1: resuming
i801_smbus 0000:00:1f.3: resuming
Intel ICH 0000:00:1f.5: resuming
PCI: Enabling device 0000:00:1f.5 (0000 -> 0003)
ACPI: PCI Interrupt 0000:00:1f.5[B] -> GSI 17 (level, low) -> IRQ 22
PCI: Setting latency timer of device 0000:00:1f.5 to 64
pci 0000:01:00.0: resuming
pci 0000:01:00.1: resuming
pci 0000:02:00.0: resuming
bttv 0000:02:02.0: resuming
bttv0: reset, reinitialize
bttv0: PLL: 28636363 => 35468950 .. ok
bt878 0000:02:02.1: resuming
saa7134 0000:02:03.0: resuming
via-rhine 0000:02:09.0: resuming
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
pci 0000:02:0a.0: resuming
pnp 00:00: resuming
system 00:01: resuming
pnp 00:02: resuming
pnp 00:03: resuming
pnp 00:04: resuming
pnp 00:05: resuming
pnp 00:06: resuming
serial 00:07: resuming
pnp: Device 00:07 activated.
pnp 00:08: resuming
i8042 kbd 00:09: resuming
pnp: Failed to activate device 00:09.
mpu401 00:0a: resuming
pnp: Device 00:0a activated.
system 00:0b: resuming
system 00:0c: resuming
platform pcspkr: resuming
vesafb vesafb.0: resuming
serial8250 serial8250: resuming
ide-disk 0.0: resuming
ide-disk 1.0: resuming
ide-cdrom 1.1: resuming
usb usb1: resuming
hub 1-0:1.0: resuming
usb usb2: resuming
hub 2-0:1.0: resuming
usb usb3: resuming
hub 3-0:1.0: resuming
usb usb4: resuming
hub 4-0:1.0: resuming
usb usb5: resuming
hub 5-0:1.0: resuming
usb 3-1: resuming
usb-storage 3-1:1.0: resuming
usb 3-2: resuming
usbhid 3-2:1.0: resuming
i8042 i8042: resuming
serio serio0: resuming
atkbd serio1: resuming
sd 0:0:0:0: resuming
sd 0:0:0:1: resuming
sd 0:0:0:2: resuming
sd 0:0:0:3: resuming
ir-kbd-i2c 1-001a: resuming
ac97 0-0:CMI9761: resuming
tveeprom 2-0050: resuming
tuner 2-0043: resuming
tuner 2-0060: resuming
eeprom 0-0050: resuming
eeprom 0-0051: resuming
eeprom 0-0052: resuming
eeprom 0-0053: resuming
eeprom 2-0051: resuming
Restarting tasks... done
Loaded prism54 driver, version 1.2
PCI: Enabling device 0000:02:00.0 (0010 -> 0012)
ACPI: PCI Interrupt 0000:02:00.0[A] -> GSI 16 (level, low) -> IRQ 19
PM: Adding info for ieee1394:fw-host0
ohci1394: fw-host0: OHCI-1394 1.0 (PCI): IRQ=[21]  MMIO=[ea004000-ea0047ff]  Max Packet=[2048]  IR/IT contexts=[8/8]



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-27  6:58       ` Rafael J. Wysocki
@ 2006-09-27 10:48         ` Mike Galbraith
  2006-09-27 13:03           ` Mike Galbraith
  0 siblings, 1 reply; 72+ messages in thread
From: Mike Galbraith @ 2006-09-27 10:48 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel

On Wed, 2006-09-27 at 08:58 +0200, Rafael J. Wysocki wrote:

> Please try to remove the acpi_cpufreq driver before the suspend.

Yeah, that's what's causing the suspend failure.  Thanks.

> If that works, please add your system configuration to the bugzilla entry at
> http://bugzilla.kernel.org/show_bug.cgi?id=7188

When my shiny new password arrives.

	-Mike


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-27 13:03           ` Mike Galbraith
@ 2006-09-27 11:42             ` Rafael J. Wysocki
  0 siblings, 0 replies; 72+ messages in thread
From: Rafael J. Wysocki @ 2006-09-27 11:42 UTC (permalink / raw)
  To: Mike Galbraith
  Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel, Dave Jones

On Wednesday, 27 September 2006 15:03, Mike Galbraith wrote:
> On Wed, 2006-09-27 at 10:48 +0000, Mike Galbraith wrote:
> > On Wed, 2006-09-27 at 08:58 +0200, Rafael J. Wysocki wrote:
> > 
> > > Please try to remove the acpi_cpufreq driver before the suspend.
> > 
> > Yeah, that's what's causing the suspend failure.  Thanks.
> 
> Followup:
> 
> Without the P-States driver (CONFIG_X86_ACPI_CPUFREQ) enabled, both
> virgin 2.6.18 and 2.6.18 with this patchset suspend/resume just fine,
> and cpufreq (p4_clockmod) works fine.
> 
> Why CONFIG_X86_ACPI_CPUFREQ blows my box out of the water with the
> patchset applied, I have no idea.

I think DaveJ is looking into it.

> Enabling suspend tracing didn't do 
> anything for me except cause fsck to check my drive, me to reset my
> clock, only to have fsck then check my drive yet again :)

Well, I've never used it. ;-)

Greetings,
Rafael


-- 
You never change things by fighting the existing reality.
		R. Buckminster Fuller

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [GIT PATCH] Driver Core patches for 2.6.18
  2006-09-27 10:48         ` Mike Galbraith
@ 2006-09-27 13:03           ` Mike Galbraith
  2006-09-27 11:42             ` Rafael J. Wysocki
  0 siblings, 1 reply; 72+ messages in thread
From: Mike Galbraith @ 2006-09-27 13:03 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Greg KH, Linus Torvalds, Andrew Morton, linux-kernel

On Wed, 2006-09-27 at 10:48 +0000, Mike Galbraith wrote:
> On Wed, 2006-09-27 at 08:58 +0200, Rafael J. Wysocki wrote:
> 
> > Please try to remove the acpi_cpufreq driver before the suspend.
> 
> Yeah, that's what's causing the suspend failure.  Thanks.

Followup:

Without the P-States driver (CONFIG_X86_ACPI_CPUFREQ) enabled, both
virgin 2.6.18 and 2.6.18 with this patchset suspend/resume just fine,
and cpufreq (p4_clockmod) works fine.

Why CONFIG_X86_ACPI_CPUFREQ blows my box out of the water with the
patchset applied, I have no idea.  Enabling suspend tracing didn't do
anything for me except cause fsck to check my drive, me to reset my
clock, only to have fsck then check my drive yet again :)

	-Mike


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 26/47] Driver core: add groups support to struct device
  2006-09-26 14:23                                                           ` Greg KH
  2006-09-26 17:10                                                             ` Dmitry Torokhov
@ 2006-09-27 14:40                                                             ` Pavel Machek
  1 sibling, 0 replies; 72+ messages in thread
From: Pavel Machek @ 2006-09-27 14:40 UTC (permalink / raw)
  To: Greg KH
  Cc: Dmitry Torokhov, Kay Sievers, linux-kernel, Linus Torvalds,
	Andrew Morton

Hi!

> > Why can't the device itself manage it? If you want to stub out the
> > common parts just create a function like netdev_suspend and call it at
> > appropriate time.
> 
> Because you would then need to add that function call to _every_ network
> device driver.  This way, we do not need to do that as the class gets
> called in the proper place before the device driver does.

I'm not sure this is good idea, it also has potential to break all the
network devices with one diff.

Some devices will be doing parts of class_suspend already, so I do not
think that some breakage will happen.

-- 
Thanks for all the (sleeping) penguins.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 44/47] PCI: enable driver multi-threaded probe
  2006-09-26  5:38                                                                                       ` [PATCH 44/47] PCI: enable driver multi-threaded probe Greg KH
  2006-09-26  5:38                                                                                         ` [PATCH 45/47] Driver core: Fix potential deadlock in driver core Greg KH
@ 2006-09-27 18:51                                                                                         ` Olaf Hering
  2006-09-29 23:32                                                                                           ` Greg KH
  1 sibling, 1 reply; 72+ messages in thread
From: Olaf Hering @ 2006-09-27 18:51 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 832 bytes --]

On Mon, Sep 25, Greg KH wrote:

> Use at your own risk!!!

I havent debugged it, but it seems to reorder the driver probing, offb
vs. nvidiafb (-bad, +good):

-Using unsupported 1024x768 NVDA,Display-A at 90020000, depth=8, pitch=1024
-PCI: Unable to reserve mem region #2:10000000@90000000 for device 0000:0a:00.0
-nvidiafb: cannot request PCI regions
+nvidiafb: Device ID: 10de0141 
+nvidiafb: CRTC0 analog found
+nvidiafb: CRTC1 analog found
+nvidiafb: Found OF EDID for head 1
+nvidiafb: EDID found from BUS1
+nvidiafb: EDID found from BUS2
+nvidiafb: CRTC 0 appears to have a CRT attached
+nvidiafb: Using CRT on CRTC 0
 Console: switching to colour frame buffer device 128x48
-fb0: Open Firmware frame buffer device on /pci@0,f0000000/NVDA,Parent@0/NVDA,Display-A@0
+nvidiafb: PCI nVidia NV14 framebuffer (64MB @ 0x90000000)


[-- Attachment #2: dmesg.sync.txt.gz --]
[-- Type: application/x-gunzip, Size: 5262 bytes --]

[-- Attachment #3: dmesg.async.txt.gz --]
[-- Type: application/x-gunzip, Size: 5689 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 44/47] PCI: enable driver multi-threaded probe
  2006-09-27 18:51                                                                                         ` [PATCH 44/47] PCI: enable driver multi-threaded probe Olaf Hering
@ 2006-09-29 23:32                                                                                           ` Greg KH
  2006-09-30  6:07                                                                                             ` Olaf Hering
  0 siblings, 1 reply; 72+ messages in thread
From: Greg KH @ 2006-09-29 23:32 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linux-kernel

On Wed, Sep 27, 2006 at 08:51:24PM +0200, Olaf Hering wrote:
> On Mon, Sep 25, Greg KH wrote:
> 
> > Use at your own risk!!!
> 
> I havent debugged it, but it seems to reorder the driver probing, offb
> vs. nvidiafb (-bad, +good):
> 
> -Using unsupported 1024x768 NVDA,Display-A at 90020000, depth=8, pitch=1024
> -PCI: Unable to reserve mem region #2:10000000@90000000 for device 0000:0a:00.0
> -nvidiafb: cannot request PCI regions
> +nvidiafb: Device ID: 10de0141 
> +nvidiafb: CRTC0 analog found
> +nvidiafb: CRTC1 analog found
> +nvidiafb: Found OF EDID for head 1
> +nvidiafb: EDID found from BUS1
> +nvidiafb: EDID found from BUS2
> +nvidiafb: CRTC 0 appears to have a CRT attached
> +nvidiafb: Using CRT on CRTC 0
>  Console: switching to colour frame buffer device 128x48
> -fb0: Open Firmware frame buffer device on /pci@0,f0000000/NVDA,Parent@0/NVDA,Display-A@0
> +nvidiafb: PCI nVidia NV14 framebuffer (64MB @ 0x90000000)

Hm, is things just getting registered out of order, so the wrong video
device is used by the kernel?  Or by userspace?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 44/47] PCI: enable driver multi-threaded probe
  2006-09-29 23:32                                                                                           ` Greg KH
@ 2006-09-30  6:07                                                                                             ` Olaf Hering
  0 siblings, 0 replies; 72+ messages in thread
From: Olaf Hering @ 2006-09-30  6:07 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

On Fri, Sep 29, Greg KH wrote:

> On Wed, Sep 27, 2006 at 08:51:24PM +0200, Olaf Hering wrote:
> > On Mon, Sep 25, Greg KH wrote:
> > 
> > > Use at your own risk!!!
> > 
> > I havent debugged it, but it seems to reorder the driver probing, offb
> > vs. nvidiafb (-bad, +good):
> > 
> > -Using unsupported 1024x768 NVDA,Display-A at 90020000, depth=8, pitch=1024
> > -PCI: Unable to reserve mem region #2:10000000@90000000 for device 0000:0a:00.0
> > -nvidiafb: cannot request PCI regions
> > +nvidiafb: Device ID: 10de0141 
> > +nvidiafb: CRTC0 analog found
> > +nvidiafb: CRTC1 analog found
> > +nvidiafb: Found OF EDID for head 1
> > +nvidiafb: EDID found from BUS1
> > +nvidiafb: EDID found from BUS2
> > +nvidiafb: CRTC 0 appears to have a CRT attached
> > +nvidiafb: Using CRT on CRTC 0
> >  Console: switching to colour frame buffer device 128x48
> > -fb0: Open Firmware frame buffer device on /pci@0,f0000000/NVDA,Parent@0/NVDA,Display-A@0
> > +nvidiafb: PCI nVidia NV14 framebuffer (64MB @ 0x90000000)
> 
> Hm, is things just getting registered out of order, so the wrong video
> device is used by the kernel?  Or by userspace?

noidea, offb seems to get initialized before nvidiafb.

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2006-09-30  6:07 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-26  5:37 [GIT PATCH] Driver Core patches for 2.6.18 Greg KH
2006-09-26  5:37 ` [PATCH 1/47] Documentation/ABI: devfs is not obsolete, but removed! Greg KH
2006-09-26  5:37   ` [PATCH 2/47] deprecate PHYSDEV* keys Greg KH
2006-09-26  5:37     ` [PATCH 3/47] class_device_create(): make fmt argument 'const char *' Greg KH
2006-09-26  5:37       ` [PATCH 4/47] device_create(): " Greg KH
2006-09-26  5:37         ` [PATCH 5/47] Driver core: add const to class_create Greg KH
2006-09-26  5:37           ` [PATCH 6/47] sysfs: Make poll behaviour consistent Greg KH
2006-09-26  5:37             ` [PATCH 7/47] Debugfs: kernel-doc fixes for debugfs Greg KH
2006-09-26  5:37               ` [PATCH 8/47] SYSFS: allow sysfs_create_link to create symlinks in the root of sysfs Greg KH
2006-09-26  5:37                 ` [PATCH 9/47] Suspend infrastructure cleanup and extension Greg KH
2006-09-26  5:37                   ` [PATCH 10/47] Suspend changes for PCI core Greg KH
2006-09-26  5:37                     ` [PATCH 11/47] make suspend quieter Greg KH
2006-09-26  5:37                       ` [PATCH 12/47] fix broken/dubious driver suspend() methods Greg KH
2006-09-26  5:37                         ` [PATCH 13/47] PM: define PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                           ` [PATCH 14/47] PM: PCI and IDE handle PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                             ` [PATCH 15/47] PM: video drivers and PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                               ` [PATCH 16/47] PM: USB HCDs use PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                                 ` [PATCH 17/47] PM: issue PM_EVENT_PRETHAW Greg KH
2006-09-26  5:37                                   ` [PATCH 18/47] updated Documentation/power/devices.txt Greg KH
2006-09-26  5:37                                     ` [PATCH 19/47] PM: update docs for writing .../power/state Greg KH
2006-09-26  5:37                                       ` [PATCH 20/47] PM: add kconfig option for deprecated .../power/state files Greg KH
2006-09-26  5:37                                         ` [PATCH 21/47] PM: schedule /sys/devices/.../power/state for removal Greg KH
2006-09-26  5:37                                           ` [PATCH 22/47] PM: no suspend_prepare() phase Greg KH
2006-09-26  5:37                                             ` [PATCH 23/47] PM: add /sys/power documentation to Documentation/ABI Greg KH
2006-09-26  5:37                                               ` [PATCH 24/47] PM: device_suspend/resume may sleep Greg KH
2006-09-26  5:37                                                 ` [PATCH 25/47] PM: platform_bus and late_suspend/early_resume Greg KH
2006-09-26  5:37                                                   ` [PATCH 26/47] Driver core: add groups support to struct device Greg KH
2006-09-26  5:37                                                     ` [PATCH 27/47] Driver core: allow devices in classes to have no parent Greg KH
2006-09-26  5:37                                                       ` [PATCH 28/47] Driver core: add ability for classes to handle devices properly Greg KH
2006-09-26  5:37                                                         ` [PATCH 29/47] Driver core: add device_rename function Greg KH
2006-09-26  5:37                                                           ` [PATCH 30/47] Driver core: create devices/virtual/ tree Greg KH
2006-09-26  5:37                                                             ` [PATCH 31/47] Class: add support for class interfaces for devices Greg KH
2006-09-26  5:37                                                               ` [PATCH 32/47] Driver core: add ability for devices to create and remove bin files Greg KH
2006-09-26  5:37                                                                 ` [PATCH 33/47] kobject: must_check fixes Greg KH
2006-09-26  5:37                                                                   ` [PATCH 34/47] sysfs_remove_bin_file: no return value, dump_stack on error Greg KH
2006-09-26  5:37                                                                     ` [PATCH 35/47] Driver core: fix comments in drivers/base/power/resume.c Greg KH
2006-09-26  5:37                                                                       ` [PATCH 36/47] Driver core: fixed add_bind_files() definition Greg KH
2006-09-26  5:37                                                                         ` [PATCH 37/47] add __must_check to device management code Greg KH
2006-09-26  5:37                                                                           ` [PATCH 38/47] add CONFIG_ENABLE_MUST_CHECK Greg KH
2006-09-26  5:37                                                                             ` [PATCH 39/47] v4l-dev2: handle __must_check Greg KH
2006-09-26  5:38                                                                               ` [PATCH 40/47] drivers/base: Platform notify needs to occur before drivers attach to the device Greg KH
2006-09-26  5:38                                                                                 ` [PATCH 41/47] drivers/base: check errors Greg KH
2006-09-26  5:38                                                                                   ` [PATCH 42/47] sysfs: add proper sysfs_init() prototype Greg KH
2006-09-26  5:38                                                                                     ` [PATCH 43/47] Driver Core: add ability for drivers to do a threaded probe Greg KH
2006-09-26  5:38                                                                                       ` [PATCH 44/47] PCI: enable driver multi-threaded probe Greg KH
2006-09-26  5:38                                                                                         ` [PATCH 45/47] Driver core: Fix potential deadlock in driver core Greg KH
2006-09-26  5:38                                                                                           ` [PATCH 46/47] Driver core: Remove unneeded routines from " Greg KH
2006-09-26  5:38                                                                                             ` [PATCH 47/47] Driver core: Don't call put methods while holding a spinlock Greg KH
2006-09-27 18:51                                                                                         ` [PATCH 44/47] PCI: enable driver multi-threaded probe Olaf Hering
2006-09-29 23:32                                                                                           ` Greg KH
2006-09-30  6:07                                                                                             ` Olaf Hering
2006-09-26 17:23                                                                                   ` [PATCH 41/47] drivers/base: check errors Dmitry Torokhov
2006-09-27  4:33                                                                                     ` Greg KH
2006-09-26 13:24                                                             ` [PATCH 30/47] Driver core: create devices/virtual/ tree Dmitry Torokhov
2006-09-26 13:41                                                               ` Greg KH
2006-09-26 13:51                                                                 ` Dmitry Torokhov
2006-09-26 14:26                                                                   ` Greg KH
2006-09-26 17:15                                                                     ` Dmitry Torokhov
2006-09-26 13:20                                                     ` [PATCH 26/47] Driver core: add groups support to struct device Dmitry Torokhov
2006-09-26 13:46                                                       ` Greg KH
2006-09-26 14:01                                                         ` Dmitry Torokhov
2006-09-26 14:23                                                           ` Greg KH
2006-09-26 17:10                                                             ` Dmitry Torokhov
2006-09-27 14:40                                                             ` Pavel Machek
2006-09-26 15:18                                                         ` Marcel Holtmann
2006-09-26 12:34 ` [GIT PATCH] Driver Core patches for 2.6.18 Mike Galbraith
2006-09-26 20:39   ` Greg KH
2006-09-27  8:47     ` Mike Galbraith
2006-09-27  6:58       ` Rafael J. Wysocki
2006-09-27 10:48         ` Mike Galbraith
2006-09-27 13:03           ` Mike Galbraith
2006-09-27 11:42             ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).