LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] Use attribute groups in struct device_type
@ 2007-03-10  6:37 Dmitry Torokhov
  2007-03-10  6:54 ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Torokhov @ 2007-03-10  6:37 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Andrew Morton

Greg,

Please consider applying the patch below. It switches struct device_type
to using attribute groups which os more flexible. I am using it in my
input class_device -> device conversion (which is 99% done btw).

I looked through -mm and the latest git and there does not seem to be
any users of struct device_type yet...

-- 
Dmitry

Driver core: use attribute groups in struct device_type

Attribute groups are more flexible than attribute lists
(an attribute list can be represented by anonymous group)
so switch struct device_type to use them.

Also rework attribute creation for devices so that they all
cleaned up properly in case of errors.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/base/core.c    |  115 +++++++++++++++++++++++++++++--------------------
 include/linux/device.h |    2 
 2 files changed, 70 insertions(+), 47 deletions(-)

Index: work/drivers/base/core.c
===================================================================
--- work.orig/drivers/base/core.c
+++ work/drivers/base/core.c
@@ -259,64 +259,95 @@ static ssize_t store_uevent(struct devic
 	return count;
 }
 
-static int device_add_groups(struct device *dev)
+static int device_add_attributes(struct device *dev,
+				 struct device_attribute *attrs)
+{
+	int error = 0;
+	int i;
+
+	if (attrs) {
+		for (i = 0; attr_name(attrs[i]); i++) {
+			error = device_create_file(dev, &attrs[i]);
+			if (error)
+				break;
+		}
+		if (error)
+			while (--i >= 0)
+				device_remove_file(dev, &attrs[i]);
+	}
+	return error;
+}
+
+static void device_remove_attributes(struct device *dev,
+				     struct device_attribute *attrs)
 {
 	int i;
+
+	if (attrs)
+		for (i = 0; attr_name(attrs[i]); i++)
+			device_remove_file(dev, &attrs[i]);
+}
+
+static int device_add_groups(struct device *dev,
+			     struct attribute_group **groups)
+{
 	int error = 0;
+	int i;
 
-	if (dev->groups) {
-		for (i = 0; dev->groups[i]; i++) {
-			error = sysfs_create_group(&dev->kobj, dev->groups[i]);
+	if (groups) {
+		for (i = 0; groups[i]; i++) {
+			error = sysfs_create_group(&dev->kobj, groups[i]);
 			if (error) {
 				while (--i >= 0)
-					sysfs_remove_group(&dev->kobj, dev->groups[i]);
-				goto out;
+					sysfs_remove_group(&dev->kobj, groups[i]);
+				break;
 			}
 		}
 	}
-out:
 	return error;
 }
 
-static void device_remove_groups(struct device *dev)
+static void device_remove_groups(struct device *dev,
+				 struct attribute_group **groups)
 {
 	int i;
-	if (dev->groups) {
-		for (i = 0; dev->groups[i]; i++) {
-			sysfs_remove_group(&dev->kobj, dev->groups[i]);
-		}
-	}
+
+	if (groups)
+		for (i = 0; groups[i]; i++)
+			sysfs_remove_group(&dev->kobj, groups[i]);
 }
 
 static int device_add_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
 	struct device_type *type = dev->type;
-	int error = 0;
-	int i;
+	int error;
 
-	if (class && 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 (class) {
+		error = device_add_attributes(dev, class->dev_attrs);
 		if (error)
-			while (--i >= 0)
-				device_remove_file(dev, &class->dev_attrs[i]);
+			return error;
 	}
 
-	if (type && type->attrs) {
-		for (i = 0; attr_name(type->attrs[i]); i++) {
-			error = device_create_file(dev, &type->attrs[i]);
-			if (error)
-				break;
-		}
+	if (type) {
+		error = device_add_groups(dev, type->groups);
 		if (error)
-			while (--i >= 0)
-				device_remove_file(dev, &type->attrs[i]);
+			goto err_remove_class_attrs;
 	}
 
+	error = device_add_groups(dev, dev->groups);
+	if (error)
+		goto err_remove_type_groups;
+
+	return 0;
+
+ err_remove_type_groups:
+	if (type)
+		device_remove_groups(dev, type->groups);
+ err_remove_class_attrs:
+	if (class)
+		device_remove_attributes(dev, class->dev_attrs);
+
 	return error;
 }
 
@@ -324,17 +355,14 @@ static void device_remove_attrs(struct d
 {
 	struct class *class = dev->class;
 	struct device_type *type = dev->type;
-	int i;
 
-	if (class && class->dev_attrs) {
-		for (i = 0; attr_name(class->dev_attrs[i]); i++)
-			device_remove_file(dev, &class->dev_attrs[i]);
-	}
+	device_remove_groups(dev, dev->groups);
 
-	if (type && type->attrs) {
-		for (i = 0; attr_name(type->attrs[i]); i++)
-			device_remove_file(dev, &type->attrs[i]);
-	}
+	if (type)
+		device_remove_groups(dev, type->groups);
+
+	if (class)
+		device_remove_attributes(dev, class->dev_attrs);
 }
 
 
@@ -599,8 +627,6 @@ 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)))
 		goto PMError;
 	if ((error = bus_add_device(dev)))
@@ -624,7 +650,7 @@ int device_add(struct device *dev)
 		up(&dev->class->sem);
 	}
  Done:
- 	kfree(class_name);
+	kfree(class_name);
 	put_device(dev);
 	return error;
  AttachError:
@@ -635,8 +661,6 @@ int device_add(struct device *dev)
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->bus_notifier,
 					     BUS_NOTIFY_DEL_DEVICE, dev);
-	device_remove_groups(dev);
- GroupError:
 	device_remove_attrs(dev);
  AttrsError:
 	if (dev->devt_attr) {
@@ -783,7 +807,6 @@ void device_del(struct device * dev)
 		up(&dev->class->sem);
 	}
 	device_remove_file(dev, &dev->uevent_attr);
-	device_remove_groups(dev);
 	device_remove_attrs(dev);
 	bus_remove_device(dev);
 
Index: work/include/linux/device.h
===================================================================
--- work.orig/include/linux/device.h
+++ work/include/linux/device.h
@@ -328,7 +328,7 @@ extern struct class_device *class_device
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
 struct device_type {
-	struct device_attribute *attrs;
+	struct attribute_group **groups;
 	int (*uevent)(struct device *dev, char **envp, int num_envp,
 		      char *buffer, int buffer_size);
 	void (*release)(struct device *dev);

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  6:37 [PATCH] Use attribute groups in struct device_type Dmitry Torokhov
@ 2007-03-10  6:54 ` Greg KH
  2007-03-10  6:55   ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Greg KH @ 2007-03-10  6:54 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Andrew Morton

On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> Greg,
> 
> Please consider applying the patch below. It switches struct device_type
> to using attribute groups which os more flexible. I am using it in my
> input class_device -> device conversion (which is 99% done btw).

Argh, I never sent you my version of that, did I?  Very sorry about
that, I was working on fixing up the device namespace issue first, which
isn't done yet :(

Anyway, my patch that did that is below, feel free to use it or not if
you want.

> I looked through -mm and the latest git and there does not seem to be
> any users of struct device_type yet...

Yes, the input patch below uses it and I have a block-device patch from
Kay in my tree that Andrew doesn't pull from (as it's usually really
messed up and I know to hide this kind of breakage from him...)

thanks,

greg k-h
--------------------

>From kay.sievers@vrfy.org  Wed Sep 13 22:59:01 2006
Date: Wed, 13 Sep 2006 16:11:35 +0200
From: Kay Sievers <kay.sievers@vrfy.org>
To: Greg KH <greg@kroah.com>
Subject: Driver core: convert input core to use struct device

From: Kay Sievers <kay.sievers@vrfy.org>

Converts from using struct "class_device" to "struct device" making
everything show up properly in /sys/devices/ with symlinks from the
/sys/class directory.

Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/hid/hid-input.c                           |    2 
 drivers/hwmon/hdaps.c                             |    2 
 drivers/input/evdev.c                             |   12 --
 drivers/input/input.c                             |  110 ++++++++++++----------
 drivers/input/joydev.c                            |   12 --
 drivers/input/joystick/a3d.c                      |    2 
 drivers/input/joystick/adi.c                      |    2 
 drivers/input/joystick/cobra.c                    |    2 
 drivers/input/joystick/gf2k.c                     |    2 
 drivers/input/joystick/grip.c                     |    2 
 drivers/input/joystick/grip_mp.c                  |    2 
 drivers/input/joystick/guillemot.c                |    2 
 drivers/input/joystick/iforce/iforce-main.c       |    4 
 drivers/input/joystick/magellan.c                 |    2 
 drivers/input/joystick/sidewinder.c               |    2 
 drivers/input/joystick/spaceball.c                |    2 
 drivers/input/joystick/spaceorb.c                 |    2 
 drivers/input/joystick/stinger.c                  |    2 
 drivers/input/joystick/tmdc.c                     |    2 
 drivers/input/joystick/twidjoy.c                  |    2 
 drivers/input/joystick/warrior.c                  |    2 
 drivers/input/keyboard/atkbd.c                    |    2 
 drivers/input/keyboard/corgikbd.c                 |    2 
 drivers/input/keyboard/lkkbd.c                    |    2 
 drivers/input/keyboard/newtonkbd.c                |    2 
 drivers/input/keyboard/spitzkbd.c                 |    2 
 drivers/input/keyboard/sunkbd.c                   |    2 
 drivers/input/keyboard/xtkbd.c                    |    2 
 drivers/input/misc/pcspkr.c                       |    2 
 drivers/input/misc/wistron_btns.c                 |    2 
 drivers/input/mouse/psmouse-base.c                |    2 
 drivers/input/mouse/sermouse.c                    |    2 
 drivers/input/mouse/vsxxxaa.c                     |    2 
 drivers/input/mousedev.c                          |   24 +---
 drivers/input/touchscreen/ads7846.c               |    2 
 drivers/input/touchscreen/corgi_ts.c              |    2 
 drivers/input/touchscreen/elo.c                   |    2 
 drivers/input/touchscreen/h3600_ts_input.c        |    2 
 drivers/input/touchscreen/penmount.c              |    2 
 drivers/input/tsdev.c                             |   12 --
 drivers/media/dvb/dvb-usb/dvb-usb-remote.c        |    2 
 drivers/media/video/bt8xx/bttv-input.c            |    2 
 drivers/media/video/cx88/cx88-input.c             |    2 
 drivers/media/video/saa7134/saa7134-input.c       |    2 
 drivers/media/video/usbvideo/konicawc.c           |    2 
 drivers/media/video/usbvideo/quickcam_messenger.c |    2 
 drivers/usb/input/acecad.c                        |    2 
 drivers/usb/input/aiptek.c                        |    2 
 drivers/usb/input/appletouch.c                    |    2 
 drivers/usb/input/ati_remote.c                    |    2 
 drivers/usb/input/ati_remote2.c                   |    2 
 drivers/usb/input/gtco.c                          |    2 
 drivers/usb/input/itmtouch.c                      |    2 
 drivers/usb/input/kbtab.c                         |    2 
 drivers/usb/input/keyspan_remote.c                |    2 
 drivers/usb/input/mtouchusb.c                     |    2 
 drivers/usb/input/powermate.c                     |    2 
 drivers/usb/input/touchkitusb.c                   |    2 
 drivers/usb/input/usbkbd.c                        |    2 
 drivers/usb/input/usbmouse.c                      |    2 
 drivers/usb/input/usbtouchscreen.c                |    2 
 drivers/usb/input/wacom_sys.c                     |    2 
 drivers/usb/input/xpad.c                          |    2 
 drivers/usb/input/yealink.c                       |    2 
 include/linux/input.h                             |    8 -
 net/bluetooth/hidp/core.c                         |    2 
 66 files changed, 146 insertions(+), 154 deletions(-)

--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -896,7 +896,7 @@ int hidinput_connect(struct hid_device *
 				input_dev->id.vendor  = hid->vendor;
 				input_dev->id.product = hid->product;
 				input_dev->id.version = hid->version;
-				input_dev->cdev.dev = hid->dev;
+				input_dev->d.parent = hid->dev;
 				hidinput->input = input_dev;
 				list_add_tail(&hidinput->list, &hid->inputs);
 			}
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -572,7 +572,7 @@ static int __init hdaps_init(void)
 
 	/* initialize the input class */
 	hdaps_idev->name = "hdaps";
-	hdaps_idev->cdev.dev = &pdev->dev;
+	hdaps_idev->d.parent = &pdev->dev;
 	hdaps_idev->evbit[0] = BIT(EV_ABS);
 	input_set_abs_params(hdaps_idev, ABS_X,
 			-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -620,7 +620,6 @@ static struct input_handle *evdev_connec
 					  const struct input_device_id *id)
 {
 	struct evdev *evdev;
-	struct class_device *cdev;
 	int minor;
 
 	for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
@@ -645,13 +644,9 @@ static struct input_handle *evdev_connec
 
 	evdev_table[minor] = evdev;
 
-	cdev = class_device_create(&input_class, &dev->cdev,
+	device_create(&input_class, &dev->d,
 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
-			dev->cdev.dev, evdev->name);
-
-	/* temporary symlink to keep userspace happy */
-	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
-			  evdev->name);
+			evdev->name);
 
 	return &evdev->handle;
 }
@@ -661,8 +656,7 @@ static void evdev_disconnect(struct inpu
 	struct evdev *evdev = handle->private;
 	struct evdev_list *list;
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
-	class_device_destroy(&input_class,
+	device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
 	evdev->exist = 0;
 
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -430,7 +430,7 @@ static void input_seq_print_bitmap(struc
 static int input_devices_seq_show(struct seq_file *seq, void *v)
 {
 	struct input_dev *dev = container_of(v, struct input_dev, node);
-	const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+	const char *path = kobject_get_path(&dev->d.kobj, GFP_KERNEL);
 	struct input_handle *handle;
 
 	seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
@@ -585,14 +585,16 @@ static inline void input_proc_exit(void)
 #endif
 
 #define INPUT_DEV_STRING_ATTR_SHOW(name)					\
-static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)	\
+static ssize_t input_dev_show_##name(struct device *dev,			\
+				     struct device_attribute *attr,		\
+				     char *buf)					\
 {										\
 	struct input_dev *input_dev = to_input_dev(dev);			\
 										\
 	return scnprintf(buf, PAGE_SIZE, "%s\n",				\
 			 input_dev->name ? input_dev->name : "");		\
 }										\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
 
 INPUT_DEV_STRING_ATTR_SHOW(name);
 INPUT_DEV_STRING_ATTR_SHOW(phys);
@@ -646,7 +648,9 @@ static int input_print_modalias(char *bu
 	return len;
 }
 
-static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
+static ssize_t input_dev_show_modalias(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
 {
 	struct input_dev *id = to_input_dev(dev);
 	ssize_t len;
@@ -655,13 +659,13 @@ static ssize_t input_dev_show_modalias(s
 
 	return min_t(int, len, PAGE_SIZE);
 }
-static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
 
 static struct attribute *input_dev_attrs[] = {
-	&class_device_attr_name.attr,
-	&class_device_attr_phys.attr,
-	&class_device_attr_uniq.attr,
-	&class_device_attr_modalias.attr,
+	&dev_attr_name.attr,
+	&dev_attr_phys.attr,
+	&dev_attr_uniq.attr,
+	&dev_attr_modalias.attr,
 	NULL
 };
 
@@ -670,12 +674,14 @@ static struct attribute_group input_dev_
 };
 
 #define INPUT_DEV_ID_ATTR(name)							\
-static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf)	\
+static ssize_t input_dev_show_id_##name(struct device *dev,			\
+					struct device_attribute *attr,		\
+					char *buf)				\
 {										\
 	struct input_dev *input_dev = to_input_dev(dev);			\
 	return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name);		\
 }										\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
 
 INPUT_DEV_ID_ATTR(bustype);
 INPUT_DEV_ID_ATTR(vendor);
@@ -683,10 +689,10 @@ INPUT_DEV_ID_ATTR(product);
 INPUT_DEV_ID_ATTR(version);
 
 static struct attribute *input_dev_id_attrs[] = {
-	&class_device_attr_bustype.attr,
-	&class_device_attr_vendor.attr,
-	&class_device_attr_product.attr,
-	&class_device_attr_version.attr,
+	&dev_attr_bustype.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_product.attr,
+	&dev_attr_version.attr,
 	NULL
 };
 
@@ -716,14 +722,16 @@ static int input_print_bitmap(char *buf,
 }
 
 #define INPUT_DEV_CAP_ATTR(ev, bm)						\
-static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf)	\
+static ssize_t input_dev_show_cap_##bm(struct device *dev,			\
+				       struct device_attribute *attr,		\
+				       char *buf)				\
 {										\
 	struct input_dev *input_dev = to_input_dev(dev);			\
 	int len = input_print_bitmap(buf, PAGE_SIZE,				\
 				     input_dev->bm##bit, ev##_MAX, 1);		\
 	return min_t(int, len, PAGE_SIZE);					\
 }										\
-static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
 
 INPUT_DEV_CAP_ATTR(EV, ev);
 INPUT_DEV_CAP_ATTR(KEY, key);
@@ -736,15 +744,15 @@ INPUT_DEV_CAP_ATTR(FF, ff);
 INPUT_DEV_CAP_ATTR(SW, sw);
 
 static struct attribute *input_dev_caps_attrs[] = {
-	&class_device_attr_ev.attr,
-	&class_device_attr_key.attr,
-	&class_device_attr_rel.attr,
-	&class_device_attr_abs.attr,
-	&class_device_attr_msc.attr,
-	&class_device_attr_led.attr,
-	&class_device_attr_snd.attr,
-	&class_device_attr_ff.attr,
-	&class_device_attr_sw.attr,
+	&dev_attr_ev.attr,
+	&dev_attr_key.attr,
+	&dev_attr_rel.attr,
+	&dev_attr_abs.attr,
+	&dev_attr_msc.attr,
+	&dev_attr_led.attr,
+	&dev_attr_snd.attr,
+	&dev_attr_ff.attr,
+	&dev_attr_sw.attr,
 	NULL
 };
 
@@ -753,9 +761,9 @@ static struct attribute_group input_dev_
 	.attrs	= input_dev_caps_attrs,
 };
 
-static void input_dev_release(struct class_device *class_dev)
+static void input_dev_release(struct device *d)
 {
-	struct input_dev *dev = to_input_dev(class_dev);
+	struct input_dev *dev = to_input_dev(d);
 
 	input_ff_destroy(dev);
 	kfree(dev);
@@ -842,16 +850,23 @@ static int input_add_uevent_modalias_var
 			return err;					\
 	} while (0)
 
-static int input_dev_uevent(struct class_device *cdev, char **envp,
+static int input_dev_uevent(struct device *d, char **envp,
 			    int num_envp, char *buffer, int buffer_size)
 {
-	struct input_dev *dev = to_input_dev(cdev);
+	struct input_dev *dev;
 	int i = 0;
 	int len = 0;
 
+	/* input is a single class, this is only valid for input_dev's */
+	if (strncmp("input", kobject_name(&d->kobj), 5) != 0)
+		return 0;
+
+	dev = to_input_dev(d);
+
 	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
 				dev->id.bustype, dev->id.vendor,
 				dev->id.product, dev->id.version);
+
 	if (dev->name)
 		INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
 	if (dev->phys)
@@ -885,8 +900,8 @@ static int input_dev_uevent(struct class
 
 struct class input_class = {
 	.name			= "input",
-	.release		= input_dev_release,
-	.uevent			= input_dev_uevent,
+	.dev_release		= input_dev_release,
+	.dev_uevent		= input_dev_uevent,
 };
 EXPORT_SYMBOL_GPL(input_class);
 
@@ -905,8 +920,8 @@ struct input_dev *input_allocate_device(
 
 	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
 	if (dev) {
-		dev->cdev.class = &input_class;
-		class_device_initialize(&dev->cdev);
+		device_initialize(&dev->d);
+		dev->d.class = &input_class;
 		mutex_init(&dev->mutex);
 		INIT_LIST_HEAD(&dev->h_list);
 		INIT_LIST_HEAD(&dev->node);
@@ -971,26 +986,27 @@ int input_register_device(struct input_d
 
 	list_add_tail(&dev->node, &input_dev_list);
 
-	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+	dev->d.class = &input_class;
+	snprintf(dev->d.bus_id, sizeof(dev->d.bus_id),
 		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
-	error = class_device_add(&dev->cdev);
+	error = device_add(&dev->d);
 	if (error)
 		return error;
 
-	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group);
+	error = sysfs_create_group(&dev->d.kobj, &input_dev_attr_group);
 	if (error)
 		goto fail1;
 
-	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+	error = sysfs_create_group(&dev->d.kobj, &input_dev_id_attr_group);
 	if (error)
 		goto fail2;
 
-	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+	error = sysfs_create_group(&dev->d.kobj, &input_dev_caps_attr_group);
 	if (error)
 		goto fail3;
 
-	path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+	path = kobject_get_path(&dev->d.kobj, GFP_KERNEL);
 	printk(KERN_INFO "input: %s as %s\n",
 		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
 	kfree(path);
@@ -1008,9 +1024,9 @@ int input_register_device(struct input_d
 
 	return 0;
 
- fail3:	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
- fail2:	sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
- fail1:	class_device_del(&dev->cdev);
+ fail3:	sysfs_remove_group(&dev->d.kobj, &input_dev_id_attr_group);
+ fail2:	sysfs_remove_group(&dev->d.kobj, &input_dev_attr_group);
+ fail1:	device_del(&dev->d);
 	return error;
 }
 EXPORT_SYMBOL(input_register_device);
@@ -1036,11 +1052,11 @@ void input_unregister_device(struct inpu
 
 	list_del_init(&dev->node);
 
-	sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
-	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
-	sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
+	sysfs_remove_group(&dev->d.kobj, &input_dev_caps_attr_group);
+	sysfs_remove_group(&dev->d.kobj, &input_dev_id_attr_group);
+	sysfs_remove_group(&dev->d.kobj, &input_dev_attr_group);
 
-	class_device_unregister(&dev->cdev);
+	device_unregister(&dev->d);
 
 	input_wakeup_procfs_readers();
 }
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -469,7 +469,6 @@ static struct input_handle *joydev_conne
 					   const struct input_device_id *id)
 {
 	struct joydev *joydev;
-	struct class_device *cdev;
 	int i, j, t, minor;
 
 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@@ -534,13 +533,9 @@ static struct input_handle *joydev_conne
 
 	joydev_table[minor] = joydev;
 
-	cdev = class_device_create(&input_class, &dev->cdev,
+	device_create(&input_class, &dev->d,
 			MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
-			dev->cdev.dev, joydev->name);
-
-	/* temporary symlink to keep userspace happy */
-	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
-			  joydev->name);
+			joydev->name);
 
 	return &joydev->handle;
 }
@@ -550,8 +545,7 @@ static void joydev_disconnect(struct inp
 	struct joydev *joydev = handle->private;
 	struct joydev_list *list;
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
-	class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
+	device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
 	joydev->exist = 0;
 
 	if (joydev->open) {
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -314,7 +314,7 @@ static int a3d_connect(struct gameport *
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
 	input_dev->id.product = a3d->mode;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &gameport->dev;
+	input_dev->d.parent = &gameport->dev;
 	input_dev->private = a3d;
 	input_dev->open = a3d_open;
 	input_dev->close = a3d_close;
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -424,7 +424,7 @@ static int adi_init_input(struct adi *ad
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
 	input_dev->id.product = adi->id;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &port->gameport->dev;
+	input_dev->d.parent = &port->gameport->dev;
 	input_dev->private = port;
 
 	input_dev->open = adi_open;
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -211,7 +211,7 @@ static int cobra_connect(struct gameport
 		input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
 		input_dev->id.product = 0x0008;
 		input_dev->id.version = 0x0100;
-		input_dev->cdev.dev = &gameport->dev;
+		input_dev->d.parent = &gameport->dev;
 		input_dev->private = cobra;
 
 		input_dev->open = cobra_open;
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -308,7 +308,7 @@ static int gf2k_connect(struct gameport 
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
 	input_dev->id.product = gf2k->id;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &gameport->dev;
+	input_dev->d.parent = &gameport->dev;
 	input_dev->private = gf2k;
 
 	input_dev->open = gf2k_open;
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -363,7 +363,7 @@ static int grip_connect(struct gameport 
 		input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
 		input_dev->id.product = grip->mode[i];
 		input_dev->id.version = 0x0100;
-		input_dev->cdev.dev = &gameport->dev;
+		input_dev->d.parent = &gameport->dev;
 		input_dev->private = grip;
 
 		input_dev->open = grip_open;
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -599,7 +599,7 @@ static int register_slot(int slot, struc
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
 	input_dev->id.product = 0x0100 + port->mode;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &grip->gameport->dev;
+	input_dev->d.parent = &grip->gameport->dev;
 	input_dev->private = grip;
 
 	input_dev->open = grip_open;
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -231,7 +231,7 @@ static int guillemot_connect(struct game
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
 	input_dev->id.product = guillemot_type[i].id;
 	input_dev->id.version = (int)data[14] << 8 | data[15];
-	input_dev->cdev.dev = &gameport->dev;
+	input_dev->d.parent = &gameport->dev;
 	input_dev->private = guillemot;
 
 	input_dev->open = guillemot_open;
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -287,13 +287,13 @@ int iforce_init_device(struct iforce *if
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
 	case IFORCE_USB:
 		input_dev->id.bustype = BUS_USB;
-		input_dev->cdev.dev = &iforce->usbdev->dev;
+		input_dev->d.parent = &iforce->usbdev->dev;
 		break;
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
 	case IFORCE_232:
 		input_dev->id.bustype = BUS_RS232;
-		input_dev->cdev.dev = &iforce->serio->dev;
+		input_dev->d.parent = &iforce->serio->dev;
 		break;
 #endif
 	}
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -168,7 +168,7 @@ static int magellan_connect(struct serio
 	input_dev->id.vendor = SERIO_MAGELLAN;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = magellan;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -751,7 +751,7 @@ static int sw_connect(struct gameport *g
 		input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
 		input_dev->id.product = sw->type;
 		input_dev->id.version = 0x0100;
-		input_dev->cdev.dev = &gameport->dev;
+		input_dev->d.parent = &gameport->dev;
 		input_dev->private = sw;
 
 		input_dev->open = sw_open;
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -226,7 +226,7 @@ static int spaceball_connect(struct seri
 	input_dev->id.vendor = SERIO_SPACEBALL;
 	input_dev->id.product = id;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = spaceball;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -183,7 +183,7 @@ static int spaceorb_connect(struct serio
 	input_dev->id.vendor = SERIO_SPACEORB;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = spaceorb;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -154,7 +154,7 @@ static int stinger_connect(struct serio 
 	input_dev->id.vendor = SERIO_STINGER;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = stinger;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -326,7 +326,7 @@ static int tmdc_setup_port(struct tmdc *
 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
 	input_dev->id.product = model->id;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &tmdc->gameport->dev;
+	input_dev->d.parent = &tmdc->gameport->dev;
 	input_dev->private = tmdc;
 
 	input_dev->open = tmdc_open;
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -205,7 +205,7 @@ static int twidjoy_connect(struct serio 
 	input_dev->id.vendor = SERIO_TWIDJOY;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = twidjoy;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -160,7 +160,7 @@ static int warrior_connect(struct serio 
 	input_dev->id.vendor = SERIO_WARRIOR;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = warrior;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -884,7 +884,7 @@ static void atkbd_set_device_attrs(struc
 	input_dev->id.version = atkbd->id;
 	input_dev->event = atkbd_event;
 	input_dev->private = atkbd;
-	input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
+	input_dev->d.parent = &atkbd->ps2dev.serio->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
 
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -323,7 +323,7 @@ static int __init corgikbd_probe(struct 
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &pdev->dev;
+	input_dev->d.parent = &pdev->dev;
 	input_dev->private = corgikbd;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -666,7 +666,7 @@ lkkbd_connect (struct serio *serio, stru
 	input_dev->id.vendor = SERIO_LKKBD;
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->event = lkkbd_event;
 	input_dev->private = lk;
 
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -104,7 +104,7 @@ static int nkbd_connect(struct serio *se
 	input_dev->id.vendor = SERIO_NEWTON;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = nkbd;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -375,7 +375,7 @@ static int __init spitzkbd_probe(struct 
 	input_dev->private = spitzkbd;
 	input_dev->name = "Spitz Keyboard";
 	input_dev->phys = spitzkbd->phys;
-	input_dev->cdev.dev = &dev->dev;
+	input_dev->d.parent = &dev->dev;
 
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor = 0x0001;
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -271,7 +271,7 @@ static int sunkbd_connect(struct serio *
 	input_dev->id.vendor  = SERIO_SUNKBD;
 	input_dev->id.product = sunkbd->type;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = sunkbd;
 	input_dev->event = sunkbd_event;
 
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -108,7 +108,7 @@ static int xtkbd_connect(struct serio *s
 	input_dev->id.vendor  = 0x0001;
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = xtkbd;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -78,7 +78,7 @@ static int __devinit pcspkr_probe(struct
 	pcspkr_dev->id.vendor = 0x001f;
 	pcspkr_dev->id.product = 0x0001;
 	pcspkr_dev->id.version = 0x0100;
-	pcspkr_dev->cdev.dev = &dev->dev;
+	pcspkr_dev->d.parent = &dev->dev;
 
 	pcspkr_dev->evbit[0] = BIT(EV_SND);
 	pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -473,7 +473,7 @@ static int __devinit setup_input_dev(voi
 	input_dev->name = "Wistron laptop buttons";
 	input_dev->phys = "wistron/input0";
 	input_dev->id.bustype = BUS_HOST;
-	input_dev->cdev.dev = &wistron_device->dev;
+	input_dev->d.parent = &wistron_device->dev;
 
 	for (key = keymap; key->type != KE_END; key++) {
 		if (key->type == KE_KEY) {
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -1063,7 +1063,7 @@ static int psmouse_switch_protocol(struc
 	struct input_dev *input_dev = psmouse->dev;
 
 	input_dev->private = psmouse;
-	input_dev->cdev.dev = &psmouse->ps2dev.serio->dev;
+	input_dev->d.parent = &psmouse->ps2dev.serio->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -258,7 +258,7 @@ static int sermouse_connect(struct serio
 	input_dev->id.vendor  = sermouse->type;
 	input_dev->id.product = c;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -508,7 +508,7 @@ vsxxxaa_connect (struct serio *serio, st
 	input_dev->name = mouse->name;
 	input_dev->phys = mouse->phys;
 	input_dev->id.bustype = BUS_RS232;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = mouse;
 
 	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -628,7 +628,6 @@ static struct input_handle *mousedev_con
 					     const struct input_device_id *id)
 {
 	struct mousedev *mousedev;
-	struct class_device *cdev;
 	int minor = 0;
 
 	for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
@@ -656,13 +655,9 @@ static struct input_handle *mousedev_con
 
 	mousedev_table[minor] = mousedev;
 
-	cdev = class_device_create(&input_class, &dev->cdev,
+	device_create(&input_class, &dev->d,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
-			dev->cdev.dev, mousedev->name);
-
-	/* temporary symlink to keep userspace happy */
-	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
-			  mousedev->name);
+			mousedev->name);
 
 	return &mousedev->handle;
 }
@@ -672,8 +667,7 @@ static void mousedev_disconnect(struct i
 	struct mousedev *mousedev = handle->private;
 	struct mousedev_list *list;
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
-	class_device_destroy(&input_class,
+	device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
 	mousedev->exist = 0;
 
@@ -738,7 +732,7 @@ static int psaux_registered;
 
 static int __init mousedev_init(void)
 {
-	struct class_device *cdev;
+	struct device *dev;
 	int error;
 
 	error = input_register_handler(&mousedev_handler);
@@ -752,11 +746,11 @@ static int __init mousedev_init(void)
 	mousedev_mix.exist = 1;
 	mousedev_mix.minor = MOUSEDEV_MIX;
 
-	cdev = class_device_create(&input_class, NULL,
-			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
-	if (IS_ERR(cdev)) {
+	dev = device_create(&input_class, NULL,
+			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), "mice");
+	if (IS_ERR(dev)) {
 		input_unregister_handler(&mousedev_handler);
-		return PTR_ERR(cdev);
+		return PTR_ERR(dev);
 	}
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -779,7 +773,7 @@ static void __exit mousedev_exit(void)
 	if (psaux_registered)
 		misc_deregister(&psaux_mouse);
 #endif
-	class_device_destroy(&input_class,
+	device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
 	input_unregister_handler(&mousedev_handler);
 }
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -897,7 +897,7 @@ static int __devinit ads7846_probe(struc
 
 	input_dev->name = "ADS784x Touchscreen";
 	input_dev->phys = ts->phys;
-	input_dev->cdev.dev = &spi->dev;
+	input_dev->d.parent = &spi->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -300,7 +300,7 @@ static int __init corgits_probe(struct p
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0002;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &pdev->dev;
+	input_dev->d.parent = &pdev->dev;
 	input_dev->private = corgi_ts;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -319,7 +319,7 @@ static int elo_connect(struct serio *ser
 	input_dev->id.vendor = SERIO_ELO;
 	input_dev->id.product = elo->id;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -367,7 +367,7 @@ static int h3600ts_connect(struct serio 
 	input_dev->id.vendor = SERIO_H3600;
 	input_dev->id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 	input_dev->private = ts;
 
 	input_dev->event = h3600ts_event;
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -112,7 +112,7 @@ static int pm_connect(struct serio *seri
 	input_dev->id.vendor = SERIO_PENMOUNT;
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
-	input_dev->cdev.dev = &serio->dev;
+	input_dev->d.parent = &serio->dev;
 
         input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
         input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -375,7 +375,6 @@ static struct input_handle *tsdev_connec
 					  const struct input_device_id *id)
 {
 	struct tsdev *tsdev;
-	struct class_device *cdev;
 	int minor, delta;
 
 	for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++);
@@ -415,13 +414,9 @@ static struct input_handle *tsdev_connec
 
 	tsdev_table[minor] = tsdev;
 
-	cdev = class_device_create(&input_class, &dev->cdev,
+	device_create(&input_class, &dev->d,
 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
-			dev->cdev.dev, tsdev->name);
-
-	/* temporary symlink to keep userspace happy */
-	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
-			  tsdev->name);
+			tsdev->name);
 
 	return &tsdev->handle;
 }
@@ -431,8 +426,7 @@ static void tsdev_disconnect(struct inpu
 	struct tsdev *tsdev = handle->private;
 	struct tsdev_list *list;
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
-	class_device_destroy(&input_class,
+	device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
 	tsdev->exist = 0;
 
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -112,7 +112,7 @@ int dvb_usb_remote_init(struct dvb_usb_d
 	input_dev->name = "IR-receiver inside an USB DVB receiver";
 	input_dev->phys = d->rc_phys;
 	usb_to_input_id(d->udev, &input_dev->id);
-	input_dev->cdev.dev = &d->udev->dev;
+	input_dev->d.parent = &d->udev->dev;
 
 	/* set the bits for the keys */
 	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -313,7 +313,7 @@ int bttv_input_init(struct bttv *btv)
 		input_dev->id.vendor  = btv->c.pci->vendor;
 		input_dev->id.product = btv->c.pci->device;
 	}
-	input_dev->cdev.dev = &btv->c.pci->dev;
+	input_dev->d.parent = &btv->c.pci->dev;
 
 	btv->remote = ir;
 	bttv_ir_start(btv, ir);
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -328,7 +328,7 @@ int cx88_ir_init(struct cx88_core *core,
 		input_dev->id.vendor = pci->vendor;
 		input_dev->id.product = pci->device;
 	}
-	input_dev->cdev.dev = &pci->dev;
+	input_dev->d.parent = &pci->dev;
 	/* record handles to ourself */
 	ir->core = core;
 	core->ir = ir;
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -373,7 +373,7 @@ int saa7134_input_init1(struct saa7134_d
 		input_dev->id.vendor  = dev->pci->vendor;
 		input_dev->id.product = dev->pci->device;
 	}
-	input_dev->cdev.dev = &dev->pci->dev;
+	input_dev->d.parent = &dev->pci->dev;
 
 	dev->remote = ir;
 	saa7134_ir_start(dev, ir);
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -236,7 +236,7 @@ static void konicawc_register_input(stru
 	input_dev->name = "Konicawc snapshot button";
 	input_dev->phys = cam->input_physname;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &dev->dev;
+	input_dev->d.parent = &dev->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY);
 	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -100,7 +100,7 @@ static void qcm_register_input(struct qc
 	input_dev->name = "QCM button";
 	input_dev->phys = cam->input_physname;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &dev->dev;
+	input_dev->d.parent = &dev->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY);
 	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -178,7 +178,7 @@ static int usb_acecad_probe(struct usb_i
 	input_dev->name = acecad->name;
 	input_dev->phys = acecad->phys;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = acecad;
 
 	input_dev->open = usb_acecad_open;
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -2043,7 +2043,7 @@ aiptek_probe(struct usb_interface *intf,
 	inputdev->name = "Aiptek";
 	inputdev->phys = aiptek->features.usbPath;
 	usb_to_input_id(usbdev, &inputdev->id);
-	inputdev->cdev.dev = &intf->dev;
+	inputdev->d.parent = &intf->dev;
 	inputdev->private = aiptek;
 	inputdev->open = aiptek_open;
 	inputdev->close = aiptek_close;
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -589,7 +589,7 @@ static int atp_probe(struct usb_interfac
 	input_dev->name = "appletouch";
 	input_dev->phys = dev->phys;
 	usb_to_input_id(dev->udev, &input_dev->id);
-	input_dev->cdev.dev = &iface->dev;
+	input_dev->d.parent = &iface->dev;
 
 	input_dev->private = dev;
 	input_dev->open = atp_open;
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -661,7 +661,7 @@ static void ati_remote_input_init(struct
 	idev->phys = ati_remote->phys;
 
 	usb_to_input_id(ati_remote->udev, &idev->id);
-	idev->cdev.dev = &ati_remote->udev->dev;
+	idev->d.parent = &ati_remote->udev->dev;
 }
 
 static int ati_remote_initialize(struct ati_remote *ati_remote)
--- a/drivers/usb/input/ati_remote2.c
+++ b/drivers/usb/input/ati_remote2.c
@@ -330,7 +330,7 @@ static int ati_remote2_input_init(struct
 	idev->phys = ar2->phys;
 
 	usb_to_input_id(ar2->udev, &idev->id);
-	idev->cdev.dev = &ar2->udev->dev;
+	idev->d.parent = &ar2->udev->dev;
 
 	i = input_register_device(idev);
 	if (i)
--- a/drivers/usb/input/gtco.c
+++ b/drivers/usb/input/gtco.c
@@ -1007,7 +1007,7 @@ static int gtco_probe(struct usb_interfa
 
 	/* Set input device required ID information */
 	usb_to_input_id(device->usbdev, &device->inputdevice->id);
-	inputdev->cdev.dev = &usbinterface->dev;
+	inputdev->d.parent = &usbinterface->dev;
 
 	/* Setup the URB, it will be posted later on open of input device */
 	endpoint = &usbinterface->altsetting[0].endpoint[0].desc;
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -186,7 +186,7 @@ static int itmtouch_probe(struct usb_int
 	input_dev->name = itmtouch->name;
 	input_dev->phys = itmtouch->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = itmtouch;
 
 	input_dev->open = itmtouch_open;
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -145,7 +145,7 @@ static int kbtab_probe(struct usb_interf
 	input_dev->name = "KB Gear Tablet";
 	input_dev->phys = kbtab->phys;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = kbtab;
 
 	input_dev->open = kbtab_open;
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -495,7 +495,7 @@ static int keyspan_probe(struct usb_inte
 	input_dev->name = remote->name;
 	input_dev->phys = remote->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &interface->dev;
+	input_dev->d.parent = &interface->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
 	for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -233,7 +233,7 @@ static int mtouchusb_probe(struct usb_in
 	input_dev->name = mtouch->name;
 	input_dev->phys = mtouch->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = mtouch;
 
 	input_dev->open = mtouchusb_open;
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -359,7 +359,7 @@ static int powermate_probe(struct usb_in
 
 	input_dev->phys = pm->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = pm;
 
 	input_dev->event = powermate_input_event;
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -314,7 +314,7 @@ static int touchkit_probe(struct usb_int
 	input_dev->name = touchkit->name;
 	input_dev->phys = touchkit->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = touchkit;
 	input_dev->open = touchkit_open;
 	input_dev->close = touchkit_close;
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -273,7 +273,7 @@ static int usb_kbd_probe(struct usb_inte
 	input_dev->name = kbd->name;
 	input_dev->phys = kbd->phys;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &iface->dev;
+	input_dev->d.parent = &iface->dev;
 	input_dev->private = kbd;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -170,7 +170,7 @@ static int usb_mouse_probe(struct usb_in
 	input_dev->name = mouse->name;
 	input_dev->phys = mouse->phys;
 	usb_to_input_id(dev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -740,7 +740,7 @@ static int usbtouch_probe(struct usb_int
 	input_dev->name = usbtouch->name;
 	input_dev->phys = usbtouch->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = usbtouch;
 	input_dev->open = usbtouch_open;
 	input_dev->close = usbtouch_close;
--- a/drivers/usb/input/wacom_sys.c
+++ b/drivers/usb/input/wacom_sys.c
@@ -229,7 +229,7 @@ static int wacom_probe(struct usb_interf
 	wacom->wacom_wac = wacom_wac;
 	usb_to_input_id(dev, &input_dev->id);
 
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = wacom;
 	input_dev->open = wacom_open;
 	input_dev->close = wacom_close;
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -344,7 +344,7 @@ static int xpad_probe(struct usb_interfa
 	input_dev->name = xpad_device[i].name;
 	input_dev->phys = xpad->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 	input_dev->private = xpad;
 	input_dev->open = xpad_open;
 	input_dev->close = xpad_close;
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -937,7 +937,7 @@ static int usb_probe(struct usb_interfac
 	input_dev->name = nfo->name;
 	input_dev->phys = yld->phys;
 	usb_to_input_id(udev, &input_dev->id);
-	input_dev->cdev.dev = &intf->dev;
+	input_dev->d.parent = &intf->dev;
 
 	input_dev->private = yld;
 	input_dev->open = input_open;
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -995,12 +995,12 @@ struct input_dev {
 	struct mutex mutex;	/* serializes open and close operations */
 	unsigned int users;
 
-	struct class_device cdev;
+	struct device d;
 
 	struct list_head	h_list;
 	struct list_head	node;
 };
-#define to_input_dev(d) container_of(d, struct input_dev, cdev)
+#define to_input_dev(dev) container_of(dev, struct input_dev, d)
 
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
@@ -1113,12 +1113,12 @@ void input_free_device(struct input_dev 
 
 static inline struct input_dev *input_get_device(struct input_dev *dev)
 {
-	return to_input_dev(class_device_get(&dev->cdev));
+	return to_input_dev(get_device(&dev->d));
 }
 
 static inline void input_put_device(struct input_dev *dev)
 {
-	class_device_put(&dev->cdev);
+	put_device(&dev->d);
 }
 
 int input_register_device(struct input_dev *);
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -663,7 +663,7 @@ static inline void hidp_setup_input(stru
 		input->relbit[0] |= BIT(REL_WHEEL);
 	}
 
-	input->cdev.dev = hidp_get_device(session);
+	input->d.parent = hidp_get_device(session);
 
 	input->event = hidp_input_event;
 

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  6:54 ` Greg KH
@ 2007-03-10  6:55   ` Greg KH
  2007-03-10  7:12     ` Dmitry Torokhov
  0 siblings, 1 reply; 7+ messages in thread
From: Greg KH @ 2007-03-10  6:55 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Andrew Morton

On Fri, Mar 09, 2007 at 10:54:43PM -0800, Greg KH wrote:
> On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> > Greg,
> > 
> > Please consider applying the patch below. It switches struct device_type
> > to using attribute groups which os more flexible. I am using it in my
> > input class_device -> device conversion (which is 99% done btw).
> 
> Argh, I never sent you my version of that, did I?  Very sorry about
> that, I was working on fixing up the device namespace issue first, which
> isn't done yet :(
> 
> Anyway, my patch that did that is below, feel free to use it or not if
> you want.
> 
> > I looked through -mm and the latest git and there does not seem to be
> > any users of struct device_type yet...
> 
> Yes, the input patch below uses it and I have a block-device patch from
> Kay in my tree that Andrew doesn't pull from (as it's usually really
> messed up and I know to hide this kind of breakage from him...)

Oops, that patch didn't use it, this follow-on patch from Kay uses them.

thanks,

greg k-h

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

>From kay.sievers@novell.com Sat Oct  7 13:11:36 2006
From: Kay Sievers <kay.sievers@novell.com>
Date: Sat, 07 Oct 2006 21:54:55 +0200
Subject: Driver core: swich input_device to device_type
Message-Id: <1160250895.4235.23.camel@localhost>


Signed-off-by: Kay Sievers <kay.sievers@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/input/input.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -853,16 +853,10 @@ static int input_add_uevent_modalias_var
 static int input_dev_uevent(struct device *d, char **envp,
 			    int num_envp, char *buffer, int buffer_size)
 {
-	struct input_dev *dev;
+	struct input_dev *dev = to_input_dev(d);
 	int i = 0;
 	int len = 0;
 
-	/* input is a single class, this is only valid for input_dev's */
-	if (strncmp("input", kobject_name(&d->kobj), 5) != 0)
-		return 0;
-
-	dev = to_input_dev(d);
-
 	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
 				dev->id.bustype, dev->id.vendor,
 				dev->id.product, dev->id.version);
@@ -898,10 +892,13 @@ static int input_dev_uevent(struct devic
 	return 0;
 }
 
+struct device_type input_dev_type = {
+	.uevent 		= input_dev_uevent,
+	.release 		= input_dev_release,
+};
+
 struct class input_class = {
 	.name			= "input",
-	.dev_release		= input_dev_release,
-	.dev_uevent		= input_dev_uevent,
 };
 EXPORT_SYMBOL_GPL(input_class);
 
@@ -922,6 +919,7 @@ struct input_dev *input_allocate_device(
 	if (dev) {
 		device_initialize(&dev->d);
 		dev->d.class = &input_class;
+		dev->d.type = &input_dev_type;
 		mutex_init(&dev->mutex);
 		INIT_LIST_HEAD(&dev->h_list);
 		INIT_LIST_HEAD(&dev->node);

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  6:55   ` Greg KH
@ 2007-03-10  7:12     ` Dmitry Torokhov
  2007-03-10  7:22       ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Torokhov @ 2007-03-10  7:12 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Andrew Morton

On Saturday 10 March 2007 01:55, Greg KH wrote:
> On Fri, Mar 09, 2007 at 10:54:43PM -0800, Greg KH wrote:
> > On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> > > Greg,
> > > 
> > > Please consider applying the patch below. It switches struct device_type
> > > to using attribute groups which os more flexible. I am using it in my
> > > input class_device -> device conversion (which is 99% done btw).
> > 
> > Argh, I never sent you my version of that, did I?  Very sorry about
> > that, I was working on fixing up the device namespace issue first, which
> > isn't done yet :(
> > 
> > Anyway, my patch that did that is below, feel free to use it or not if
> > you want.
> > 
> > > I looked through -mm and the latest git and there does not seem to be
> > > any users of struct device_type yet...
> > 
> > Yes, the input patch below uses it and I have a block-device patch from
> > Kay in my tree that Andrew doesn't pull from (as it's usually really
> > messed up and I know to hide this kind of breakage from him...)
> 
> Oops, that patch didn't use it, this follow-on patch from Kay uses them.
> 

Ok, so input portion in your tree does not use type->attrs so we don't
have a conflict here. Unless my patch messes up Kay's blockdev patch
badly I'd like you to accept it. Input uses 3 attribute groups and I
don't want to open-code their creation/removal.

-- 
Dmitry

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  7:12     ` Dmitry Torokhov
@ 2007-03-10  7:22       ` Greg KH
  2007-03-10 14:27         ` Kay Sievers
  2007-03-26  4:45         ` Dmitry Torokhov
  0 siblings, 2 replies; 7+ messages in thread
From: Greg KH @ 2007-03-10  7:22 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Andrew Morton

On Sat, Mar 10, 2007 at 02:12:04AM -0500, Dmitry Torokhov wrote:
> On Saturday 10 March 2007 01:55, Greg KH wrote:
> > On Fri, Mar 09, 2007 at 10:54:43PM -0800, Greg KH wrote:
> > > On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> > > > Greg,
> > > > 
> > > > Please consider applying the patch below. It switches struct device_type
> > > > to using attribute groups which os more flexible. I am using it in my
> > > > input class_device -> device conversion (which is 99% done btw).
> > > 
> > > Argh, I never sent you my version of that, did I?  Very sorry about
> > > that, I was working on fixing up the device namespace issue first, which
> > > isn't done yet :(
> > > 
> > > Anyway, my patch that did that is below, feel free to use it or not if
> > > you want.
> > > 
> > > > I looked through -mm and the latest git and there does not seem to be
> > > > any users of struct device_type yet...
> > > 
> > > Yes, the input patch below uses it and I have a block-device patch from
> > > Kay in my tree that Andrew doesn't pull from (as it's usually really
> > > messed up and I know to hide this kind of breakage from him...)
> > 
> > Oops, that patch didn't use it, this follow-on patch from Kay uses them.
> > 
> 
> Ok, so input portion in your tree does not use type->attrs so we don't
> have a conflict here. Unless my patch messes up Kay's blockdev patch
> badly I'd like you to accept it. Input uses 3 attribute groups and I
> don't want to open-code their creation/removal.

I'll take your patch and see if it messes up Kay's.  If it does, I'm
sure he will fix it up for me later :)

thanks,

greg k-h

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  7:22       ` Greg KH
@ 2007-03-10 14:27         ` Kay Sievers
  2007-03-26  4:45         ` Dmitry Torokhov
  1 sibling, 0 replies; 7+ messages in thread
From: Kay Sievers @ 2007-03-10 14:27 UTC (permalink / raw)
  To: Greg KH; +Cc: Dmitry Torokhov, linux-kernel, Andrew Morton

On 3/10/07, Greg KH <gregkh@suse.de> wrote:
> On Sat, Mar 10, 2007 at 02:12:04AM -0500, Dmitry Torokhov wrote:
> > On Saturday 10 March 2007 01:55, Greg KH wrote:
> > > On Fri, Mar 09, 2007 at 10:54:43PM -0800, Greg KH wrote:
> > > > On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> > > > > Greg,
> > > > >
> > > > > Please consider applying the patch below. It switches struct device_type
> > > > > to using attribute groups which os more flexible. I am using it in my
> > > > > input class_device -> device conversion (which is 99% done btw).
> > > >
> > > > Argh, I never sent you my version of that, did I?  Very sorry about
> > > > that, I was working on fixing up the device namespace issue first, which
> > > > isn't done yet :(
> > > >
> > > > Anyway, my patch that did that is below, feel free to use it or not if
> > > > you want.
> > > >
> > > > > I looked through -mm and the latest git and there does not seem to be
> > > > > any users of struct device_type yet...
> > > >
> > > > Yes, the input patch below uses it and I have a block-device patch from
> > > > Kay in my tree that Andrew doesn't pull from (as it's usually really
> > > > messed up and I know to hide this kind of breakage from him...)
> > >
> > > Oops, that patch didn't use it, this follow-on patch from Kay uses them.
> >
> > Ok, so input portion in your tree does not use type->attrs so we don't
> > have a conflict here. Unless my patch messes up Kay's blockdev patch
> > badly I'd like you to accept it. Input uses 3 attribute groups and I
> > don't want to open-code their creation/removal.
>
> I'll take your patch and see if it messes up Kay's.  If it does, I'm
> sure he will fix it up for me later :)

Sure, no problem. I like Dmitry's change.

Kay

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

* Re: [PATCH] Use attribute groups in struct device_type
  2007-03-10  7:22       ` Greg KH
  2007-03-10 14:27         ` Kay Sievers
@ 2007-03-26  4:45         ` Dmitry Torokhov
  1 sibling, 0 replies; 7+ messages in thread
From: Dmitry Torokhov @ 2007-03-26  4:45 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, Andrew Morton, Kay Sievers

Hi Greg,

On Saturday 10 March 2007 02:22, Greg KH wrote:
> On Sat, Mar 10, 2007 at 02:12:04AM -0500, Dmitry Torokhov wrote:
> > On Saturday 10 March 2007 01:55, Greg KH wrote:
> > > On Fri, Mar 09, 2007 at 10:54:43PM -0800, Greg KH wrote:
> > > > On Sat, Mar 10, 2007 at 01:37:34AM -0500, Dmitry Torokhov wrote:
> > > > > Greg,
> > > > > 
> > > > > Please consider applying the patch below. It switches struct device_type
> > > > > to using attribute groups which os more flexible. I am using it in my
> > > > > input class_device -> device conversion (which is 99% done btw).
> > > > 
> > > > Argh, I never sent you my version of that, did I?  Very sorry about
> > > > that, I was working on fixing up the device namespace issue first, which
> > > > isn't done yet :(
> > > > 
> > > > Anyway, my patch that did that is below, feel free to use it or not if
> > > > you want.
> > > > 
> > > > > I looked through -mm and the latest git and there does not seem to be
> > > > > any users of struct device_type yet...
> > > > 
> > > > Yes, the input patch below uses it and I have a block-device patch from
> > > > Kay in my tree that Andrew doesn't pull from (as it's usually really
> > > > messed up and I know to hide this kind of breakage from him...)
> > > 
> > > Oops, that patch didn't use it, this follow-on patch from Kay uses them.
> > > 
> > 
> > Ok, so input portion in your tree does not use type->attrs so we don't
> > have a conflict here. Unless my patch messes up Kay's blockdev patch
> > badly I'd like you to accept it. Input uses 3 attribute groups and I
> > don't want to open-code their creation/removal.
> 
> I'll take your patch and see if it messes up Kay's.  If it does, I'm
> sure he will fix it up for me later :)
> 

Here is the patch converting input core to struct device. It is a bit
different from yours as it does full conversion of handles into devices
(instead of just associating dynamically created device structure with
handles). The patch depends on bunch of other changes in my tree and
so will not apply to mainline so if you'd like to try it just pull
from my tree and then apply. I am interested whether new udev will
handle this.

I would also like to put it in my tree but it depends on the patch
adding attribute groups to the struct device_type which is in your
domain. What would be the best way for getting this to -mm?   

-- 
Dmitry

Input: convert from class devices to regular devices

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/evdev.c    |   84 +++++++++----------
 drivers/input/input.c    |  135 +++++++++++++++++--------------
 drivers/input/joydev.c   |   84 +++++++++----------
 drivers/input/mousedev.c |  204 ++++++++++++++++++++++++++---------------------
 drivers/input/tsdev.c    |   66 ++++++---------
 include/linux/input.h    |   19 ++--
 6 files changed, 313 insertions(+), 279 deletions(-)

Index: work/drivers/input/input.c
===================================================================
--- work.orig/drivers/input/input.c
+++ work/drivers/input/input.c
@@ -443,7 +443,7 @@ static int input_attach_handler(struct i
 		printk(KERN_ERR
 			"input: failed to attach handler %s to device %s, "
 			"error: %d\n",
-			handler->name, kobject_name(&dev->cdev.kobj), error);
+			handler->name, kobject_name(&dev->dev.kobj), error);
 
 	return error;
 }
@@ -528,7 +528,7 @@ static void input_seq_print_bitmap(struc
 static int input_devices_seq_show(struct seq_file *seq, void *v)
 {
 	struct input_dev *dev = container_of(v, struct input_dev, node);
-	const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+	const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
 	struct input_handle *handle;
 
 	seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
@@ -683,15 +683,17 @@ static inline int input_proc_init(void) 
 static inline void input_proc_exit(void) { }
 #endif
 
-#define INPUT_DEV_STRING_ATTR_SHOW(name)					\
-static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)	\
-{										\
-	struct input_dev *input_dev = to_input_dev(dev);			\
-										\
-	return scnprintf(buf, PAGE_SIZE, "%s\n",				\
-			 input_dev->name ? input_dev->name : "");		\
-}										\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+#define INPUT_DEV_STRING_ATTR_SHOW(name)				\
+static ssize_t input_dev_show_##name(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     char *buf)				\
+{									\
+	struct input_dev *input_dev = to_input_dev(dev);		\
+									\
+	return scnprintf(buf, PAGE_SIZE, "%s\n",			\
+			 input_dev->name ? input_dev->name : "");	\
+}									\
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)
 
 INPUT_DEV_STRING_ATTR_SHOW(name);
 INPUT_DEV_STRING_ATTR_SHOW(phys);
@@ -745,7 +747,9 @@ static int input_print_modalias(char *bu
 	return len;
 }
 
-static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
+static ssize_t input_dev_show_modalias(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
 {
 	struct input_dev *id = to_input_dev(dev);
 	ssize_t len;
@@ -754,13 +758,13 @@ static ssize_t input_dev_show_modalias(s
 
 	return min_t(int, len, PAGE_SIZE);
 }
-static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
 
 static struct attribute *input_dev_attrs[] = {
-	&class_device_attr_name.attr,
-	&class_device_attr_phys.attr,
-	&class_device_attr_uniq.attr,
-	&class_device_attr_modalias.attr,
+	&dev_attr_name.attr,
+	&dev_attr_phys.attr,
+	&dev_attr_uniq.attr,
+	&dev_attr_modalias.attr,
 	NULL
 };
 
@@ -768,13 +772,15 @@ static struct attribute_group input_dev_
 	.attrs	= input_dev_attrs,
 };
 
-#define INPUT_DEV_ID_ATTR(name)							\
-static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf)	\
-{										\
-	struct input_dev *input_dev = to_input_dev(dev);			\
-	return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name);		\
-}										\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+#define INPUT_DEV_ID_ATTR(name)						\
+static ssize_t input_dev_show_id_##name(struct device *dev,		\
+					struct device_attribute *attr,	\
+					char *buf)			\
+{									\
+	struct input_dev *input_dev = to_input_dev(dev);		\
+	return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name);	\
+}									\
+static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)
 
 INPUT_DEV_ID_ATTR(bustype);
 INPUT_DEV_ID_ATTR(vendor);
@@ -782,10 +788,10 @@ INPUT_DEV_ID_ATTR(product);
 INPUT_DEV_ID_ATTR(version);
 
 static struct attribute *input_dev_id_attrs[] = {
-	&class_device_attr_bustype.attr,
-	&class_device_attr_vendor.attr,
-	&class_device_attr_product.attr,
-	&class_device_attr_version.attr,
+	&dev_attr_bustype.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_product.attr,
+	&dev_attr_version.attr,
 	NULL
 };
 
@@ -814,15 +820,17 @@ static int input_print_bitmap(char *buf,
 	return len;
 }
 
-#define INPUT_DEV_CAP_ATTR(ev, bm)						\
-static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf)	\
-{										\
-	struct input_dev *input_dev = to_input_dev(dev);			\
-	int len = input_print_bitmap(buf, PAGE_SIZE,				\
-				     input_dev->bm##bit, ev##_MAX, 1);		\
-	return min_t(int, len, PAGE_SIZE);					\
-}										\
-static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+#define INPUT_DEV_CAP_ATTR(ev, bm)					\
+static ssize_t input_dev_show_cap_##bm(struct device *dev,		\
+				       struct device_attribute *attr,	\
+				       char *buf)			\
+{									\
+	struct input_dev *input_dev = to_input_dev(dev);		\
+	int len = input_print_bitmap(buf, PAGE_SIZE,			\
+				     input_dev->bm##bit, ev##_MAX, 1);	\
+	return min_t(int, len, PAGE_SIZE);				\
+}									\
+static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
 
 INPUT_DEV_CAP_ATTR(EV, ev);
 INPUT_DEV_CAP_ATTR(KEY, key);
@@ -835,15 +843,15 @@ INPUT_DEV_CAP_ATTR(FF, ff);
 INPUT_DEV_CAP_ATTR(SW, sw);
 
 static struct attribute *input_dev_caps_attrs[] = {
-	&class_device_attr_ev.attr,
-	&class_device_attr_key.attr,
-	&class_device_attr_rel.attr,
-	&class_device_attr_abs.attr,
-	&class_device_attr_msc.attr,
-	&class_device_attr_led.attr,
-	&class_device_attr_snd.attr,
-	&class_device_attr_ff.attr,
-	&class_device_attr_sw.attr,
+	&dev_attr_ev.attr,
+	&dev_attr_key.attr,
+	&dev_attr_rel.attr,
+	&dev_attr_abs.attr,
+	&dev_attr_msc.attr,
+	&dev_attr_led.attr,
+	&dev_attr_snd.attr,
+	&dev_attr_ff.attr,
+	&dev_attr_sw.attr,
 	NULL
 };
 
@@ -859,9 +867,9 @@ static struct attribute_group *input_dev
 	NULL
 };
 
-static void input_dev_release(struct class_device *class_dev)
+static void input_dev_release(struct device *device)
 {
-	struct input_dev *dev = to_input_dev(class_dev);
+	struct input_dev *dev = to_input_dev(device);
 
 	input_ff_destroy(dev);
 	kfree(dev);
@@ -948,10 +956,10 @@ static int input_add_uevent_modalias_var
 			return err;					\
 	} while (0)
 
-static int input_dev_uevent(struct class_device *cdev, char **envp,
+static int input_dev_uevent(struct device *device, char **envp,
 			    int num_envp, char *buffer, int buffer_size)
 {
-	struct input_dev *dev = to_input_dev(cdev);
+	struct input_dev *dev = to_input_dev(device);
 	int i = 0;
 	int len = 0;
 
@@ -989,10 +997,14 @@ static int input_dev_uevent(struct class
 	return 0;
 }
 
+static struct device_type input_dev_type = {
+	.groups		= input_dev_attr_groups,
+	.release	= input_dev_release,
+	.uevent		= input_dev_uevent,
+};
+
 struct class input_class = {
-	.name			= "input",
-	.release		= input_dev_release,
-	.uevent			= input_dev_uevent,
+	.name		= "input",
 };
 EXPORT_SYMBOL_GPL(input_class);
 
@@ -1011,9 +1023,9 @@ struct input_dev *input_allocate_device(
 
 	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
 	if (dev) {
-		dev->cdev.class = &input_class;
-		dev->cdev.groups = input_dev_attr_groups;
-		class_device_initialize(&dev->cdev);
+		dev->dev.type = &input_dev_type;
+		dev->dev.class = &input_class;
+		device_initialize(&dev->dev);
 		mutex_init(&dev->mutex);
 		INIT_LIST_HEAD(&dev->h_list);
 		INIT_LIST_HEAD(&dev->node);
@@ -1076,14 +1088,17 @@ int input_register_device(struct input_d
 
 	list_add_tail(&dev->node, &input_dev_list);
 
-	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+	snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
 		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
-	error = class_device_add(&dev->cdev);
+	if (dev->cdev.dev)
+		dev->dev.parent = dev->cdev.dev;
+
+	error = device_add(&dev->dev);
 	if (error)
 		return error;
 
-	path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
 	printk(KERN_INFO "input: %s as %s\n",
 		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
 	kfree(path);
@@ -1115,7 +1130,7 @@ void input_unregister_device(struct inpu
 
 	list_del_init(&dev->node);
 
-	class_device_unregister(&dev->cdev);
+	device_unregister(&dev->dev);
 
 	input_wakeup_procfs_readers();
 }
Index: work/include/linux/input.h
===================================================================
--- work.orig/include/linux/input.h
+++ work/include/linux/input.h
@@ -970,12 +970,15 @@ struct input_dev {
 	struct mutex mutex;	/* serializes open and close operations */
 	unsigned int users;
 
-	struct class_device cdev;
+	struct {
+		struct device *dev;
+	} cdev;			/*temporarily while we are switching to struct device */
+	struct device dev;
 
 	struct list_head	h_list;
 	struct list_head	node;
 };
-#define to_input_dev(d) container_of(d, struct input_dev, cdev)
+#define to_input_dev(d) container_of(d, struct input_dev, dev)
 
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
@@ -1078,22 +1081,22 @@ struct input_handle {
 	struct list_head	h_node;
 };
 
-#define to_dev(n) container_of(n,struct input_dev,node)
-#define to_handler(n) container_of(n,struct input_handler,node)
-#define to_handle(n) container_of(n,struct input_handle,d_node)
-#define to_handle_h(n) container_of(n,struct input_handle,h_node)
+#define to_dev(n) container_of(n, struct input_dev, node)
+#define to_handler(n) container_of(n, struct input_handler, node)
+#define to_handle(n) container_of(n, struct input_handle, d_node)
+#define to_handle_h(n) container_of(n, struct input_handle, h_node)
 
 struct input_dev *input_allocate_device(void);
 void input_free_device(struct input_dev *dev);
 
 static inline struct input_dev *input_get_device(struct input_dev *dev)
 {
-	return to_input_dev(class_device_get(&dev->cdev));
+	return to_input_dev(get_device(&dev->dev));
 }
 
 static inline void input_put_device(struct input_dev *dev)
 {
-	class_device_put(&dev->cdev);
+	put_device(&dev->dev);
 }
 
 int input_register_device(struct input_dev *);
Index: work/drivers/input/evdev.c
===================================================================
--- work.orig/drivers/input/evdev.c
+++ work/drivers/input/evdev.c
@@ -31,6 +31,7 @@ struct evdev {
 	wait_queue_head_t wait;
 	struct evdev_client *grab;
 	struct list_head client_list;
+	struct device dev;
 };
 
 struct evdev_client {
@@ -95,8 +96,10 @@ static int evdev_flush(struct file *file
 	return input_flush_device(&evdev->handle, file);
 }
 
-static void evdev_free(struct evdev *evdev)
+static void evdev_free(struct device *dev)
 {
+	struct evdev *evdev = container_of(dev, struct evdev, dev);
+
 	evdev_table[evdev->minor] = NULL;
 	kfree(evdev);
 }
@@ -115,12 +118,10 @@ static int evdev_release(struct inode *i
 	list_del(&client->node);
 	kfree(client);
 
-	if (!--evdev->open) {
-		if (evdev->exist)
-			input_close_device(&evdev->handle);
-		else
-			evdev_free(evdev);
-	}
+	if (!--evdev->open && evdev->exist)
+		input_close_device(&evdev->handle);
+
+	put_device(&evdev->dev);
 
 	return 0;
 }
@@ -140,24 +141,32 @@ static int evdev_open(struct inode *inod
 	if (!evdev || !evdev->exist)
 		return -ENODEV;
 
+	get_device(&evdev->dev);
+
 	client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
+	if (!client) {
+		error = -ENOMEM;
+		goto err_put_evdev;
+	}
 
 	client->evdev = evdev;
 	list_add_tail(&client->node, &evdev->client_list);
 
 	if (!evdev->open++ && evdev->exist) {
 		error = input_open_device(&evdev->handle);
-		if (error) {
-			list_del(&client->node);
-			kfree(client);
-			return error;
-		}
+		if (error)
+			goto err_free_client;
 	}
 
 	file->private_data = client;
 	return 0;
+
+ err_free_client:
+	list_del(&client->node);
+	kfree(client);
+ err_put_evdev:
+	put_device(&evdev->dev);
+	return error;
 }
 
 #ifdef CONFIG_COMPAT
@@ -626,8 +635,6 @@ static int evdev_connect(struct input_ha
 			 const struct input_device_id *id)
 {
 	struct evdev *evdev;
-	struct class_device *cdev;
-	dev_t devt;
 	int minor;
 	int error;
 
@@ -650,38 +657,32 @@ static int evdev_connect(struct input_ha
 	evdev->handle.name = evdev->name;
 	evdev->handle.handler = handler;
 	evdev->handle.private = evdev;
-	sprintf(evdev->name, "event%d", minor);
-
-	evdev_table[minor] = evdev;
+	snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
 
-	devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+	snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
+		 "event%d", minor);
+	evdev->dev.class = &input_class;
+	evdev->dev.parent = &dev->dev;
+	evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
+	evdev->dev.release = evdev_free;
+	device_initialize(&evdev->dev);
 
-	cdev = class_device_create(&input_class, &dev->cdev, devt,
-				   dev->cdev.dev, evdev->name);
-	if (IS_ERR(cdev)) {
-		error = PTR_ERR(cdev);
-		goto err_free_evdev;
-	}
+	evdev_table[minor] = evdev;
 
-	/* temporary symlink to keep userspace happy */
-	error = sysfs_create_link(&input_class.subsys.kset.kobj,
-				  &cdev->kobj, evdev->name);
+	error = device_add(&evdev->dev);
 	if (error)
-		goto err_cdev_destroy;
+		goto err_free_evdev;
 
 	error = input_register_handle(&evdev->handle);
 	if (error)
-		goto err_remove_link;
+		goto err_delete_evdev;
 
 	return 0;
 
- err_remove_link:
-	sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
- err_cdev_destroy:
-	class_device_destroy(&input_class, devt);
+ err_delete_evdev:
+	device_del(&evdev->dev);
  err_free_evdev:
-	kfree(evdev);
-	evdev_table[minor] = NULL;
+	put_device(&evdev->dev);
 	return error;
 }
 
@@ -691,10 +692,8 @@ static void evdev_disconnect(struct inpu
 	struct evdev_client *client;
 
 	input_unregister_handle(handle);
+	device_del(&evdev->dev);
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
-	class_device_destroy(&input_class,
-			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
 	evdev->exist = 0;
 
 	if (evdev->open) {
@@ -703,8 +702,9 @@ static void evdev_disconnect(struct inpu
 		wake_up_interruptible(&evdev->wait);
 		list_for_each_entry(client, &evdev->client_list, node)
 			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-	} else
-		evdev_free(evdev);
+	}
+
+	put_device(&evdev->dev);
 }
 
 static const struct input_device_id evdev_ids[] = {
Index: work/drivers/input/joydev.c
===================================================================
--- work.orig/drivers/input/joydev.c
+++ work/drivers/input/joydev.c
@@ -44,6 +44,8 @@ struct joydev {
 	struct input_handle handle;
 	wait_queue_head_t wait;
 	struct list_head client_list;
+	struct device dev;
+
 	struct js_corr corr[ABS_MAX + 1];
 	struct JS_DATA_SAVE_TYPE glue;
 	int nabs;
@@ -139,8 +141,10 @@ static int joydev_fasync(int fd, struct 
 	return retval < 0 ? retval : 0;
 }
 
-static void joydev_free(struct joydev *joydev)
+static void joydev_free(struct device *dev)
 {
+	struct joydev *joydev = container_of(dev, struct joydev, dev);
+
 	joydev_table[joydev->minor] = NULL;
 	kfree(joydev);
 }
@@ -155,12 +159,10 @@ static int joydev_release(struct inode *
 	list_del(&client->node);
 	kfree(client);
 
-	if (!--joydev->open) {
-		if (joydev->exist)
-			input_close_device(&joydev->handle);
-		else
-			joydev_free(joydev);
-	}
+	if (!--joydev->open && joydev->exist)
+		input_close_device(&joydev->handle);
+
+	put_device(&joydev->dev);
 
 	return 0;
 }
@@ -179,24 +181,32 @@ static int joydev_open(struct inode *ino
 	if (!joydev || !joydev->exist)
 		return -ENODEV;
 
+	get_device(&joydev->dev);
+
 	client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
+	if (!client) {
+		error = -ENOMEM;
+		goto err_put_joydev;
+	}
 
 	client->joydev = joydev;
 	list_add_tail(&client->node, &joydev->client_list);
 
 	if (!joydev->open++ && joydev->exist) {
 		error = input_open_device(&joydev->handle);
-		if (error) {
-			list_del(&client->node);
-			kfree(client);
-			return error;
-		}
+		if (error)
+			goto err_free_client;
 	}
 
 	file->private_data = client;
 	return 0;
+
+ err_free_client:
+	list_del(&client->node);
+	kfree(client);
+ err_put_joydev:
+	put_device(&joydev->dev);
+	return error;
 }
 
 static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -482,8 +492,6 @@ static int joydev_connect(struct input_h
 			  const struct input_device_id *id)
 {
 	struct joydev *joydev;
-	struct class_device *cdev;
-	dev_t devt;
 	int i, j, t, minor;
 	int error;
 
@@ -506,7 +514,7 @@ static int joydev_connect(struct input_h
 	joydev->handle.name = joydev->name;
 	joydev->handle.handler = handler;
 	joydev->handle.private = joydev;
-	sprintf(joydev->name, "js%d", minor);
+	snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
 
 	for (i = 0; i < ABS_MAX + 1; i++)
 		if (test_bit(i, dev->absbit)) {
@@ -548,36 +556,30 @@ static int joydev_connect(struct input_h
 		joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
 	}
 
-	joydev_table[minor] = joydev;
-
-	devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+	snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id),
+		 "js%d", minor);
+	joydev->dev.class = &input_class;
+	joydev->dev.parent = &dev->dev;
+	joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
+	joydev->dev.release = joydev_free;
+	device_initialize(&joydev->dev);
 
-	cdev = class_device_create(&input_class, &dev->cdev, devt,
-				   dev->cdev.dev, joydev->name);
-	if (IS_ERR(cdev)) {
-		error = PTR_ERR(cdev);
-		goto err_free_joydev;
-	}
+	joydev_table[minor] = joydev;
 
-	/* temporary symlink to keep userspace happy */
-	error = sysfs_create_link(&input_class.subsys.kset.kobj,
-				  &cdev->kobj, joydev->name);
+	error = device_add(&joydev->dev);
 	if (error)
-		goto err_cdev_destroy;
+		goto err_free_joydev;
 
 	error = input_register_handle(&joydev->handle);
 	if (error)
-		goto err_remove_link;
+		goto err_delete_joydev;
 
 	return 0;
 
- err_remove_link:
-	sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
- err_cdev_destroy:
-	class_device_destroy(&input_class, devt);
+ err_delete_joydev:
+	device_del(&joydev->dev);
  err_free_joydev:
-	joydev_table[minor] = NULL;
-	kfree(joydev);
+	put_device(&joydev->dev);
 	return error;
 }
 
@@ -588,9 +590,8 @@ static void joydev_disconnect(struct inp
 	struct joydev_client *client;
 
 	input_unregister_handle(handle);
+	device_del(&joydev->dev);
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
-	class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
 	joydev->exist = 0;
 
 	if (joydev->open) {
@@ -598,8 +599,9 @@ static void joydev_disconnect(struct inp
 		wake_up_interruptible(&joydev->wait);
 		list_for_each_entry(client, &joydev->client_list, node)
 			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-	} else
-		joydev_free(joydev);
+	}
+
+	put_device(&joydev->dev);
 }
 
 static const struct input_device_id joydev_blacklist[] = {
Index: work/drivers/input/mousedev.c
===================================================================
--- work.orig/drivers/input/mousedev.c
+++ work/drivers/input/mousedev.c
@@ -65,6 +65,7 @@ struct mousedev {
 	wait_queue_head_t wait;
 	struct list_head client_list;
 	struct input_handle handle;
+	struct device dev;
 
 	struct list_head mixdev_node;
 	int mixdev_open;
@@ -113,7 +114,7 @@ static unsigned char mousedev_imex_seq[]
 static struct input_handler mousedev_handler;
 
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
-static struct mousedev mousedev_mix;
+static struct mousedev *mousedev_mix;
 static LIST_HEAD(mousedev_mix_list);
 
 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
@@ -219,10 +220,10 @@ static void mousedev_key_event(struct mo
 
 	if (value) {
 		set_bit(index, &mousedev->packet.buttons);
-		set_bit(index, &mousedev_mix.packet.buttons);
+		set_bit(index, &mousedev_mix->packet.buttons);
 	} else {
 		clear_bit(index, &mousedev->packet.buttons);
-		clear_bit(index, &mousedev_mix.packet.buttons);
+		clear_bit(index, &mousedev_mix->packet.buttons);
 	}
 }
 
@@ -288,11 +289,11 @@ static void mousedev_touchpad_touch(stru
 			 * motion packet so we won't mess current position.
 			 */
 			set_bit(0, &mousedev->packet.buttons);
-			set_bit(0, &mousedev_mix.packet.buttons);
-			mousedev_notify_readers(mousedev, &mousedev_mix.packet);
-			mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
+			set_bit(0, &mousedev_mix->packet.buttons);
+			mousedev_notify_readers(mousedev, &mousedev_mix->packet);
+			mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet);
 			clear_bit(0, &mousedev->packet.buttons);
-			clear_bit(0, &mousedev_mix.packet.buttons);
+			clear_bit(0, &mousedev_mix->packet.buttons);
 		}
 		mousedev->touch = mousedev->pkt_count = 0;
 		mousedev->frac_dx = 0;
@@ -344,7 +345,7 @@ static void mousedev_event(struct input_
 				}
 
 				mousedev_notify_readers(mousedev, &mousedev->packet);
-				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
+				mousedev_notify_readers(mousedev_mix, &mousedev->packet);
 
 				mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
 				mousedev->packet.abs_event = 0;
@@ -363,8 +364,10 @@ static int mousedev_fasync(int fd, struc
 	return retval < 0 ? retval : 0;
 }
 
-static void mousedev_free(struct mousedev *mousedev)
+static void mousedev_free(struct device *dev)
 {
+	struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
+
 	mousedev_table[mousedev->minor] = NULL;
 	kfree(mousedev);
 }
@@ -373,7 +376,7 @@ static int mixdev_add_device(struct mous
 {
 	int error;
 
-	if (mousedev_mix.open) {
+	if (mousedev_mix->open) {
 		error = input_open_device(&mousedev->handle);
 		if (error)
 			return error;
@@ -407,6 +410,7 @@ static void mixdev_open_devices(void)
 			if (input_open_device(&mousedev->handle))
 				continue;
 
+			get_device(&mousedev->dev);
 			mousedev->open++;
 			mousedev->mixdev_open++;
 		}
@@ -415,16 +419,16 @@ static void mixdev_open_devices(void)
 
 static void mixdev_close_devices(void)
 {
-	struct mousedev *mousedev, *next;
+	struct mousedev *mousedev;
 
-	list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) {
+	list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
 		if (mousedev->mixdev_open) {
 			mousedev->mixdev_open = 0;
 			if (!--mousedev->open) {
 				if (mousedev->exist)
 					input_close_device(&mousedev->handle);
-				else
-					mousedev_free(mousedev);
+
+				put_device(&mousedev->dev);
 			}
 		}
 	}
@@ -445,10 +449,10 @@ static int mousedev_release(struct inode
 			mixdev_close_devices();
 		else if (mousedev->exist)
 			input_close_device(&mousedev->handle);
-		else
-			mousedev_free(mousedev);
 	}
 
+	put_device(&mousedev->dev);
+
 	return 0;
 }
 
@@ -474,9 +478,13 @@ static int mousedev_open(struct inode *i
 	if (!mousedev)
 		return -ENODEV;
 
+	get_device(&mousedev->dev);
+
 	client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
+	if (!client) {
+		error = -ENOMEM;
+		goto err_put_mousedev;
+	}
 
 	spin_lock_init(&client->packet_lock);
 	client->pos_x = xres / 2;
@@ -484,21 +492,25 @@ static int mousedev_open(struct inode *i
 	client->mousedev = mousedev;
 	list_add_tail(&client->node, &mousedev->client_list);
 
-	if (!mousedev->open++) {
+	if (!mousedev->open++ && mousedev->exist) {
 		if (mousedev->minor == MOUSEDEV_MIX)
 			mixdev_open_devices();
-		else if (mousedev->exist) {
+		else {
 			error = input_open_device(&mousedev->handle);
-			if (error) {
-				list_del(&client->node);
-				kfree(client);
-				return error;
-			}
+			if (error)
+				goto err_free_client;
 		}
 	}
 
 	file->private_data = client;
 	return 0;
+
+ err_free_client:
+	list_del(&client->node);
+	kfree(client);
+ err_put_mousedev:
+	put_device(&mousedev->dev);
+	return error;
 }
 
 static inline int mousedev_limit_delta(int delta, int limit)
@@ -681,57 +693,96 @@ static const struct file_operations mous
 	.fasync =	mousedev_fasync,
 };
 
-static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
-			    const struct input_device_id *id)
+static struct mousedev *mousedev_create(struct input_dev *dev,
+					struct input_handler *handler,
+					int minor)
 {
 	struct mousedev *mousedev;
-	struct class_device *cdev;
-	dev_t devt;
-	int minor;
 	int error;
 
-	for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
-	if (minor == MOUSEDEV_MINORS) {
-		printk(KERN_ERR "mousedev: no more free mousedev devices\n");
-		return -ENFILE;
-	}
-
 	mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
-	if (!mousedev)
-		return -ENOMEM;
+	if (!mousedev) {
+		error = -ENOMEM;
+		goto err_out;
+	}
 
 	INIT_LIST_HEAD(&mousedev->client_list);
 	INIT_LIST_HEAD(&mousedev->mixdev_node);
 	init_waitqueue_head(&mousedev->wait);
 
+	if (minor == MOUSEDEV_MIX)
+		strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
+	else
+		snprintf(mousedev->name, sizeof(mousedev->name),
+			 "mouse%d", minor);
+
 	mousedev->minor = minor;
 	mousedev->exist = 1;
 	mousedev->handle.dev = dev;
 	mousedev->handle.name = mousedev->name;
 	mousedev->handle.handler = handler;
 	mousedev->handle.private = mousedev;
-	sprintf(mousedev->name, "mouse%d", minor);
 
-	mousedev_table[minor] = mousedev;
+	strlcpy(mousedev->dev.bus_id, mousedev->name,
+		sizeof(mousedev->dev.bus_id));
+	mousedev->dev.class = &input_class;
+	if (dev)
+		mousedev->dev.parent = &dev->dev;
+	mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);
+	mousedev->dev.release = mousedev_free;
+	device_initialize(&mousedev->dev);
 
-	devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+	mousedev_table[minor] = mousedev;
 
-	cdev = class_device_create(&input_class, &dev->cdev, devt,
-				   dev->cdev.dev, mousedev->name);
-	if (IS_ERR(cdev)) {
-		error = PTR_ERR(cdev);
+	error = device_add(&mousedev->dev);
+	if (error)
 		goto err_free_mousedev;
+
+	return mousedev;
+
+ err_free_mousedev:
+	put_device(&mousedev->dev);
+ err_out:
+	return ERR_PTR(error);
+}
+
+static void mousedev_destroy(struct mousedev *mousedev)
+{
+	struct mousedev_client *client;
+
+	device_del(&mousedev->dev);
+	mousedev->exist = 0;
+
+	if (mousedev->open) {
+		input_close_device(&mousedev->handle);
+		wake_up_interruptible(&mousedev->wait);
+		list_for_each_entry(client, &mousedev->client_list, node)
+			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
 	}
 
-	/* temporary symlink to keep userspace happy */
-	error = sysfs_create_link(&input_class.subsys.kset.kobj,
-				  &cdev->kobj, mousedev->name);
-	if (error)
-		goto err_cdev_destroy;
+	put_device(&mousedev->dev);
+}
+
+static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+			    const struct input_device_id *id)
+{
+	struct mousedev *mousedev;
+	int minor;
+	int error;
+
+	for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
+	if (minor == MOUSEDEV_MINORS) {
+		printk(KERN_ERR "mousedev: no more free mousedev devices\n");
+		return -ENFILE;
+	}
+
+	mousedev = mousedev_create(dev, handler, minor);
+	if (IS_ERR(mousedev))
+		return PTR_ERR(mousedev);
 
 	error = input_register_handle(&mousedev->handle);
 	if (error)
-		goto err_remove_link;
+		goto err_delete_mousedev;
 
 	error = mixdev_add_device(mousedev);
 	if (error)
@@ -741,37 +792,18 @@ static int mousedev_connect(struct input
 
  err_unregister_handle:
 	input_unregister_handle(&mousedev->handle);
- err_remove_link:
-	sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
- err_cdev_destroy:
-	class_device_destroy(&input_class, devt);
- err_free_mousedev:
-	mousedev_table[minor] = NULL;
-	kfree(mousedev);
+ err_delete_mousedev:
+	device_unregister(&mousedev->dev);
 	return error;
 }
 
 static void mousedev_disconnect(struct input_handle *handle)
 {
 	struct mousedev *mousedev = handle->private;
-	struct mousedev_client *client;
-
-	input_unregister_handle(handle);
-
-	sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
-	class_device_destroy(&input_class,
-			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
-	mousedev->exist = 0;
 
 	mixdev_remove_device(mousedev);
-
-	if (mousedev->open) {
-		input_close_device(handle);
-		wake_up_interruptible(&mousedev->wait);
-		list_for_each_entry(client, &mousedev->client_list, node)
-			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-	} else
-		mousedev_free(mousedev);
+	input_unregister_handle(handle);
+	mousedev_destroy(mousedev);
 }
 
 static const struct input_device_id mousedev_ids[] = {
@@ -823,25 +855,16 @@ static int psaux_registered;
 
 static int __init mousedev_init(void)
 {
-	struct class_device *cdev;
 	int error;
 
+	mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX);
+	if (IS_ERR(mousedev_mix))
+		return PTR_ERR(mousedev_mix);
+
 	error = input_register_handler(&mousedev_handler);
-	if (error)
+	if (error) {
+		mousedev_destroy(mousedev_mix);
 		return error;
-
-	memset(&mousedev_mix, 0, sizeof(struct mousedev));
-	INIT_LIST_HEAD(&mousedev_mix.client_list);
-	init_waitqueue_head(&mousedev_mix.wait);
-	mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
-	mousedev_mix.exist = 1;
-	mousedev_mix.minor = MOUSEDEV_MIX;
-
-	cdev = class_device_create(&input_class, NULL,
-			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
-	if (IS_ERR(cdev)) {
-		input_unregister_handler(&mousedev_handler);
-		return PTR_ERR(cdev);
 	}
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -864,9 +887,8 @@ static void __exit mousedev_exit(void)
 	if (psaux_registered)
 		misc_deregister(&psaux_mouse);
 #endif
-	class_device_destroy(&input_class,
-			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
 	input_unregister_handler(&mousedev_handler);
+	mousedev_destroy(mousedev_mix);
 }
 
 module_init(mousedev_init);
Index: work/drivers/input/tsdev.c
===================================================================
--- work.orig/drivers/input/tsdev.c
+++ work/drivers/input/tsdev.c
@@ -110,9 +110,11 @@ struct tsdev {
 	int open;
 	int minor;
 	char name[8];
+	struct input_handle handle;
 	wait_queue_head_t wait;
 	struct list_head client_list;
-	struct input_handle handle;
+	struct device dev;
+
 	int x, y, pressure;
 	struct ts_calibration cal;
 };
@@ -185,8 +187,10 @@ static int tsdev_open(struct inode *inod
 	return 0;
 }
 
-static void tsdev_free(struct tsdev *tsdev)
+static void tsdev_free(struct device *dev)
 {
+	struct tsdev *tsdev = container_of(dev, struct tsdev, dev);
+
 	tsdev_table[tsdev->minor] = NULL;
 	kfree(tsdev);
 }
@@ -201,12 +205,10 @@ static int tsdev_release(struct inode *i
 	list_del(&client->node);
 	kfree(client);
 
-	if (!--tsdev->open) {
-		if (tsdev->exist)
-			input_close_device(&tsdev->handle);
-		else
-			tsdev_free(tsdev);
-	}
+	if (!--tsdev->open && tsdev->exist)
+		input_close_device(&tsdev->handle);
+
+	put_device(&tsdev->dev);
 
 	return 0;
 }
@@ -389,8 +391,6 @@ static int tsdev_connect(struct input_ha
 			 const struct input_device_id *id)
 {
 	struct tsdev *tsdev;
-	struct class_device *cdev;
-	dev_t devt;
 	int minor, delta;
 	int error;
 
@@ -408,14 +408,13 @@ static int tsdev_connect(struct input_ha
 	INIT_LIST_HEAD(&tsdev->client_list);
 	init_waitqueue_head(&tsdev->wait);
 
-	sprintf(tsdev->name, "ts%d", minor);
-
 	tsdev->exist = 1;
 	tsdev->minor = minor;
 	tsdev->handle.dev = dev;
 	tsdev->handle.name = tsdev->name;
 	tsdev->handle.handler = handler;
 	tsdev->handle.private = tsdev;
+	snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor);
 
 	/* Precompute the rough calibration matrix */
 	delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
@@ -430,36 +429,30 @@ static int tsdev_connect(struct input_ha
 	tsdev->cal.yscale = (yres << 8) / delta;
 	tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
 
-	tsdev_table[minor] = tsdev;
-
-	devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+	snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id),
+		 "ts%d", minor);
+	tsdev->dev.class = &input_class;
+	tsdev->dev.parent = &dev->dev;
+	tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor);
+	tsdev->dev.release = tsdev_free;
+	device_initialize(&tsdev->dev);
 
-	cdev = class_device_create(&input_class, &dev->cdev, devt,
-				   dev->cdev.dev, tsdev->name);
-	if (IS_ERR(cdev)) {
-		error = PTR_ERR(cdev);
-		goto err_free_tsdev;
-	}
+	tsdev_table[minor] = tsdev;
 
-	/* temporary symlink to keep userspace happy */
-	error = sysfs_create_link(&input_class.subsys.kset.kobj,
-				  &cdev->kobj, tsdev->name);
+	error = device_add(&tsdev->dev);
 	if (error)
-		goto err_cdev_destroy;
+		goto err_free_tsdev;
 
 	error = input_register_handle(&tsdev->handle);
 	if (error)
-		goto err_remove_link;
+		goto err_delete_tsdev;
 
 	return 0;
 
- err_remove_link:
-	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
- err_cdev_destroy:
-	class_device_destroy(&input_class, devt);
+ err_delete_tsdev:
+	device_del(&tsdev->dev);
  err_free_tsdev:
-	tsdev_table[minor] = NULL;
-	kfree(tsdev);
+	put_device(&tsdev->dev);
 	return error;
 }
 
@@ -469,10 +462,8 @@ static void tsdev_disconnect(struct inpu
 	struct tsdev_client *client;
 
 	input_unregister_handle(handle);
+	device_del(&tsdev->dev);
 
-	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
-	class_device_destroy(&input_class,
-			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
 	tsdev->exist = 0;
 
 	if (tsdev->open) {
@@ -480,8 +471,9 @@ static void tsdev_disconnect(struct inpu
 		wake_up_interruptible(&tsdev->wait);
 		list_for_each_entry(client, &tsdev->client_list, node)
 			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-	} else
-		tsdev_free(tsdev);
+	}
+
+	put_device(&tsdev->dev);
 }
 
 static const struct input_device_id tsdev_ids[] = {

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

end of thread, other threads:[~2007-03-26  4:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-10  6:37 [PATCH] Use attribute groups in struct device_type Dmitry Torokhov
2007-03-10  6:54 ` Greg KH
2007-03-10  6:55   ` Greg KH
2007-03-10  7:12     ` Dmitry Torokhov
2007-03-10  7:22       ` Greg KH
2007-03-10 14:27         ` Kay Sievers
2007-03-26  4:45         ` Dmitry Torokhov

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).