Procházet zdrojové kódy

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (28 commits)
  sysfs: Shadow directory support
  Driver Core: Increase the default timeout value of the firmware subsystem
  Driver core: allow to delay the uevent at device creation time
  Driver core: add device_type to struct device
  Driver core: add uevent vars for devices of a class
  SYSFS: Fix missing include of list.h in sysfs.h
  HOWTO: Add a reference to Harbison and Steele
  sysfs: error handling in sysfs, fill_read_buffer()
  kobject: kobject_put cleanup
  sysfs: kobject_put cleanup
  sysfs: suppress lockdep warnings
  Driver core: fix race in sysfs between sysfs_remove_file() and read()/write()
  driver core: Change function call order in device_bind_driver().
  driver core: Don't stop probing on ->probe errors.
  driver core fixes: device_register() retval check in platform.c
  driver core fixes: make_class_name() retval checks
  /sys/modules/*/holders
  USB: add the sysfs driver name to all modules
  SERIO: add the sysfs driver name to all modules
  PCI: add the sysfs driver name to all modules
  ...
Linus Torvalds před 18 roky
rodič
revize
f2aca47dc3
69 změnil soubory, kde provedl 1286 přidání a 709 odebrání
  1. 1 0
      Documentation/HOWTO
  2. 14 7
      drivers/base/class.c
  3. 133 70
      drivers/base/core.c
  4. 12 9
      drivers/base/dd.c
  5. 1 1
      drivers/base/firmware_class.c
  6. 9 2
      drivers/base/platform.c
  7. 4 3
      drivers/ide/setup-pci.c
  8. 15 18
      drivers/infiniband/ulp/ipoib/ipoib_main.c
  9. 5 6
      drivers/infiniband/ulp/ipoib/ipoib_vlan.c
  10. 4 2
      drivers/input/serio/serio.c
  11. 1 1
      drivers/net/arm/at91_ether.c
  12. 1 1
      drivers/net/arm/etherh.c
  13. 174 113
      drivers/net/bonding/bond_sysfs.c
  14. 1 1
      drivers/net/iseries_veth.c
  15. 18 18
      drivers/net/macb.c
  16. 1 1
      drivers/net/smc911x.c
  17. 1 1
      drivers/net/smc91x.c
  18. 1 1
      drivers/net/wireless/hostap/hostap_main.c
  19. 2 2
      drivers/net/wireless/orinoco.c
  20. 1 1
      drivers/net/wireless/orinoco_cs.c
  21. 1 1
      drivers/net/wireless/spectrum_cs.c
  22. 3 1
      drivers/pci/pci-driver.c
  23. 17 17
      drivers/pcmcia/cs.c
  24. 2 2
      drivers/pcmcia/cs_internal.h
  25. 7 7
      drivers/pcmcia/ds.c
  26. 1 1
      drivers/pcmcia/i82092.c
  27. 1 1
      drivers/pcmcia/i82365.c
  28. 0 1
      drivers/pcmcia/pcmcia_ioctl.c
  29. 0 1
      drivers/pcmcia/pcmcia_resource.c
  30. 1 1
      drivers/pcmcia/pd6729.c
  31. 31 25
      drivers/pcmcia/rsrc_nonstatic.c
  32. 3 3
      drivers/pcmcia/soc_common.c
  33. 61 43
      drivers/pcmcia/socket_sysfs.c
  34. 1 1
      drivers/pcmcia/tcic.c
  35. 1 1
      drivers/pcmcia/yenta_socket.c
  36. 1 1
      drivers/spi/pxa2xx_spi.c
  37. 16 16
      drivers/spi/spi.c
  38. 3 3
      drivers/spi/spi_bitbang.c
  39. 2 2
      drivers/spi/spi_butterfly.c
  40. 3 1
      drivers/usb/core/driver.c
  41. 2 2
      drivers/usb/input/hid-lgff.c
  42. 3 3
      fs/sysfs/bin.c
  43. 175 39
      fs/sysfs/dir.c
  44. 58 24
      fs/sysfs/file.c
  45. 2 0
      fs/sysfs/group.c
  46. 35 1
      fs/sysfs/inode.c
  47. 10 1
      fs/sysfs/mount.c
  48. 1 0
      fs/sysfs/symlink.c
  49. 21 0
      fs/sysfs/sysfs.h
  50. 11 1
      include/linux/device.h
  51. 2 2
      include/linux/ide.h
  52. 4 0
      include/linux/kobject.h
  53. 2 1
      include/linux/module.h
  54. 3 2
      include/linux/netdevice.h
  55. 3 2
      include/linux/pci.h
  56. 5 0
      include/linux/serio.h
  57. 5 5
      include/linux/spi/spi.h
  58. 20 4
      include/linux/sysfs.h
  59. 3 2
      include/linux/usb.h
  60. 1 1
      include/pcmcia/ss.h
  61. 59 17
      kernel/module.c
  62. 20 8
      kernel/params.c
  63. 61 12
      lib/kobject.c
  64. 1 1
      net/bridge/br_if.c
  65. 127 107
      net/bridge/br_sysfs_br.c
  66. 1 1
      net/bridge/br_sysfs_if.c
  67. 3 3
      net/core/dev.c
  68. 93 82
      net/core/net-sysfs.c
  69. 1 1
      net/core/skbuff.c

+ 1 - 0
Documentation/HOWTO

@@ -30,6 +30,7 @@ are not a good substitute for a solid C education and/or years of
 experience, the following books are good for, if anything, reference:
  - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
  - "Practical C Programming" by Steve Oualline [O'Reilly]
+ - "C:  A Reference Manual" by Harbison and Steele [Prentice Hall]
 
 The kernel is written using GNU C and the GNU toolchain.  While it
 adheres to the ISO C89 standard, it uses a number of extensions that are

+ 14 - 7
drivers/base/class.c

@@ -364,7 +364,7 @@ char *make_class_name(const char *name, struct kobject *kobj)
 
 	class_name = kmalloc(size, GFP_KERNEL);
 	if (!class_name)
-		return ERR_PTR(-ENOMEM);
+		return NULL;
 
 	strcpy(class_name, name);
 	strcat(class_name, ":");
@@ -411,8 +411,11 @@ static int make_deprecated_class_device_links(struct class_device *class_dev)
 		return 0;
 
 	class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
-	error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
-				  class_name);
+	if (class_name)
+		error = sysfs_create_link(&class_dev->dev->kobj,
+					  &class_dev->kobj, class_name);
+	else
+		error = -ENOMEM;
 	kfree(class_name);
 	return error;
 }
@@ -425,7 +428,8 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
 		return;
 
 	class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
-	sysfs_remove_link(&class_dev->dev->kobj, class_name);
+	if (class_name)
+		sysfs_remove_link(&class_dev->dev->kobj, class_name);
 	kfree(class_name);
 }
 #else
@@ -863,9 +867,12 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
 	if (class_dev->dev) {
 		new_class_name = make_class_name(class_dev->class->name,
 						 &class_dev->kobj);
-		sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
-				  new_class_name);
-		sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
+		if (new_class_name)
+			sysfs_create_link(&class_dev->dev->kobj,
+					  &class_dev->kobj, new_class_name);
+		if (old_class_name)
+			sysfs_remove_link(&class_dev->dev->kobj,
+						old_class_name);
 	}
 #endif
 	class_device_put(class_dev);

+ 133 - 70
drivers/base/core.c

@@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
 
 	if (dev->release)
 		dev->release(dev);
+	else if (dev->type && dev->type->release)
+		dev->type->release(dev);
 	else if (dev->class && dev->class->dev_release)
 		dev->class->dev_release(dev);
 	else {
@@ -154,25 +156,47 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 			       "MINOR=%u", MINOR(dev->devt));
 	}
 
-#ifdef CONFIG_SYSFS_DEPRECATED
-	/* add bus name (same as SUBSYSTEM, deprecated) */
-	if (dev->bus)
-		add_uevent_var(envp, num_envp, &i,
-			       buffer, buffer_size, &length,
-			       "PHYSDEVBUS=%s", dev->bus->name);
-#endif
-
-	/* add driver name (PHYSDEV* values are deprecated)*/
-	if (dev->driver) {
+	if (dev->driver)
 		add_uevent_var(envp, num_envp, &i,
 			       buffer, buffer_size, &length,
 			       "DRIVER=%s", dev->driver->name);
+
 #ifdef CONFIG_SYSFS_DEPRECATED
+	if (dev->class) {
+		struct device *parent = dev->parent;
+
+		/* find first bus device in parent chain */
+		while (parent && !parent->bus)
+			parent = parent->parent;
+		if (parent && parent->bus) {
+			const char *path;
+
+			path = kobject_get_path(&parent->kobj, GFP_KERNEL);
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVPATH=%s", path);
+			kfree(path);
+
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVBUS=%s", parent->bus->name);
+
+			if (parent->driver)
+				add_uevent_var(envp, num_envp, &i,
+					       buffer, buffer_size, &length,
+					       "PHYSDEVDRIVER=%s", parent->driver->name);
+		}
+	} else if (dev->bus) {
 		add_uevent_var(envp, num_envp, &i,
 			       buffer, buffer_size, &length,
-			       "PHYSDEVDRIVER=%s", dev->driver->name);
-#endif
+			       "PHYSDEVBUS=%s", dev->bus->name);
+
+		if (dev->driver)
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVDRIVER=%s", dev->driver->name);
 	}
+#endif
 
 	/* terminate, set to next free slot, shrink available space */
 	envp[i] = NULL;
@@ -184,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 	if (dev->bus && dev->bus->uevent) {
 		/* have the bus specific function add its stuff */
 		retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
-			if (retval) {
-			pr_debug ("%s - uevent() returned %d\n",
+		if (retval)
+			pr_debug ("%s: bus uevent() returned %d\n",
 				  __FUNCTION__, retval);
-		}
 	}
 
 	if (dev->class && dev->class->dev_uevent) {
 		/* have the class specific function add its stuff */
 		retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
-			if (retval) {
-				pr_debug("%s - dev_uevent() returned %d\n",
-					 __FUNCTION__, retval);
-		}
+		if (retval)
+			pr_debug("%s: class uevent() returned %d\n",
+				 __FUNCTION__, retval);
+	}
+
+	if (dev->type && dev->type->uevent) {
+		/* have the device type specific fuction add its stuff */
+		retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
+		if (retval)
+			pr_debug("%s: dev_type uevent() returned %d\n",
+				 __FUNCTION__, retval);
 	}
 
 	return retval;
@@ -247,37 +277,50 @@ static void device_remove_groups(struct device *dev)
 static int device_add_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
+	struct device_type *type = dev->type;
 	int error = 0;
 	int i;
 
-	if (!class)
-		return 0;
-
-	if (class->dev_attrs) {
+	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 (error)
+			while (--i >= 0)
+				device_remove_file(dev, &class->dev_attrs[i]);
 	}
-	if (error)
-		while (--i >= 0)
-			device_remove_file(dev, &class->dev_attrs[i]);
+
+	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 (error)
+			while (--i >= 0)
+				device_remove_file(dev, &type->attrs[i]);
+	}
+
 	return error;
 }
 
 static void device_remove_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
+	struct device_type *type = dev->type;
 	int i;
 
-	if (!class)
-		return;
-
-	if (class->dev_attrs) {
+	if (class && class->dev_attrs) {
 		for (i = 0; attr_name(class->dev_attrs[i]); i++)
 			device_remove_file(dev, &class->dev_attrs[i]);
 	}
+
+	if (type && type->attrs) {
+		for (i = 0; attr_name(type->attrs[i]); i++)
+			device_remove_file(dev, &type->attrs[i]);
+	}
 }
 
 
@@ -390,22 +433,23 @@ void device_initialize(struct device *dev)
 }
 
 #ifdef CONFIG_SYSFS_DEPRECATED
-static int setup_parent(struct device *dev, struct device *parent)
+static struct kobject * get_device_parent(struct device *dev,
+					  struct device *parent)
 {
 	/* Set the parent to the class, not the parent device */
 	/* this keeps sysfs from having a symlink to make old udevs happy */
 	if (dev->class)
-		dev->kobj.parent = &dev->class->subsys.kset.kobj;
+		return &dev->class->subsys.kset.kobj;
 	else if (parent)
-		dev->kobj.parent = &parent->kobj;
+		return &parent->kobj;
 
-	return 0;
+	return NULL;
 }
 #else
-static int virtual_device_parent(struct device *dev)
+static struct kobject * virtual_device_parent(struct device *dev)
 {
 	if (!dev->class)
-		return -ENODEV;
+		return ERR_PTR(-ENODEV);
 
 	if (!dev->class->virtual_dir) {
 		static struct kobject *virtual_dir = NULL;
@@ -415,25 +459,31 @@ static int virtual_device_parent(struct device *dev)
 		dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
 	}
 
-	dev->kobj.parent = dev->class->virtual_dir;
-	return 0;
+	return dev->class->virtual_dir;
 }
 
-static int setup_parent(struct device *dev, struct device *parent)
+static struct kobject * get_device_parent(struct device *dev,
+					  struct device *parent)
 {
-	int error;
-
 	/* if this is a class device, and has no parent, create one */
 	if ((dev->class) && (parent == NULL)) {
-		error = virtual_device_parent(dev);
-		if (error)
-			return error;
+		return virtual_device_parent(dev);
 	} else if (parent)
-		dev->kobj.parent = &parent->kobj;
+		return &parent->kobj;
+	return NULL;
+}
 
+#endif
+static int setup_parent(struct device *dev, struct device *parent)
+{
+	struct kobject *kobj;
+	kobj = get_device_parent(dev, parent);
+	if (IS_ERR(kobj))
+		return PTR_ERR(kobj);
+	if (kobj)
+		dev->kobj.parent = kobj;
 	return 0;
 }
-#endif
 
 /**
  *	device_add - add device to device hierarchy.
@@ -520,9 +570,13 @@ int device_add(struct device *dev)
 					  &dev->kobj, dev->bus_id);
 #ifdef CONFIG_SYSFS_DEPRECATED
 		if (parent) {
-			sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
-			class_name = make_class_name(dev->class->name, &dev->kobj);
-			sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
+			sysfs_create_link(&dev->kobj, &dev->parent->kobj,
+							"device");
+			class_name = make_class_name(dev->class->name,
+							&dev->kobj);
+			if (class_name)
+				sysfs_create_link(&dev->parent->kobj,
+						  &dev->kobj, class_name);
 		}
 #endif
 	}
@@ -535,7 +589,8 @@ int device_add(struct device *dev)
 		goto PMError;
 	if ((error = bus_add_device(dev)))
 		goto BusError;
-	kobject_uevent(&dev->kobj, KOBJ_ADD);
+	if (!dev->uevent_suppress)
+		kobject_uevent(&dev->kobj, KOBJ_ADD);
 	if ((error = bus_attach_device(dev)))
 		goto AttachError;
 	if (parent)
@@ -665,7 +720,9 @@ void device_del(struct device * dev)
 		if (parent) {
 			char *class_name = make_class_name(dev->class->name,
 							   &dev->kobj);
-			sysfs_remove_link(&dev->parent->kobj, class_name);
+			if (class_name)
+				sysfs_remove_link(&dev->parent->kobj,
+						  class_name);
 			kfree(class_name);
 			sysfs_remove_link(&dev->kobj, "device");
 		}
@@ -968,20 +1025,25 @@ static int device_move_class_links(struct device *dev,
 
 	class_name = make_class_name(dev->class->name, &dev->kobj);
 	if (!class_name) {
-		error = PTR_ERR(class_name);
-		class_name = NULL;
+		error = -ENOMEM;
 		goto out;
 	}
 	if (old_parent) {
 		sysfs_remove_link(&dev->kobj, "device");
 		sysfs_remove_link(&old_parent->kobj, class_name);
 	}
-	error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device");
-	if (error)
-		goto out;
-	error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name);
-	if (error)
-		sysfs_remove_link(&dev->kobj, "device");
+	if (new_parent) {
+		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
+					  "device");
+		if (error)
+			goto out;
+		error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
+					  class_name);
+		if (error)
+			sysfs_remove_link(&dev->kobj, "device");
+	}
+	else
+		error = 0;
 out:
 	kfree(class_name);
 	return error;
@@ -993,29 +1055,28 @@ out:
 /**
  * device_move - moves a device to a new parent
  * @dev: the pointer to the struct device to be moved
- * @new_parent: the new parent of the device
+ * @new_parent: the new parent of the device (can by NULL)
  */
 int device_move(struct device *dev, struct device *new_parent)
 {
 	int error;
 	struct device *old_parent;
+	struct kobject *new_parent_kobj;
 
 	dev = get_device(dev);
 	if (!dev)
 		return -EINVAL;
 
-	if (!device_is_registered(dev)) {
-		error = -EINVAL;
-		goto out;
-	}
 	new_parent = get_device(new_parent);
-	if (!new_parent) {
-		error = -EINVAL;
+	new_parent_kobj = get_device_parent (dev, new_parent);
+	if (IS_ERR(new_parent_kobj)) {
+		error = PTR_ERR(new_parent_kobj);
+		put_device(new_parent);
 		goto out;
 	}
 	pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
-		new_parent->bus_id);
-	error = kobject_move(&dev->kobj, &new_parent->kobj);
+		 new_parent ? new_parent->bus_id : "<NULL>");
+	error = kobject_move(&dev->kobj, new_parent_kobj);
 	if (error) {
 		put_device(new_parent);
 		goto out;
@@ -1024,7 +1085,8 @@ int device_move(struct device *dev, struct device *new_parent)
 	dev->parent = new_parent;
 	if (old_parent)
 		klist_remove(&dev->knode_parent);
-	klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+	if (new_parent)
+		klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
 	if (!dev->class)
 		goto out_put;
 	error = device_move_class_links(dev, old_parent, new_parent);
@@ -1032,7 +1094,8 @@ int device_move(struct device *dev, struct device *new_parent)
 		/* We ignore errors on cleanup since we're hosed anyway... */
 		device_move_class_links(dev, new_parent, old_parent);
 		if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
-			klist_remove(&dev->knode_parent);
+			if (new_parent)
+				klist_remove(&dev->knode_parent);
 			if (old_parent)
 				klist_add_tail(&dev->knode_parent,
 					       &old_parent->klist_children);

+ 12 - 9
drivers/base/dd.c

@@ -86,8 +86,12 @@ static void driver_sysfs_remove(struct device *dev)
  */
 int device_bind_driver(struct device *dev)
 {
-	driver_bound(dev);
-	return driver_sysfs_add(dev);
+	int ret;
+
+	ret = driver_sysfs_add(dev);
+	if (!ret)
+		driver_bound(dev);
+	return ret;
 }
 
 struct stupid_thread_structure {
@@ -136,18 +140,17 @@ probe_failed:
 	driver_sysfs_remove(dev);
 	dev->driver = NULL;
 
-	if (ret == -ENODEV || ret == -ENXIO) {
-		/* Driver matched, but didn't support device
-		 * or device not found.
-		 * Not an error; keep going.
-		 */
-		ret = 0;
-	} else {
+	if (ret != -ENODEV && ret != -ENXIO) {
 		/* driver matched but the probe failed */
 		printk(KERN_WARNING
 		       "%s: probe of %s failed with error %d\n",
 		       drv->name, dev->bus_id, ret);
 	}
+	/*
+	 * Ignore errors returned by ->probe so that the next driver can try
+	 * its luck.
+	 */
+	ret = 0;
 done:
 	kfree(data);
 	atomic_dec(&probe_count);

+ 1 - 1
drivers/base/firmware_class.c

@@ -35,7 +35,7 @@ enum {
 	FW_STATUS_READY_NOHOTPLUG,
 };
 
-static int loading_timeout = 10;	/* In seconds */
+static int loading_timeout = 60;	/* In seconds */
 
 /* fw_lock could be moved to 'struct firmware_priv' but since it is just
  * guarding for corner cases a global lock should be OK */

+ 9 - 2
drivers/base/platform.c

@@ -611,8 +611,15 @@ EXPORT_SYMBOL_GPL(platform_bus_type);
 
 int __init platform_bus_init(void)
 {
-	device_register(&platform_bus);
-	return bus_register(&platform_bus_type);
+	int error;
+
+	error = device_register(&platform_bus);
+	if (error)
+		return error;
+	error =  bus_register(&platform_bus_type);
+	if (error)
+		device_unregister(&platform_bus);
+	return error;
 }
 
 #ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK

+ 4 - 3
drivers/ide/setup-pci.c

@@ -783,10 +783,11 @@ static LIST_HEAD(ide_pci_drivers);
  *	Returns are the same as for pci_register_driver
  */
 
-int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
+int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
+			      const char *mod_name)
 {
 	if(!pre_init)
-		return __pci_register_driver(driver, module);
+		return __pci_register_driver(driver, module, mod_name);
 	driver->driver.owner = module;
 	list_add_tail(&driver->node, &ide_pci_drivers);
 	return 0;
@@ -862,6 +863,6 @@ void __init ide_scan_pcibus (int scan_direction)
 	{
 		list_del(l);
 		d = list_entry(l, struct pci_driver, node);
-		__pci_register_driver(d, d->driver.owner);
+		__pci_register_driver(d, d->driver.owner, d->driver.mod_name);
 	}
 }

+ 15 - 18
drivers/infiniband/ulp/ipoib/ipoib_main.c

@@ -958,16 +958,17 @@ struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
 	return netdev_priv(dev);
 }
 
-static ssize_t show_pkey(struct class_device *cdev, char *buf)
+static ssize_t show_pkey(struct device *dev,
+			 struct device_attribute *attr, char *buf)
 {
-	struct ipoib_dev_priv *priv =
-		netdev_priv(container_of(cdev, struct net_device, class_dev));
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "0x%04x\n", priv->pkey);
 }
-static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
 
-static ssize_t create_child(struct class_device *cdev,
+static ssize_t create_child(struct device *dev,
+			    struct device_attribute *attr,
 			    const char *buf, size_t count)
 {
 	int pkey;
@@ -985,14 +986,14 @@ static ssize_t create_child(struct class_device *cdev,
 	 */
 	pkey |= 0x8000;
 
-	ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev),
-			     pkey);
+	ret = ipoib_vlan_add(to_net_dev(dev), pkey);
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
+static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
 
-static ssize_t delete_child(struct class_device *cdev,
+static ssize_t delete_child(struct device *dev,
+			    struct device_attribute *attr,
 			    const char *buf, size_t count)
 {
 	int pkey;
@@ -1004,18 +1005,16 @@ static ssize_t delete_child(struct class_device *cdev,
 	if (pkey < 0 || pkey > 0xffff)
 		return -EINVAL;
 
-	ret = ipoib_vlan_delete(container_of(cdev, struct net_device, class_dev),
-				pkey);
+	ret = ipoib_vlan_delete(to_net_dev(dev), pkey);
 
 	return ret ? ret : count;
 
 }
-static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
+static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
 
 int ipoib_add_pkey_attr(struct net_device *dev)
 {
-	return class_device_create_file(&dev->class_dev,
-					&class_device_attr_pkey);
+	return device_create_file(&dev->dev, &dev_attr_pkey);
 }
 
 static struct net_device *ipoib_add_port(const char *format,
@@ -1083,11 +1082,9 @@ static struct net_device *ipoib_add_port(const char *format,
 
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
-	if (class_device_create_file(&priv->dev->class_dev,
-				     &class_device_attr_create_child))
+	if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
 		goto sysfs_failed;
-	if (class_device_create_file(&priv->dev->class_dev,
-				     &class_device_attr_delete_child))
+	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
 		goto sysfs_failed;
 
 	return priv->dev;

+ 5 - 6
drivers/infiniband/ulp/ipoib/ipoib_vlan.c

@@ -42,15 +42,15 @@
 
 #include "ipoib.h"
 
-static ssize_t show_parent(struct class_device *class_dev, char *buf)
+static ssize_t show_parent(struct device *d, struct device_attribute *attr,
+			   char *buf)
 {
-	struct net_device *dev =
-		container_of(class_dev, struct net_device, class_dev);
+	struct net_device *dev = to_net_dev(d);
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
 	return sprintf(buf, "%s\n", priv->parent->name);
 }
-static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
+static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
 
 int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 {
@@ -118,8 +118,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
 
-	if (class_device_create_file(&priv->dev->class_dev,
-				     &class_device_attr_parent))
+	if (device_create_file(&priv->dev->dev, &dev_attr_parent))
 		goto sysfs_failed;
 
 	list_add_tail(&priv->list, &ppriv->child_intfs);

+ 4 - 2
drivers/input/serio/serio.c

@@ -45,7 +45,7 @@ EXPORT_SYMBOL(serio_interrupt);
 EXPORT_SYMBOL(__serio_register_port);
 EXPORT_SYMBOL(serio_unregister_port);
 EXPORT_SYMBOL(serio_unregister_child_port);
-EXPORT_SYMBOL(serio_register_driver);
+EXPORT_SYMBOL(__serio_register_driver);
 EXPORT_SYMBOL(serio_unregister_driver);
 EXPORT_SYMBOL(serio_open);
 EXPORT_SYMBOL(serio_close);
@@ -789,12 +789,14 @@ static void serio_attach_driver(struct serio_driver *drv)
 			drv->driver.name, error);
 }
 
-int serio_register_driver(struct serio_driver *drv)
+int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
 {
 	int manual_bind = drv->manual_bind;
 	int error;
 
 	drv->driver.bus = &serio_bus;
+	drv->driver.owner = owner;
+	drv->driver.mod_name = mod_name;
 
 	/*
 	 * Temporarily disable automatic binding because probing

+ 1 - 1
drivers/net/arm/at91_ether.c

@@ -641,7 +641,7 @@ static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo
 {
 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
 	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+	strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
 }
 
 static const struct ethtool_ops at91ether_ethtool_ops = {

+ 1 - 1
drivers/net/arm/etherh.c

@@ -587,7 +587,7 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
 {
 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
 	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, dev->class_dev.dev->bus_id,
+	strlcpy(info->bus_info, dev->dev.parent->bus_id,
 		sizeof(info->bus_info));
 }
 

+ 174 - 113
drivers/net/bonding/bond_sysfs.c

@@ -39,8 +39,7 @@
 
 /* #define BONDING_DEBUG 1 */
 #include "bonding.h"
-#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_dev(obj)	container_of(obj,struct device,kobj)
 #define to_bond(cd)	((struct bonding *)(to_net_dev(cd)->priv))
 
 /*---------------------------- Declarations -------------------------------*/
@@ -154,7 +153,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
 				 * If it's > expected, then there's a file open,
 				 * and we have to fail.
 				 */
-				if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
+				if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
 							> expected_refcount){
 					rtnl_unlock();
 					printk(KERN_INFO DRV_NAME
@@ -201,13 +200,13 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
 	int ret = 0;
 
 	/* first, create a link from the slave back to the master */
-	ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
+	ret = sysfs_create_link(&(slave->dev.kobj), &(master->dev.kobj),
 				"master");
 	if (ret)
 		return ret;
 	/* next, create a link from the master to the slave */
 	sprintf(linkname,"slave_%s",slave->name);
-	ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
+	ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
 				linkname);
 	return ret;
 
@@ -217,20 +216,21 @@ void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *s
 {
 	char linkname[IFNAMSIZ+7];
 
-	sysfs_remove_link(&(slave->class_dev.kobj), "master");
+	sysfs_remove_link(&(slave->dev.kobj), "master");
 	sprintf(linkname,"slave_%s",slave->name);
-	sysfs_remove_link(&(master->class_dev.kobj), linkname);
+	sysfs_remove_link(&(master->dev.kobj), linkname);
 }
 
 
 /*
  * Show the slaves in the current bond.
  */
-static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
+static ssize_t bonding_show_slaves(struct device *d,
+				   struct device_attribute *attr, char *buf)
 {
 	struct slave *slave;
 	int i, res = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	read_lock_bh(&bond->lock);
 	bond_for_each_slave(bond, slave, i) {
@@ -254,14 +254,16 @@ static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
  * up for this to succeed.
  * This function is largely the same flow as bonding_update_bonds().
  */
-static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
+static ssize_t bonding_store_slaves(struct device *d,
+				    struct device_attribute *attr,
+				    const char *buffer, size_t count)
 {
 	char command[IFNAMSIZ + 1] = { 0, };
 	char *ifname;
 	int i, res, found, ret = count;
 	struct slave *slave;
 	struct net_device *dev = NULL;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	/* Quick sanity check -- is the bond interface up? */
 	if (!(bond->dev->flags & IFF_UP)) {
@@ -387,25 +389,28 @@ out:
 	return ret;
 }
 
-static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
 
 /*
  * Show and set the bonding mode.  The bond interface must be down to
  * change the mode.
  */
-static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
+static ssize_t bonding_show_mode(struct device *d,
+				 struct device_attribute *attr, char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%s %d\n",
 			bond_mode_tbl[bond->params.mode].modename,
 			bond->params.mode) + 1;
 }
 
-static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_mode(struct device *d,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
 		printk(KERN_ERR DRV_NAME
@@ -438,16 +443,18 @@ static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
 
 /*
  * Show and set the bonding transmit hash method.  The bond interface must be down to
  * change the xmit hash policy.
  */
-static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
+static ssize_t bonding_show_xmit_hash(struct device *d,
+				      struct device_attribute *attr,
+				      char *buf)
 {
 	int count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if ((bond->params.mode != BOND_MODE_XOR) &&
 	    (bond->params.mode != BOND_MODE_8023AD)) {
@@ -462,10 +469,12 @@ static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
 	return count;
 }
 
-static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_xmit_hash(struct device *d,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
 		printk(KERN_ERR DRV_NAME
@@ -501,24 +510,28 @@ static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf,
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
 
 /*
  * Show and set arp_validate.
  */
-static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf)
+static ssize_t bonding_show_arp_validate(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%s %d\n",
 		       arp_validate_tbl[bond->params.arp_validate].modename,
 		       bond->params.arp_validate) + 1;
 }
 
-static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_arp_validate(struct device *d,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
 {
 	int new_value;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
 	if (new_value < 0) {
@@ -548,7 +561,7 @@ static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *b
 	return count;
 }
 
-static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
+static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
 
 /*
  * Show and set the arp timer interval.  There are two tricky bits
@@ -556,17 +569,21 @@ static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_valid
  * MII monitoring.  Second, if the ARP timer isn't running, we must
  * start it.
  */
-static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
+static ssize_t bonding_show_arp_interval(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
 }
 
-static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_arp_interval(struct device *d,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
 		printk(KERN_ERR DRV_NAME
@@ -638,15 +655,17 @@ static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *b
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
 
 /*
  * Show and set the arp targets.
  */
-static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
+static ssize_t bonding_show_arp_targets(struct device *d,
+					struct device_attribute *attr,
+					char *buf)
 {
 	int i, res = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
 		if (bond->params.arp_targets[i])
@@ -660,11 +679,13 @@ static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
 	return res;
 }
 
-static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_arp_targets(struct device *d,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
 {
 	u32 newtarget;
 	int i = 0, done = 0, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 	u32 *targets;
 
 	targets = bond->params.arp_targets;
@@ -742,24 +763,28 @@ static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *bu
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
+static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
 
 /*
  * Show and set the up and down delays.  These must be multiples of the
  * MII monitoring value, and are stored internally as the multiplier.
  * Thus, we must translate to MS for the real world.
  */
-static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
+static ssize_t bonding_show_downdelay(struct device *d,
+				      struct device_attribute *attr,
+				      char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
 }
 
-static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_downdelay(struct device *d,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (!(bond->params.miimon)) {
 		printk(KERN_ERR DRV_NAME
@@ -800,20 +825,24 @@ static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf,
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
 
-static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
+static ssize_t bonding_show_updelay(struct device *d,
+				    struct device_attribute *attr,
+				    char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
 
 }
 
-static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_updelay(struct device *d,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (!(bond->params.miimon)) {
 		printk(KERN_ERR DRV_NAME
@@ -854,25 +883,29 @@ static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, s
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
 
 /*
  * Show and set the LACP interval.  Interface must be down, and the mode
  * must be set to 802.3ad mode.
  */
-static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
+static ssize_t bonding_show_lacp(struct device *d,
+				 struct device_attribute *attr,
+				 char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%s %d\n",
 		bond_lacp_tbl[bond->params.lacp_fast].modename,
 		bond->params.lacp_fast) + 1;
 }
 
-static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_lacp(struct device *d,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
 		printk(KERN_ERR DRV_NAME
@@ -906,7 +939,7 @@ static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
 
 /*
  * Show and set the MII monitor interval.  There are two tricky bits
@@ -914,17 +947,21 @@ static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bondin
  * ARP monitoring.  Second, if the timer isn't running, we must
  * start it.
  */
-static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
+static ssize_t bonding_show_miimon(struct device *d,
+				   struct device_attribute *attr,
+				   char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%d\n", bond->params.miimon) + 1;
 }
 
-static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_miimon(struct device *d,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
 		printk(KERN_ERR DRV_NAME
@@ -1000,7 +1037,7 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
 out:
 	return ret;
 }
-static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
 
 /*
  * Show and set the primary slave.  The store function is much
@@ -1009,10 +1046,12 @@ static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding
  * The bond must be a mode that supports a primary for this be
  * set.
  */
-static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
+static ssize_t bonding_show_primary(struct device *d,
+				    struct device_attribute *attr,
+				    char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->primary_slave)
 		count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
@@ -1022,11 +1061,13 @@ static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
 	return count;
 }
 
-static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_primary(struct device *d,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
 {
 	int i;
 	struct slave *slave;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	write_lock_bh(&bond->lock);
 	if (!USES_PRIMARY(bond->params.mode)) {
@@ -1065,22 +1106,26 @@ out:
 	write_unlock_bh(&bond->lock);
 	return count;
 }
-static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
 
 /*
  * Show and set the use_carrier flag.
  */
-static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
+static ssize_t bonding_show_carrier(struct device *d,
+				    struct device_attribute *attr,
+				    char *buf)
 {
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
 }
 
-static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_carrier(struct device *d,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
 {
 	int new_value, ret = count;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
@@ -1102,16 +1147,18 @@ static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, s
 out:
 	return count;
 }
-static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
 
 
 /*
  * Show and set currently active_slave.
  */
-static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
+static ssize_t bonding_show_active_slave(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
 {
 	struct slave *curr;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 	int count;
 
 
@@ -1126,13 +1173,15 @@ static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
 	return count;
 }
 
-static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
+static ssize_t bonding_store_active_slave(struct device *d,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
 {
 	int i;
 	struct slave *slave;
         struct slave *old_active = NULL;
         struct slave *new_active = NULL;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	write_lock_bh(&bond->lock);
 	if (!USES_PRIMARY(bond->params.mode)) {
@@ -1194,16 +1243,18 @@ out:
 	return count;
 
 }
-static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
 
 
 /*
  * Show link status of the bond interface.
  */
-static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
+static ssize_t bonding_show_mii_status(struct device *d,
+				       struct device_attribute *attr,
+				       char *buf)
 {
 	struct slave *curr;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	read_lock(&bond->curr_slave_lock);
 	curr = bond->curr_active_slave;
@@ -1211,16 +1262,18 @@ static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
 
 	return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
 }
-static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
+static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
 
 
 /*
  * Show current 802.3ad aggregator ID.
  */
-static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
+static ssize_t bonding_show_ad_aggregator(struct device *d,
+					  struct device_attribute *attr,
+					  char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
@@ -1231,16 +1284,18 @@ static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
+static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
 
 
 /*
  * Show number of active 802.3ad ports.
  */
-static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
+static ssize_t bonding_show_ad_num_ports(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
@@ -1251,16 +1306,18 @@ static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
+static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
 
 
 /*
  * Show current 802.3ad actor key.
  */
-static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
+static ssize_t bonding_show_ad_actor_key(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
@@ -1271,16 +1328,18 @@ static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
+static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
 
 
 /*
  * Show current 802.3ad partner key.
  */
-static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
+static ssize_t bonding_show_ad_partner_key(struct device *d,
+					   struct device_attribute *attr,
+					   char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
@@ -1291,16 +1350,18 @@ static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
+static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
 
 
 /*
  * Show current 802.3ad partner mac.
  */
-static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
+static ssize_t bonding_show_ad_partner_mac(struct device *d,
+					   struct device_attribute *attr,
+					   char *buf)
 {
 	int count = 0;
-	struct bonding *bond = to_bond(cd);
+	struct bonding *bond = to_bond(d);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
@@ -1319,30 +1380,30 @@ static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
+static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
 
 
 
 static struct attribute *per_bond_attrs[] = {
-	&class_device_attr_slaves.attr,
-	&class_device_attr_mode.attr,
-	&class_device_attr_arp_validate.attr,
-	&class_device_attr_arp_interval.attr,
-	&class_device_attr_arp_ip_target.attr,
-	&class_device_attr_downdelay.attr,
-	&class_device_attr_updelay.attr,
-	&class_device_attr_lacp_rate.attr,
-	&class_device_attr_xmit_hash_policy.attr,
-	&class_device_attr_miimon.attr,
-	&class_device_attr_primary.attr,
-	&class_device_attr_use_carrier.attr,
-	&class_device_attr_active_slave.attr,
-	&class_device_attr_mii_status.attr,
-	&class_device_attr_ad_aggregator.attr,
-	&class_device_attr_ad_num_ports.attr,
-	&class_device_attr_ad_actor_key.attr,
-	&class_device_attr_ad_partner_key.attr,
-	&class_device_attr_ad_partner_mac.attr,
+	&dev_attr_slaves.attr,
+	&dev_attr_mode.attr,
+	&dev_attr_arp_validate.attr,
+	&dev_attr_arp_interval.attr,
+	&dev_attr_arp_ip_target.attr,
+	&dev_attr_downdelay.attr,
+	&dev_attr_updelay.attr,
+	&dev_attr_lacp_rate.attr,
+	&dev_attr_xmit_hash_policy.attr,
+	&dev_attr_miimon.attr,
+	&dev_attr_primary.attr,
+	&dev_attr_use_carrier.attr,
+	&dev_attr_active_slave.attr,
+	&dev_attr_mii_status.attr,
+	&dev_attr_ad_aggregator.attr,
+	&dev_attr_ad_num_ports.attr,
+	&dev_attr_ad_actor_key.attr,
+	&dev_attr_ad_partner_key.attr,
+	&dev_attr_ad_partner_mac.attr,
 	NULL,
 };
 
@@ -1367,7 +1428,7 @@ int bond_create_sysfs(void)
 	if (!firstbond)
 		return -ENODEV;
 
-	netdev_class = firstbond->dev->class_dev.class;
+	netdev_class = firstbond->dev->dev.class;
 	if (!netdev_class)
 		return -ENODEV;
 
@@ -1410,13 +1471,13 @@ int bond_create_sysfs_entry(struct bonding *bond)
 	struct net_device *dev = bond->dev;
 	int err;
 
-	err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
+	err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
 	if (err) {
 		printk(KERN_EMERG "eek! didn't create group!\n");
 	}
 
 	if (expected_refcount < 1)
-		expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
+		expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount);
 
 	return err;
 }
@@ -1427,6 +1488,6 @@ void bond_destroy_sysfs_entry(struct bonding *bond)
 {
 	struct net_device *dev = bond->dev;
 
-	sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
+	sysfs_remove_group(&(dev->dev.kobj), &bonding_group);
 }
 

+ 1 - 1
drivers/net/iseries_veth.c

@@ -1102,7 +1102,7 @@ static struct net_device * __init veth_probe_one(int vlan,
 	}
 
 	kobject_init(&port->kobject);
-	port->kobject.parent = &dev->class_dev.kobj;
+	port->kobject.parent = &dev->dev.kobj;
 	port->kobject.ktype  = &veth_port_ktype;
 	kobject_set_name(&port->kobject, "veth_port");
 	if (0 != kobject_add(&port->kobject))

+ 18 - 18
drivers/net/macb.c

@@ -27,8 +27,6 @@
 
 #include "macb.h"
 
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-
 #define RX_BUFFER_SIZE		128
 #define RX_RING_SIZE		512
 #define RX_RING_BYTES		(sizeof(struct dma_desc) * RX_RING_SIZE)
@@ -945,10 +943,10 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	return ret;
 }
 
-static ssize_t macb_mii_show(const struct class_device *cd, char *buf,
+static ssize_t macb_mii_show(const struct device *_dev, char *buf,
 			unsigned long addr)
 {
-	struct net_device *dev = to_net_dev(cd);
+	struct net_device *dev = to_net_dev(_dev);
 	struct macb *bp = netdev_priv(dev);
 	ssize_t ret = -EINVAL;
 
@@ -962,11 +960,13 @@ static ssize_t macb_mii_show(const struct class_device *cd, char *buf,
 }
 
 #define MII_ENTRY(name, addr)					\
-static ssize_t show_##name(struct class_device *cd, char *buf)	\
+static ssize_t show_##name(struct device *_dev,			\
+			   struct device_attribute *attr,	\
+			   char *buf)				\
 {								\
-	return macb_mii_show(cd, buf, addr);			\
+	return macb_mii_show(_dev, buf, addr);			\
 }								\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
 MII_ENTRY(bmcr, MII_BMCR);
 MII_ENTRY(bmsr, MII_BMSR);
@@ -977,13 +977,13 @@ MII_ENTRY(lpa, MII_LPA);
 MII_ENTRY(expansion, MII_EXPANSION);
 
 static struct attribute *macb_mii_attrs[] = {
-	&class_device_attr_bmcr.attr,
-	&class_device_attr_bmsr.attr,
-	&class_device_attr_physid1.attr,
-	&class_device_attr_physid2.attr,
-	&class_device_attr_advertise.attr,
-	&class_device_attr_lpa.attr,
-	&class_device_attr_expansion.attr,
+	&dev_attr_bmcr.attr,
+	&dev_attr_bmsr.attr,
+	&dev_attr_physid1.attr,
+	&dev_attr_physid2.attr,
+	&dev_attr_advertise.attr,
+	&dev_attr_lpa.attr,
+	&dev_attr_expansion.attr,
 	NULL,
 };
 
@@ -994,17 +994,17 @@ static struct attribute_group macb_mii_group = {
 
 static void macb_unregister_sysfs(struct net_device *net)
 {
-	struct class_device *class_dev = &net->class_dev;
+	struct device *_dev = &net->dev;
 
-	sysfs_remove_group(&class_dev->kobj, &macb_mii_group);
+	sysfs_remove_group(&_dev->kobj, &macb_mii_group);
 }
 
 static int macb_register_sysfs(struct net_device *net)
 {
-	struct class_device *class_dev = &net->class_dev;
+	struct device *_dev = &net->dev;
 	int ret;
 
-	ret = sysfs_create_group(&class_dev->kobj, &macb_mii_group);
+	ret = sysfs_create_group(&_dev->kobj, &macb_mii_group);
 	if (ret)
 		printk(KERN_WARNING
 		       "%s: sysfs mii attribute registration failed: %d\n",

+ 1 - 1
drivers/net/smc911x.c

@@ -1659,7 +1659,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	strncpy(info->driver, CARDNAME, sizeof(info->driver));
 	strncpy(info->version, version, sizeof(info->version));
-	strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
 }
 
 static int smc911x_ethtool_nwayreset(struct net_device *dev)

+ 1 - 1
drivers/net/smc91x.c

@@ -1712,7 +1712,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	strncpy(info->driver, CARDNAME, sizeof(info->driver));
 	strncpy(info->version, version, sizeof(info->version));
-	strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
 }
 
 static int smc_ethtool_nwayreset(struct net_device *dev)

+ 1 - 1
drivers/net/wireless/hostap/hostap_main.c

@@ -84,7 +84,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
 	if (strchr(dev->name, '%'))
 		ret = dev_alloc_name(dev, dev->name);
 
-	SET_NETDEV_DEV(dev, mdev->class_dev.dev);
+	SET_NETDEV_DEV(dev, mdev->dev.parent);
 	if (ret >= 0)
 		ret = register_netdevice(dev);
 

+ 2 - 2
drivers/net/wireless/orinoco.c

@@ -4293,8 +4293,8 @@ static void orinoco_get_drvinfo(struct net_device *dev,
 	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
 	strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
 	strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
-	if (dev->class_dev.dev)
-		strncpy(info->bus_info, dev->class_dev.dev->bus_id,
+	if (dev->dev.parent)
+		strncpy(info->bus_info, dev->dev.parent->bus_id,
 			sizeof(info->bus_info) - 1);
 	else
 		snprintf(info->bus_info, sizeof(info->bus_info) - 1,

+ 1 - 1
drivers/net/wireless/orinoco_cs.c

@@ -332,7 +332,7 @@ orinoco_cs_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
+	       "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
 	       link->irq.AssignedIRQ, link->io.BasePort1,
 	       link->io.BasePort1 + link->io.NumPorts1 - 1);
 

+ 1 - 1
drivers/net/wireless/spectrum_cs.c

@@ -806,7 +806,7 @@ spectrum_cs_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
+	       "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
 	       link->irq.AssignedIRQ, link->io.BasePort1,
 	       link->io.BasePort1 + link->io.NumPorts1 - 1);
 

+ 3 - 1
drivers/pci/pci-driver.c

@@ -422,7 +422,8 @@ static struct kobj_type pci_driver_kobj_type = {
  * If no error occurred, the driver remains registered even if 
  * no device was claimed during registration.
  */
-int __pci_register_driver(struct pci_driver *drv, struct module *owner)
+int __pci_register_driver(struct pci_driver *drv, struct module *owner,
+			  const char *mod_name)
 {
 	int error;
 
@@ -430,6 +431,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
 	drv->driver.name = drv->name;
 	drv->driver.bus = &pci_bus_type;
 	drv->driver.owner = owner;
+	drv->driver.mod_name = mod_name;
 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
 
 	if (pci_multithread_probe)

+ 17 - 17
drivers/pcmcia/cs.c

@@ -110,7 +110,7 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
 
 	down_read(&pcmcia_socket_list_rwsem);
 	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
-		if (socket->dev.dev != dev)
+		if (socket->dev.parent != dev)
 			continue;
 		mutex_lock(&socket->skt_mutex);
 		socket_suspend(socket);
@@ -128,7 +128,7 @@ int pcmcia_socket_dev_resume(struct device *dev)
 
 	down_read(&pcmcia_socket_list_rwsem);
 	list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
-		if (socket->dev.dev != dev)
+		if (socket->dev.parent != dev)
 			continue;
 		mutex_lock(&socket->skt_mutex);
 		socket_resume(socket);
@@ -143,12 +143,12 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
 
 struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
 {
-	struct class_device *cl_dev = class_device_get(&skt->dev);
-	if (!cl_dev)
+	struct device *dev = get_device(&skt->dev);
+	if (!dev)
 		return NULL;
-	skt = class_get_devdata(cl_dev);
+	skt = dev_get_drvdata(dev);
 	if (!try_module_get(skt->owner)) {
-		class_device_put(&skt->dev);
+		put_device(&skt->dev);
 		return NULL;
 	}
 	return (skt);
@@ -159,14 +159,14 @@ EXPORT_SYMBOL(pcmcia_get_socket);
 void pcmcia_put_socket(struct pcmcia_socket *skt)
 {
 	module_put(skt->owner);
-	class_device_put(&skt->dev);
+	put_device(&skt->dev);
 }
 EXPORT_SYMBOL(pcmcia_put_socket);
 
 
-static void pcmcia_release_socket(struct class_device *class_dev)
+static void pcmcia_release_socket(struct device *dev)
 {
-	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+	struct pcmcia_socket *socket = dev_get_drvdata(dev);
 
 	complete(&socket->socket_released);
 }
@@ -181,7 +181,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
 	struct task_struct *tsk;
 	int ret;
 
-	if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops)
+	if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
 		return -EINVAL;
 
 	cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
@@ -226,9 +226,9 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
 #endif
 
 	/* set proper values in socket->dev */
-	socket->dev.class_data = socket;
+	dev_set_drvdata(&socket->dev, socket);
 	socket->dev.class = &pcmcia_socket_class;
-	snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
+	snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
 
 	/* base address = 0, map = 0 */
 	socket->cis_mem.flags = 0;
@@ -640,7 +640,7 @@ static int pccardd(void *__skt)
 	skt->ops->set_socket(skt, &skt->socket);
 
 	/* register with the device core */
-	ret = class_device_register(&skt->dev);
+	ret = device_register(&skt->dev);
 	if (ret) {
 		printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
 			skt);
@@ -689,7 +689,7 @@ static int pccardd(void *__skt)
 	remove_wait_queue(&skt->thread_wait, &wait);
 
 	/* remove from the device core */
-	class_device_unregister(&skt->dev);
+	device_unregister(&skt->dev);
 
 	return 0;
 }
@@ -904,7 +904,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
 EXPORT_SYMBOL(pcmcia_insert_card);
 
 
-static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
+static int pcmcia_socket_uevent(struct device *dev, char **envp,
 			        int num_envp, char *buffer, int buffer_size)
 {
 	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
@@ -930,8 +930,8 @@ static void pcmcia_release_socket_class(struct class *data)
 
 struct class pcmcia_socket_class = {
 	.name = "pcmcia_socket",
-	.uevent = pcmcia_socket_uevent,
-	.release = pcmcia_release_socket,
+	.dev_uevent = pcmcia_socket_uevent,
+	.dev_release = pcmcia_release_socket,
 	.class_release = pcmcia_release_socket_class,
 };
 EXPORT_SYMBOL(pcmcia_socket_class);

+ 2 - 2
drivers/pcmcia/cs_internal.h

@@ -142,7 +142,7 @@ struct pcmcia_callback{
 
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
 
-#define cs_socket_name(skt)	((skt)->dev.class_id)
+#define cs_socket_name(skt)	((skt)->dev.bus_id)
 
 #ifdef DEBUG
 extern int cs_debug_level(int);
@@ -158,6 +158,6 @@ extern int cs_debug_level(int);
 #endif
 
 #define cs_err(skt, fmt, arg...) \
-	printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.class_id , ## arg)
+	printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
 
 #endif /* _LINUX_CS_INTERNAL_H */

+ 7 - 7
drivers/pcmcia/ds.c

@@ -572,7 +572,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
 	p_dev->func   = function;
 
 	p_dev->dev.bus = &pcmcia_bus_type;
-	p_dev->dev.parent = s->dev.dev;
+	p_dev->dev.parent = s->dev.parent;
 	p_dev->dev.release = pcmcia_release_dev;
 	bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
 
@@ -1328,10 +1328,10 @@ static struct pcmcia_callback pcmcia_bus_callback = {
 	.resume = pcmcia_bus_resume,
 };
 
-static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
+static int __devinit pcmcia_bus_add_socket(struct device *dev,
 					   struct class_interface *class_intf)
 {
-	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+	struct pcmcia_socket *socket = dev_get_drvdata(dev);
 	int ret;
 
 	socket = pcmcia_get_socket(socket);
@@ -1364,10 +1364,10 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
 	return 0;
 }
 
-static void pcmcia_bus_remove_socket(struct class_device *class_dev,
+static void pcmcia_bus_remove_socket(struct device *dev,
 				     struct class_interface *class_intf)
 {
-	struct pcmcia_socket *socket = class_get_devdata(class_dev);
+	struct pcmcia_socket *socket = dev_get_drvdata(dev);
 
 	if (!socket)
 		return;
@@ -1389,8 +1389,8 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev,
 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
 static struct class_interface pcmcia_bus_interface = {
 	.class = &pcmcia_socket_class,
-	.add = &pcmcia_bus_add_socket,
-	.remove = &pcmcia_bus_remove_socket,
+	.add_dev = &pcmcia_bus_add_socket,
+	.remove_dev = &pcmcia_bus_remove_socket,
 };
 
 

+ 1 - 1
drivers/pcmcia/i82092.c

@@ -161,7 +161,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
 	pci_set_drvdata(dev, &sockets[i].socket);
 
 	for (i = 0; i<socket_count; i++) {
-		sockets[i].socket.dev.dev = &dev->dev;
+		sockets[i].socket.dev.parent = &dev->dev;
 		sockets[i].socket.ops = &i82092aa_operations;
 		sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
 		ret = pcmcia_register_socket(&sockets[i].socket);

+ 1 - 1
drivers/pcmcia/i82365.c

@@ -1298,7 +1298,7 @@ static int __init init_i82365(void)
     
     /* register sockets with the pcmcia core */
     for (i = 0; i < sockets; i++) {
-	    socket[i].socket.dev.dev = &i82365_device->dev;
+	    socket[i].socket.dev.parent = &i82365_device->dev;
 	    socket[i].socket.ops = &pcic_operations;
 	    socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 	    socket[i].socket.owner = THIS_MODULE;

+ 0 - 1
drivers/pcmcia/pcmcia_ioctl.c

@@ -59,7 +59,6 @@ typedef struct user_info_t {
 
 #ifdef DEBUG
 extern int ds_pc_debug;
-#define cs_socket_name(skt)    ((skt)->dev.class_id)
 
 #define ds_dbg(lvl, fmt, arg...) do {		\
 	if (ds_pc_debug >= lvl)				\

+ 0 - 1
drivers/pcmcia/pcmcia_resource.c

@@ -48,7 +48,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
 
 #ifdef DEBUG
 extern int ds_pc_debug;
-#define cs_socket_name(skt)    ((skt)->dev.class_id)
 
 #define ds_dbg(skt, lvl, fmt, arg...) do {			\
 	if (ds_pc_debug >= lvl)					\

+ 1 - 1
drivers/pcmcia/pd6729.c

@@ -682,7 +682,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 
 		socket[i].socket.ops = &pd6729_operations;
 		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
-		socket[i].socket.dev.dev = &dev->dev;
+		socket[i].socket.dev.parent = &dev->dev;
 		socket[i].socket.driver_data = &socket[i];
 	}
 

+ 31 - 25
drivers/pcmcia/rsrc_nonstatic.c

@@ -616,7 +616,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 		   unsigned long align, struct pcmcia_socket *s)
 {
-	struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
+	struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.bus_id);
 	struct socket_data *s_data = s->resource_data;
 	struct pcmcia_align_data data;
 	unsigned long min = base;
@@ -650,7 +650,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
 		u_long align, int low, struct pcmcia_socket *s)
 {
-	struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
+	struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.bus_id);
 	struct socket_data *s_data = s->resource_data;
 	struct pcmcia_align_data data;
 	unsigned long min, max;
@@ -897,9 +897,10 @@ EXPORT_SYMBOL(pccard_nonstatic_ops);
 
 /* sysfs interface to the resource database */
 
-static ssize_t show_io_db(struct class_device *class_dev, char *buf)
+static ssize_t show_io_db(struct device *dev,
+			  struct device_attribute *attr, char *buf)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
 	struct socket_data *data;
 	struct resource_map *p;
 	ssize_t ret = 0;
@@ -920,9 +921,11 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
 	return (ret);
 }
 
-static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
+static ssize_t store_io_db(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
 	unsigned long start_addr, end_addr;
 	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
@@ -947,11 +950,12 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
+static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
 
-static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
+static ssize_t show_mem_db(struct device *dev,
+			   struct device_attribute *attr, char *buf)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
 	struct socket_data *data;
 	struct resource_map *p;
 	ssize_t ret = 0;
@@ -972,9 +976,11 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
 	return (ret);
 }
 
-static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
+static ssize_t store_mem_db(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
 	unsigned long start_addr, end_addr;
 	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
@@ -999,25 +1005,25 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
+static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
 
-static struct class_device_attribute *pccard_rsrc_attributes[] = {
-	&class_device_attr_available_resources_io,
-	&class_device_attr_available_resources_mem,
+static struct device_attribute *pccard_rsrc_attributes[] = {
+	&dev_attr_available_resources_io,
+	&dev_attr_available_resources_mem,
 	NULL,
 };
 
-static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
+static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
 					   struct class_interface *class_intf)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
-	struct class_device_attribute **attr;
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
+	struct device_attribute **attr;
 	int ret = 0;
 	if (s->resource_ops != &pccard_nonstatic_ops)
 		return 0;
 
 	for (attr = pccard_rsrc_attributes; *attr; attr++) {
-		ret = class_device_create_file(class_dev, *attr);
+		ret = device_create_file(dev, *attr);
 		if (ret)
 			break;
 	}
@@ -1025,23 +1031,23 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
 	return ret;
 }
 
-static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
+static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
 					       struct class_interface *class_intf)
 {
-	struct pcmcia_socket *s = class_get_devdata(class_dev);
-	struct class_device_attribute **attr;
+	struct pcmcia_socket *s = dev_get_drvdata(dev);
+	struct device_attribute **attr;
 
 	if (s->resource_ops != &pccard_nonstatic_ops)
 		return;
 
 	for (attr = pccard_rsrc_attributes; *attr; attr++)
-		class_device_remove_file(class_dev, *attr);
+		device_remove_file(dev, *attr);
 }
 
 static struct class_interface pccard_rsrc_interface = {
 	.class = &pcmcia_socket_class,
-	.add = &pccard_sysfs_add_rsrc,
-	.remove = __devexit_p(&pccard_sysfs_remove_rsrc),
+	.add_dev = &pccard_sysfs_add_rsrc,
+	.remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
 };
 
 static int __init nonstatic_sysfs_init(void)

+ 3 - 3
drivers/pcmcia/soc_common.c

@@ -478,10 +478,10 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
  *
  * Returns: the number of characters added to the buffer
  */
-static ssize_t show_status(struct class_device *class_dev, char *buf)
+static ssize_t show_status(struct device *dev, char *buf)
 {
 	struct soc_pcmcia_socket *skt =
-		container_of(class_dev, struct soc_pcmcia_socket, socket.dev);
+		container_of(dev, struct soc_pcmcia_socket, socket.dev);
 	char *p = buf;
 
 	p+=sprintf(p, "slot     : %d\n", skt->nr);
@@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
 		add_timer(&skt->poll_timer);
 
-		class_device_create_file(&skt->socket.dev, &class_device_attr_status);
+		device_create_file(&skt->socket.dev, &device_attr_status);
 	}
 
 	dev_set_drvdata(dev, sinfo);

+ 61 - 43
drivers/pcmcia/socket_sysfs.c

@@ -40,7 +40,8 @@
 
 #define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
 
-static ssize_t pccard_show_type(struct class_device *dev, char *buf)
+static ssize_t pccard_show_type(struct device *dev, struct device_attribute *attr,
+				char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 
@@ -50,9 +51,10 @@ static ssize_t pccard_show_type(struct class_device *dev, char *buf)
 		return sprintf(buf, "32-bit\n");
 	return sprintf(buf, "16-bit\n");
 }
-static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
+static DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
 
-static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
+static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute *attr,
+				   char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 
@@ -63,28 +65,31 @@ static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
 			       s->socket.Vcc % 10);
 	return sprintf(buf, "X.XV\n");
 }
-static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
+static DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
 
-static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
+static ssize_t pccard_show_vpp(struct device *dev, struct device_attribute *attr,
+			       char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
 }
-static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
+static DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
 
-static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
+static ssize_t pccard_show_vcc(struct device *dev, struct device_attribute *attr,
+			       char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
 }
-static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
+static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
 
 
-static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
+static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,
+				   const char *buf, size_t count)
 {
 	ssize_t ret;
 	struct pcmcia_socket *s = to_socket(dev);
@@ -96,16 +101,20 @@ static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, si
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
+static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
 
 
-static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf)
+static ssize_t pccard_show_card_pm_state(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 	return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on");
 }
 
-static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count)
+static ssize_t pccard_store_card_pm_state(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
 {
 	ssize_t ret = -EINVAL;
 	struct pcmcia_socket *s = to_socket(dev);
@@ -120,9 +129,11 @@ static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *
 
 	return ret ? -ENODEV : count;
 }
-static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
+static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
 
-static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count)
+static ssize_t pccard_store_eject(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	ssize_t ret;
 	struct pcmcia_socket *s = to_socket(dev);
@@ -134,16 +145,20 @@ static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, siz
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
+static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
 
 
-static ssize_t pccard_show_irq_mask(struct class_device *dev, char *buf)
+static ssize_t pccard_show_irq_mask(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 	return sprintf(buf, "0x%04x\n", s->irq_mask);
 }
 
-static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf, size_t count)
+static ssize_t pccard_store_irq_mask(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
 {
 	ssize_t ret;
 	struct pcmcia_socket *s = to_socket(dev);
@@ -161,16 +176,19 @@ static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf,
 
 	return ret ? ret : count;
 }
-static CLASS_DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
+static DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
 
 
-static ssize_t pccard_show_resource(struct class_device *dev, char *buf)
+static ssize_t pccard_show_resource(struct device *dev,
+				    struct device_attribute *attr, char *buf)
 {
 	struct pcmcia_socket *s = to_socket(dev);
 	return sprintf(buf, "%s\n", s->resource_setup_done ? "yes" : "no");
 }
 
-static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, size_t count)
+static ssize_t pccard_store_resource(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
 {
 	unsigned long flags;
 	struct pcmcia_socket *s = to_socket(dev);
@@ -196,7 +214,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
 
 	return count;
 }
-static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
+static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 
 
 static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
@@ -279,7 +297,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
 		if (off + count > size)
 			count = size - off;
 
-		s = to_socket(container_of(kobj, struct class_device, kobj));
+		s = to_socket(container_of(kobj, struct device, kobj));
 
 		if (!(s->state & SOCKET_PRESENT))
 			return -ENODEV;
@@ -296,7 +314,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
 
 static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
-	struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj));
+	struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
 	cisdump_t *cis;
 	int error;
 
@@ -335,16 +353,16 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
 }
 
 
-static struct class_device_attribute *pccard_socket_attributes[] = {
-	&class_device_attr_card_type,
-	&class_device_attr_card_voltage,
-	&class_device_attr_card_vpp,
-	&class_device_attr_card_vcc,
-	&class_device_attr_card_insert,
-	&class_device_attr_card_pm_state,
-	&class_device_attr_card_eject,
-	&class_device_attr_card_irq_mask,
-	&class_device_attr_available_resources_setup_done,
+static struct device_attribute *pccard_socket_attributes[] = {
+	&dev_attr_card_type,
+	&dev_attr_card_voltage,
+	&dev_attr_card_vpp,
+	&dev_attr_card_vcc,
+	&dev_attr_card_insert,
+	&dev_attr_card_pm_state,
+	&dev_attr_card_eject,
+	&dev_attr_card_irq_mask,
+	&dev_attr_available_resources_setup_done,
 	NULL,
 };
 
@@ -355,35 +373,35 @@ static struct bin_attribute pccard_cis_attr = {
 	.write = pccard_store_cis,
 };
 
-static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
+static int __devinit pccard_sysfs_add_socket(struct device *dev,
 					     struct class_interface *class_intf)
 {
-	struct class_device_attribute **attr;
+	struct device_attribute **attr;
 	int ret = 0;
 
 	for (attr = pccard_socket_attributes; *attr; attr++) {
-		ret = class_device_create_file(class_dev, *attr);
+		ret = device_create_file(dev, *attr);
 		if (ret)
 			break;
 	}
 	if (!ret)
-		ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr);
+		ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
 
 	return ret;
 }
 
-static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
+static void __devexit pccard_sysfs_remove_socket(struct device *dev,
 						 struct class_interface *class_intf)
 {
-	struct class_device_attribute **attr;
+	struct device_attribute **attr;
 
-	sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr);
+	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
 	for (attr = pccard_socket_attributes; *attr; attr++)
-		class_device_remove_file(class_dev, *attr);
+		device_remove_file(dev, *attr);
 }
 
 struct class_interface pccard_sysfs_interface = {
 	.class = &pcmcia_socket_class,
-	.add = &pccard_sysfs_add_socket,
-	.remove = __devexit_p(&pccard_sysfs_remove_socket),
+	.add_dev = &pccard_sysfs_add_socket,
+	.remove_dev = __devexit_p(&pccard_sysfs_remove_socket),
 };

+ 1 - 1
drivers/pcmcia/tcic.c

@@ -512,7 +512,7 @@ static int __init init_tcic(void)
     for (i = 0; i < sockets; i++) {
 	    socket_table[i].socket.ops = &tcic_operations;
 	    socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
-	    socket_table[i].socket.dev.dev = &tcic_device.dev;
+	    socket_table[i].socket.dev.parent = &tcic_device.dev;
 	    ret = pcmcia_register_socket(&socket_table[i].socket);
 	    if (ret && i)
 		    pcmcia_unregister_socket(&socket_table[0].socket);

+ 1 - 1
drivers/pcmcia/yenta_socket.c

@@ -1104,7 +1104,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
 	/* prepare pcmcia_socket */
 	socket->socket.ops = &yenta_socket_operations;
 	socket->socket.resource_ops = &pccard_nonstatic_ops;
-	socket->socket.dev.dev = &dev->dev;
+	socket->socket.dev.parent = &dev->dev;
 	socket->socket.driver_data = socket;
 	socket->socket.owner = THIS_MODULE;
 	socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;

+ 1 - 1
drivers/spi/pxa2xx_spi.c

@@ -1234,7 +1234,7 @@ static int init_queue(struct driver_data *drv_data)
 
 	INIT_WORK(&drv_data->pump_messages, pump_messages);
 	drv_data->workqueue = create_singlethread_workqueue(
-					drv_data->master->cdev.dev->bus_id);
+					drv_data->master->dev.parent->bus_id);
 	if (drv_data->workqueue == NULL)
 		return -EBUSY;
 

+ 16 - 16
drivers/spi/spi.c

@@ -193,7 +193,7 @@ struct spi_device *__init_or_module
 spi_new_device(struct spi_master *master, struct spi_board_info *chip)
 {
 	struct spi_device	*proxy;
-	struct device		*dev = master->cdev.dev;
+	struct device		*dev = &master->dev;
 	int			status;
 
 	/* NOTE:  caller did any chip->bus_num checks necessary */
@@ -215,7 +215,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip)
 	proxy->modalias = chip->modalias;
 
 	snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
-			"%s.%u", master->cdev.class_id,
+			"%s.%u", master->dev.bus_id,
 			chip->chip_select);
 	proxy->dev.parent = dev;
 	proxy->dev.bus = &spi_bus_type;
@@ -290,7 +290,7 @@ static void __init_or_module
 scan_boardinfo(struct spi_master *master)
 {
 	struct boardinfo	*bi;
-	struct device		*dev = master->cdev.dev;
+	struct device		*dev = master->dev.parent;
 
 	down(&board_lock);
 	list_for_each_entry(bi, &board_list, list) {
@@ -319,18 +319,18 @@ scan_boardinfo(struct spi_master *master)
 
 /*-------------------------------------------------------------------------*/
 
-static void spi_master_release(struct class_device *cdev)
+static void spi_master_release(struct device *dev)
 {
 	struct spi_master *master;
 
-	master = container_of(cdev, struct spi_master, cdev);
+	master = container_of(dev, struct spi_master, dev);
 	kfree(master);
 }
 
 static struct class spi_master_class = {
 	.name		= "spi_master",
 	.owner		= THIS_MODULE,
-	.release	= spi_master_release,
+	.dev_release	= spi_master_release,
 };
 
 
@@ -364,9 +364,9 @@ spi_alloc_master(struct device *dev, unsigned size)
 	if (!master)
 		return NULL;
 
-	class_device_initialize(&master->cdev);
-	master->cdev.class = &spi_master_class;
-	master->cdev.dev = get_device(dev);
+	device_initialize(&master->dev);
+	master->dev.class = &spi_master_class;
+	master->dev.parent = get_device(dev);
 	spi_master_set_devdata(master, &master[1]);
 
 	return master;
@@ -396,7 +396,7 @@ int __init_or_module
 spi_register_master(struct spi_master *master)
 {
 	static atomic_t		dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
-	struct device		*dev = master->cdev.dev;
+	struct device		*dev = master->dev.parent;
 	int			status = -ENODEV;
 	int			dynamic = 0;
 
@@ -412,12 +412,12 @@ spi_register_master(struct spi_master *master)
 	/* register the device, then userspace will see it.
 	 * registration fails if the bus ID is in use.
 	 */
-	snprintf(master->cdev.class_id, sizeof master->cdev.class_id,
+	snprintf(master->dev.bus_id, sizeof master->dev.bus_id,
 		"spi%u", master->bus_num);
-	status = class_device_add(&master->cdev);
+	status = device_add(&master->dev);
 	if (status < 0)
 		goto done;
-	dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id,
+	dev_dbg(dev, "registered master %s%s\n", master->dev.bus_id,
 			dynamic ? " (dynamic)" : "");
 
 	/* populate children from any spi device tables */
@@ -449,8 +449,8 @@ void spi_unregister_master(struct spi_master *master)
 {
 	int dummy;
 
-	dummy = device_for_each_child(master->cdev.dev, NULL, __unregister);
-	class_device_unregister(&master->cdev);
+	dummy = device_for_each_child(&master->dev, NULL, __unregister);
+	device_unregister(&master->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_master);
 
@@ -471,7 +471,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num)
 
 	down(&spi_master_class.sem);
 	list_for_each_entry(cdev, &spi_master_class.children, node) {
-		m = container_of(cdev, struct spi_master, cdev);
+		m = container_of(cdev, struct spi_master, dev.kobj);
 		if (m->bus_num == bus_num) {
 			master = spi_master_get(m);
 			break;

+ 3 - 3
drivers/spi/spi_bitbang.c

@@ -479,7 +479,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	/* this task is the only thing to touch the SPI bits */
 	bitbang->busy = 0;
 	bitbang->workqueue = create_singlethread_workqueue(
-			bitbang->master->cdev.dev->bus_id);
+			bitbang->master->dev.parent->bus_id);
 	if (bitbang->workqueue == NULL) {
 		status = -EBUSY;
 		goto err1;
@@ -513,14 +513,14 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
 	while (!list_empty(&bitbang->queue) && limit--) {
 		spin_unlock_irq(&bitbang->lock);
 
-		dev_dbg(bitbang->master->cdev.dev, "wait for queue\n");
+		dev_dbg(&bitbang->master->dev, "wait for queue\n");
 		msleep(10);
 
 		spin_lock_irq(&bitbang->lock);
 	}
 	spin_unlock_irq(&bitbang->lock);
 	if (!list_empty(&bitbang->queue)) {
-		dev_err(bitbang->master->cdev.dev, "queue didn't empty\n");
+		dev_err(&bitbang->master->dev, "queue didn't empty\n");
 		return -EBUSY;
 	}
 

+ 2 - 2
drivers/spi/spi_butterfly.c

@@ -246,7 +246,7 @@ static void butterfly_attach(struct parport *p)
 	 * and no way to be selective about what it binds to.
 	 */
 
-	/* FIXME where should master->cdev.dev come from?
+	/* FIXME where should master->dev.parent come from?
 	 * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
 	 * setting up a platform device like this is an ugly kluge...
 	 */
@@ -386,7 +386,7 @@ static void butterfly_detach(struct parport *p)
 	butterfly = NULL;
 
 	/* stop() unregisters child devices too */
-	pdev = to_platform_device(pp->bitbang.master->cdev.dev);
+	pdev = to_platform_device(pp->bitbang.master->dev.parent);
 	status = spi_bitbang_stop(&pp->bitbang);
 
 	/* turn off VCC */

+ 3 - 1
drivers/usb/core/driver.c

@@ -750,7 +750,8 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
  * usb_register_dev() to enable that functionality.  This function no longer
  * takes care of that.
  */
-int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
+int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
+			const char *mod_name)
 {
 	int retval = 0;
 
@@ -763,6 +764,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
 	new_driver->drvwrap.driver.probe = usb_probe_interface;
 	new_driver->drvwrap.driver.remove = usb_unbind_interface;
 	new_driver->drvwrap.driver.owner = owner;
+	new_driver->drvwrap.driver.mod_name = mod_name;
 	spin_lock_init(&new_driver->dynids.lock);
 	INIT_LIST_HEAD(&new_driver->dynids.list);
 

+ 2 - 2
drivers/usb/input/hid-lgff.c

@@ -32,7 +32,7 @@
 #include <linux/hid.h>
 #include "usbhid.h"
 
-struct device_type {
+struct dev_type {
 	u16 idVendor;
 	u16 idProduct;
 	const signed short *ff;
@@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
 	-1
 };
 
-static const struct device_type devices[] = {
+static const struct dev_type devices[] = {
 	{ 0x046d, 0xc211, ff_rumble },
 	{ 0x046d, 0xc219, ff_rumble },
 	{ 0x046d, 0xc283, ff_joystick },

+ 3 - 3
fs/sysfs/bin.c

@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 
 #include "sysfs.h"
 
@@ -146,7 +147,7 @@ static int open(struct inode * inode, struct file * file)
  Error:
 	module_put(attr->attr.owner);
  Done:
-	if (error && kobj)
+	if (error)
 		kobject_put(kobj);
 	return error;
 }
@@ -157,8 +158,7 @@ static int release(struct inode * inode, struct file * file)
 	struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
 	u8 * buffer = file->private_data;
 
-	if (kobj) 
-		kobject_put(kobj);
+	kobject_put(kobj);
 	module_put(attr->attr.owner);
 	kfree(buffer);
 	return 0;

+ 175 - 39
fs/sysfs/dir.c

@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
+#include <asm/semaphore.h>
 #include "sysfs.h"
 
 DECLARE_RWSEM(sysfs_rename_sem);
@@ -32,8 +33,7 @@ static struct dentry_operations sysfs_dentry_ops = {
 /*
  * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
  */
-static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
-						void * element)
+static struct sysfs_dirent * __sysfs_new_dirent(void * element)
 {
 	struct sysfs_dirent * sd;
 
@@ -45,12 +45,28 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
 	atomic_set(&sd->s_count, 1);
 	atomic_set(&sd->s_event, 1);
 	INIT_LIST_HEAD(&sd->s_children);
-	list_add(&sd->s_sibling, &parent_sd->s_children);
+	INIT_LIST_HEAD(&sd->s_sibling);
 	sd->s_element = element;
 
 	return sd;
 }
 
+static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
+			      struct sysfs_dirent *sd)
+{
+	if (sd)
+		list_add(&sd->s_sibling, &parent_sd->s_children);
+}
+
+static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
+						void * element)
+{
+	struct sysfs_dirent *sd;
+	sd = __sysfs_new_dirent(element);
+	__sysfs_list_dirent(parent_sd, sd);
+	return sd;
+}
+
 /*
  *
  * Return -EEXIST if there is already a sysfs element with the same name for
@@ -77,14 +93,14 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
 }
 
 
-int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
-			void * element, umode_t mode, int type)
+static struct sysfs_dirent *
+__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
 {
 	struct sysfs_dirent * sd;
 
-	sd = sysfs_new_dirent(parent_sd, element);
+	sd = __sysfs_new_dirent(element);
 	if (!sd)
-		return -ENOMEM;
+		goto out;
 
 	sd->s_mode = mode;
 	sd->s_type = type;
@@ -94,7 +110,19 @@ int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
 		dentry->d_op = &sysfs_dentry_ops;
 	}
 
-	return 0;
+out:
+	return sd;
+}
+
+int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
+			void * element, umode_t mode, int type)
+{
+	struct sysfs_dirent *sd;
+
+	sd = __sysfs_make_dirent(dentry, element, mode, type);
+	__sysfs_list_dirent(parent_sd, sd);
+
+	return sd ? 0 : -ENOMEM;
 }
 
 static int init_dir(struct inode * inode)
@@ -165,11 +193,11 @@ int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
 
 /**
  *	sysfs_create_dir - create a directory for an object.
- *	@parent:	parent parent object.
  *	@kobj:		object we're creating directory for. 
+ *	@shadow_parent:	parent parent object.
  */
 
-int sysfs_create_dir(struct kobject * kobj)
+int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
 {
 	struct dentry * dentry = NULL;
 	struct dentry * parent;
@@ -177,7 +205,9 @@ int sysfs_create_dir(struct kobject * kobj)
 
 	BUG_ON(!kobj);
 
-	if (kobj->parent)
+	if (shadow_parent)
+		parent = shadow_parent;
+	else if (kobj->parent)
 		parent = kobj->parent->dentry;
 	else if (sysfs_mount && sysfs_mount->mnt_sb)
 		parent = sysfs_mount->mnt_sb->s_root;
@@ -298,21 +328,12 @@ void sysfs_remove_subdir(struct dentry * d)
 }
 
 
-/**
- *	sysfs_remove_dir - remove an object's directory.
- *	@kobj:	object. 
- *
- *	The only thing special about this is that we remove any files in 
- *	the directory before we remove the directory, and we've inlined
- *	what used to be sysfs_rmdir() below, instead of calling separately.
- */
-
-void sysfs_remove_dir(struct kobject * kobj)
+static void __sysfs_remove_dir(struct dentry *dentry)
 {
-	struct dentry * dentry = dget(kobj->dentry);
 	struct sysfs_dirent * parent_sd;
 	struct sysfs_dirent * sd, * tmp;
 
+	dget(dentry);
 	if (!dentry)
 		return;
 
@@ -333,32 +354,60 @@ void sysfs_remove_dir(struct kobject * kobj)
 	 * Drop reference from dget() on entrance.
 	 */
 	dput(dentry);
+}
+
+/**
+ *	sysfs_remove_dir - remove an object's directory.
+ *	@kobj:	object.
+ *
+ *	The only thing special about this is that we remove any files in
+ *	the directory before we remove the directory, and we've inlined
+ *	what used to be sysfs_rmdir() below, instead of calling separately.
+ */
+
+void sysfs_remove_dir(struct kobject * kobj)
+{
+	__sysfs_remove_dir(kobj->dentry);
 	kobj->dentry = NULL;
 }
 
-int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
+int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
+		     const char *new_name)
 {
 	int error = 0;
-	struct dentry * new_dentry, * parent;
-
-	if (!strcmp(kobject_name(kobj), new_name))
-		return -EINVAL;
+	struct dentry * new_dentry;
 
-	if (!kobj->parent)
-		return -EINVAL;
+	if (!new_parent)
+		return -EFAULT;
 
 	down_write(&sysfs_rename_sem);
-	parent = kobj->parent->dentry;
-
-	mutex_lock(&parent->d_inode->i_mutex);
+	mutex_lock(&new_parent->d_inode->i_mutex);
 
-	new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
+	new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
 	if (!IS_ERR(new_dentry)) {
-  		if (!new_dentry->d_inode) {
+		/* By allowing two different directories with the
+		 * same d_parent we allow this routine to move
+		 * between different shadows of the same directory
+		 */
+		if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
+			return -EINVAL;
+		else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
+			error = -EINVAL;
+		else if (new_dentry == kobj->dentry)
+			error = -EINVAL;
+		else if (!new_dentry->d_inode) {
 			error = kobject_set_name(kobj, "%s", new_name);
 			if (!error) {
+				struct sysfs_dirent *sd, *parent_sd;
+
 				d_add(new_dentry, NULL);
 				d_move(kobj->dentry, new_dentry);
+
+				sd = kobj->dentry->d_fsdata;
+				parent_sd = new_parent->d_fsdata;
+
+				list_del_init(&sd->s_sibling);
+				list_add(&sd->s_sibling, &parent_sd->s_children);
 			}
 			else
 				d_drop(new_dentry);
@@ -366,7 +415,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
 			error = -EEXIST;
 		dput(new_dentry);
 	}
-	mutex_unlock(&parent->d_inode->i_mutex);
+	mutex_unlock(&new_parent->d_inode->i_mutex);
 	up_write(&sysfs_rename_sem);
 
 	return error;
@@ -378,12 +427,10 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
 	struct sysfs_dirent *new_parent_sd, *sd;
 	int error;
 
-	if (!new_parent)
-		return -EINVAL;
-
 	old_parent_dentry = kobj->parent ?
 		kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
-	new_parent_dentry = new_parent->dentry;
+	new_parent_dentry = new_parent ?
+		new_parent->dentry : sysfs_mount->mnt_sb->s_root;
 
 again:
 	mutex_lock(&old_parent_dentry->d_inode->i_mutex);
@@ -547,6 +594,95 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
 	return offset;
 }
 
+
+/**
+ *	sysfs_make_shadowed_dir - Setup so a directory can be shadowed
+ *	@kobj:	object we're creating shadow of.
+ */
+
+int sysfs_make_shadowed_dir(struct kobject *kobj,
+	void * (*follow_link)(struct dentry *, struct nameidata *))
+{
+	struct inode *inode;
+	struct inode_operations *i_op;
+
+	inode = kobj->dentry->d_inode;
+	if (inode->i_op != &sysfs_dir_inode_operations)
+		return -EINVAL;
+
+	i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
+	if (!i_op)
+		return -ENOMEM;
+
+	memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
+	i_op->follow_link = follow_link;
+
+	/* Locking of inode->i_op?
+	 * Since setting i_op is a single word write and they
+	 * are atomic we should be ok here.
+	 */
+	inode->i_op = i_op;
+	return 0;
+}
+
+/**
+ *	sysfs_create_shadow_dir - create a shadow directory for an object.
+ *	@kobj:	object we're creating directory for.
+ *
+ *	sysfs_make_shadowed_dir must already have been called on this
+ *	directory.
+ */
+
+struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
+{
+	struct sysfs_dirent *sd;
+	struct dentry *parent, *dir, *shadow;
+	struct inode *inode;
+
+	dir = kobj->dentry;
+	inode = dir->d_inode;
+	parent = dir->d_parent;
+	shadow = ERR_PTR(-EINVAL);
+	if (!sysfs_is_shadowed_inode(inode))
+		goto out;
+
+	shadow = d_alloc(parent, &dir->d_name);
+	if (!shadow)
+		goto nomem;
+
+	sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
+	if (!sd)
+		goto nomem;
+
+	d_instantiate(shadow, igrab(inode));
+	inc_nlink(inode);
+	inc_nlink(parent->d_inode);
+	shadow->d_op = &sysfs_dentry_ops;
+
+	dget(shadow);		/* Extra count - pin the dentry in core */
+
+out:
+	return shadow;
+nomem:
+	dput(shadow);
+	shadow = ERR_PTR(-ENOMEM);
+	goto out;
+}
+
+/**
+ *	sysfs_remove_shadow_dir - remove an object's directory.
+ *	@shadow: dentry of shadow directory
+ *
+ *	The only thing special about this is that we remove any files in
+ *	the directory before we remove the directory, and we've inlined
+ *	what used to be sysfs_rmdir() below, instead of calling separately.
+ */
+
+void sysfs_remove_shadow_dir(struct dentry *shadow)
+{
+	__sysfs_remove_dir(shadow);
+}
+
 const struct file_operations sysfs_dir_operations = {
 	.open		= sysfs_dir_open,
 	.release	= sysfs_dir_close,

+ 58 - 24
fs/sysfs/file.c

@@ -7,6 +7,7 @@
 #include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/poll.h>
+#include <linux/list.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 
@@ -50,17 +51,29 @@ static struct sysfs_ops subsys_sysfs_ops = {
 	.store	= subsys_attr_store,
 };
 
+/**
+ *	add_to_collection - add buffer to a collection
+ *	@buffer:	buffer to be added
+ *	@node		inode of set to add to
+ */
 
-struct sysfs_buffer {
-	size_t			count;
-	loff_t			pos;
-	char			* page;
-	struct sysfs_ops	* ops;
-	struct semaphore	sem;
-	int			needs_read_fill;
-	int			event;
-};
+static inline void
+add_to_collection(struct sysfs_buffer *buffer, struct inode *node)
+{
+	struct sysfs_buffer_collection *set = node->i_private;
 
+	mutex_lock(&node->i_mutex);
+	list_add(&buffer->associates, &set->associates);
+	mutex_unlock(&node->i_mutex);
+}
+
+static inline void
+remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
+{
+	mutex_lock(&node->i_mutex);
+	list_del(&buffer->associates);
+	mutex_unlock(&node->i_mutex);
+}
 
 /**
  *	fill_read_buffer - allocate and fill buffer from object.
@@ -70,7 +83,8 @@ struct sysfs_buffer {
  *	Allocate @buffer->page, if it hasn't been already, then call the
  *	kobject's show() method to fill the buffer with this attribute's 
  *	data. 
- *	This is called only once, on the file's first read. 
+ *	This is called only once, on the file's first read unless an error
+ *	is returned.
  */
 static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
 {
@@ -88,12 +102,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
 
 	buffer->event = atomic_read(&sd->s_event);
 	count = ops->show(kobj,attr,buffer->page);
-	buffer->needs_read_fill = 0;
 	BUG_ON(count > (ssize_t)PAGE_SIZE);
-	if (count >= 0)
+	if (count >= 0) {
+		buffer->needs_read_fill = 0;
 		buffer->count = count;
-	else
+	} else {
 		ret = count;
+	}
 	return ret;
 }
 
@@ -153,6 +168,10 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 	ssize_t retval = 0;
 
 	down(&buffer->sem);
+	if (buffer->orphaned) {
+		retval = -ENODEV;
+		goto out;
+	}
 	if (buffer->needs_read_fill) {
 		if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
 			goto out;
@@ -165,7 +184,6 @@ out:
 	return retval;
 }
 
-
 /**
  *	fill_write_buffer - copy buffer from userspace.
  *	@buffer:	data buffer for file.
@@ -243,19 +261,25 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
 	ssize_t len;
 
 	down(&buffer->sem);
+	if (buffer->orphaned) {
+		len = -ENODEV;
+		goto out;
+	}
 	len = fill_write_buffer(buffer, buf, count);
 	if (len > 0)
 		len = flush_write_buffer(file->f_path.dentry, buffer, len);
 	if (len > 0)
 		*ppos += len;
+out:
 	up(&buffer->sem);
 	return len;
 }
 
-static int check_perm(struct inode * inode, struct file * file)
+static int sysfs_open_file(struct inode *inode, struct file *file)
 {
 	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
 	struct attribute * attr = to_attr(file->f_path.dentry);
+	struct sysfs_buffer_collection *set;
 	struct sysfs_buffer * buffer;
 	struct sysfs_ops * ops = NULL;
 	int error = 0;
@@ -285,6 +309,18 @@ static int check_perm(struct inode * inode, struct file * file)
 	if (!ops)
 		goto Eaccess;
 
+	/* make sure we have a collection to add our buffers to */
+	mutex_lock(&inode->i_mutex);
+	if (!(set = inode->i_private)) {
+		if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
+			error = -ENOMEM;
+			goto Done;
+		} else {
+			INIT_LIST_HEAD(&set->associates);
+		}
+	}
+	mutex_unlock(&inode->i_mutex);
+
 	/* File needs write support.
 	 * The inode's perms must say it's ok, 
 	 * and we must have a store method.
@@ -310,9 +346,11 @@ static int check_perm(struct inode * inode, struct file * file)
 	 */
 	buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
 	if (buffer) {
+		INIT_LIST_HEAD(&buffer->associates);
 		init_MUTEX(&buffer->sem);
 		buffer->needs_read_fill = 1;
 		buffer->ops = ops;
+		add_to_collection(buffer, inode);
 		file->private_data = buffer;
 	} else
 		error = -ENOMEM;
@@ -325,16 +363,11 @@ static int check_perm(struct inode * inode, struct file * file)
 	error = -EACCES;
 	module_put(attr->owner);
  Done:
-	if (error && kobj)
+	if (error)
 		kobject_put(kobj);
 	return error;
 }
 
-static int sysfs_open_file(struct inode * inode, struct file * filp)
-{
-	return check_perm(inode,filp);
-}
-
 static int sysfs_release(struct inode * inode, struct file * filp)
 {
 	struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
@@ -342,8 +375,9 @@ static int sysfs_release(struct inode * inode, struct file * filp)
 	struct module * owner = attr->owner;
 	struct sysfs_buffer * buffer = filp->private_data;
 
-	if (kobj) 
-		kobject_put(kobj);
+	if (buffer)
+		remove_from_collection(buffer, inode);
+	kobject_put(kobj);
 	/* After this point, attr should not be accessed. */
 	module_put(owner);
 
@@ -548,7 +582,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
 void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 {
-	sysfs_hash_and_remove(kobj->dentry,attr->name);
+	sysfs_hash_and_remove(kobj->dentry, attr->name);
 }
 
 

+ 2 - 0
fs/sysfs/group.c

@@ -13,6 +13,8 @@
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <linux/err.h>
+#include <linux/fs.h>
+#include <asm/semaphore.h>
 #include "sysfs.h"
 
 

+ 35 - 1
fs/sysfs/inode.c

@@ -13,6 +13,7 @@
 #include <linux/backing-dev.h>
 #include <linux/capability.h>
 #include <linux/errno.h>
+#include <asm/semaphore.h>
 #include "sysfs.h"
 
 extern struct super_block * sysfs_sb;
@@ -32,6 +33,16 @@ static struct inode_operations sysfs_inode_operations ={
 	.setattr	= sysfs_setattr,
 };
 
+void sysfs_delete_inode(struct inode *inode)
+{
+	/* Free the shadowed directory inode operations */
+	if (sysfs_is_shadowed_inode(inode)) {
+		kfree(inode->i_op);
+		inode->i_op = NULL;
+	}
+	return generic_delete_inode(inode);
+}
+
 int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
 {
 	struct inode * inode = dentry->d_inode;
@@ -209,6 +220,22 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
 	return NULL;
 }
 
+static inline void orphan_all_buffers(struct inode *node)
+{
+	struct sysfs_buffer_collection *set = node->i_private;
+	struct sysfs_buffer *buf;
+
+	mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD);
+	if (node->i_private) {
+		list_for_each_entry(buf, &set->associates, associates) {
+			down(&buf->sem);
+			buf->orphaned = 1;
+			up(&buf->sem);
+		}
+	}
+	mutex_unlock(&node->i_mutex);
+}
+
 
 /*
  * Unhashes the dentry corresponding to given sysfs_dirent
@@ -217,16 +244,23 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
 void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
 {
 	struct dentry * dentry = sd->s_dentry;
+	struct inode *inode;
 
 	if (dentry) {
 		spin_lock(&dcache_lock);
 		spin_lock(&dentry->d_lock);
 		if (!(d_unhashed(dentry) && dentry->d_inode)) {
+			inode = dentry->d_inode;
+			spin_lock(&inode->i_lock);
+			__iget(inode);
+			spin_unlock(&inode->i_lock);
 			dget_locked(dentry);
 			__d_drop(dentry);
 			spin_unlock(&dentry->d_lock);
 			spin_unlock(&dcache_lock);
 			simple_unlink(parent->d_inode, dentry);
+			orphan_all_buffers(inode);
+			iput(inode);
 		} else {
 			spin_unlock(&dentry->d_lock);
 			spin_unlock(&dcache_lock);
@@ -248,7 +282,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
 		return -ENOENT;
 
 	parent_sd = dir->d_fsdata;
-	mutex_lock(&dir->d_inode->i_mutex);
+	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 		if (!sd->s_element)
 			continue;

+ 10 - 1
fs/sysfs/mount.c

@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <asm/semaphore.h>
 
 #include "sysfs.h"
 
@@ -18,9 +19,12 @@ struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;
 
+static void sysfs_clear_inode(struct inode *inode);
+
 static struct super_operations sysfs_ops = {
 	.statfs		= simple_statfs,
-	.drop_inode	= generic_delete_inode,
+	.drop_inode	= sysfs_delete_inode,
+	.clear_inode	= sysfs_clear_inode,
 };
 
 static struct sysfs_dirent sysfs_root = {
@@ -31,6 +35,11 @@ static struct sysfs_dirent sysfs_root = {
 	.s_iattr	= NULL,
 };
 
+static void sysfs_clear_inode(struct inode *inode)
+{
+	kfree(inode->i_private);
+}
+
 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;

+ 1 - 0
fs/sysfs/symlink.c

@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
+#include <asm/semaphore.h>
 
 #include "sysfs.h"
 

+ 21 - 0
fs/sysfs/sysfs.h

@@ -2,6 +2,7 @@
 extern struct vfsmount * sysfs_mount;
 extern struct kmem_cache *sysfs_dir_cachep;
 
+extern void sysfs_delete_inode(struct inode *inode);
 extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
 extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
 
@@ -33,6 +34,22 @@ struct sysfs_symlink {
 	struct kobject * target_kobj;
 };
 
+struct sysfs_buffer {
+	struct list_head		associates;
+	size_t				count;
+	loff_t				pos;
+	char				* page;
+	struct sysfs_ops		* ops;
+	struct semaphore		sem;
+	int				orphaned;
+	int				needs_read_fill;
+	int				event;
+};
+
+struct sysfs_buffer_collection {
+	struct list_head	associates;
+};
+
 static inline struct kobject * to_kobj(struct dentry * dentry)
 {
 	struct sysfs_dirent * sd = dentry->d_fsdata;
@@ -96,3 +113,7 @@ static inline void sysfs_put(struct sysfs_dirent * sd)
 		release_sysfs_dirent(sd);
 }
 
+static inline int sysfs_is_shadowed_inode(struct inode *inode)
+{
+	return S_ISDIR(inode->i_mode) && inode->i_op->follow_link;
+}

+ 11 - 1
include/linux/device.h

@@ -126,6 +126,7 @@ struct device_driver {
 	struct klist_node	knode_bus;
 
 	struct module		* owner;
+	const char 		* mod_name;	/* used for built-in modules */
 
 	int	(*probe)	(struct device * dev);
 	int	(*remove)	(struct device * dev);
@@ -327,6 +328,13 @@ extern struct class_device *class_device_create(struct class *cls,
 					__attribute__((format(printf,5,6)));
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
+struct device_type {
+	struct device_attribute *attrs;
+	int (*uevent)(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size);
+	void (*release)(struct device *dev);
+};
+
 /* interface for exporting device attributes */
 struct device_attribute {
 	struct attribute	attr;
@@ -355,6 +363,7 @@ struct device {
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	struct device_type	*type;
 	unsigned		is_registered:1;
 	struct device_attribute uevent_attr;
 	struct device_attribute *devt_attr;
@@ -390,9 +399,10 @@ struct device {
 
 	/* class_device migration path */
 	struct list_head	node;
-	struct class		*class;		/* optional*/
+	struct class		*class;
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
 	struct attribute_group	**groups;	/* optional groups */
+	int			uevent_suppress;
 
 	void	(*release)(struct device * dev);
 };

+ 2 - 2
include/linux/ide.h

@@ -1192,8 +1192,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *);
 extern int ideprobe_init(void);
 
 extern void ide_scan_pcibus(int scan_direction) __init;
-extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
-#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
+extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
+#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
 void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
 extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
 

+ 4 - 0
include/linux/kobject.h

@@ -74,9 +74,13 @@ extern void kobject_init(struct kobject *);
 extern void kobject_cleanup(struct kobject *);
 
 extern int __must_check kobject_add(struct kobject *);
+extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
 extern void kobject_del(struct kobject *);
 
 extern int __must_check kobject_rename(struct kobject *, const char *new_name);
+extern int __must_check kobject_shadow_rename(struct kobject *kobj,
+						struct dentry *new_parent,
+						const char *new_name);
 extern int __must_check kobject_move(struct kobject *, struct kobject *);
 
 extern int __must_check kobject_register(struct kobject *);

+ 2 - 1
include/linux/module.h

@@ -58,6 +58,7 @@ struct module_kobject
 {
 	struct kobject kobj;
 	struct module *mod;
+	struct kobject *drivers_dir;
 };
 
 /* These are either module local, or the kernel's dummy ones. */
@@ -263,7 +264,7 @@ struct module
 	struct module_attribute *modinfo_attrs;
 	const char *version;
 	const char *srcversion;
-	struct kobject *drivers_dir;
+	struct kobject *holders_dir;
 
 	/* Exported symbols */
 	const struct kernel_symbol *syms;

+ 3 - 2
include/linux/netdevice.h

@@ -529,10 +529,11 @@ struct net_device
 	struct net_bridge_port	*br_port;
 
 	/* class/net/name entry */
-	struct class_device	class_dev;
+	struct device		dev;
 	/* space for optional statistics and wireless sysfs groups */
 	struct attribute_group  *sysfs_groups[3];
 };
+#define to_net_dev(d) container_of(d, struct net_device, dev)
 
 #define	NETDEV_ALIGN		32
 #define	NETDEV_ALIGN_CONST	(NETDEV_ALIGN - 1)
@@ -548,7 +549,7 @@ static inline void *netdev_priv(struct net_device *dev)
 /* Set the sysfs physical device reference for the network logical device
  * if set prior to registration will cause a symlink during initialization.
  */
-#define SET_NETDEV_DEV(net, pdev)	((net)->class_dev.dev = (pdev))
+#define SET_NETDEV_DEV(net, pdev)	((net)->dev.parent = (pdev))
 
 struct packet_type {
 	__be16			type;	/* This is really htons(ether_type). */

+ 3 - 2
include/linux/pci.h

@@ -573,10 +573,11 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
 void pci_enable_bridges(struct pci_bus *bus);
 
 /* Proper probing supporting hot-pluggable devices */
-int __must_check __pci_register_driver(struct pci_driver *, struct module *);
+int __must_check __pci_register_driver(struct pci_driver *, struct module *,
+				       const char *mod_name);
 static inline int __must_check pci_register_driver(struct pci_driver *driver)
 {
-	return __pci_register_driver(driver, THIS_MODULE);
+	return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
 }
 
 void pci_unregister_driver(struct pci_driver *);

+ 5 - 0
include/linux/serio.h

@@ -86,6 +86,11 @@ static inline void serio_register_port(struct serio *serio)
 void serio_unregister_port(struct serio *serio);
 void serio_unregister_child_port(struct serio *serio);
 
+int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name);
+static inline int serio_register_driver(struct serio_driver *drv)
+{
+	return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
+}
 int serio_register_driver(struct serio_driver *drv);
 void serio_unregister_driver(struct serio_driver *drv);
 

+ 5 - 5
include/linux/spi/spi.h

@@ -170,7 +170,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * message's completion function when the transaction completes.
  */
 struct spi_master {
-	struct class_device	cdev;
+	struct device		dev;
 
 	/* other than negative (== assign one dynamically), bus_num is fully
 	 * board-specific.  usually that simplifies to being SOC-specific.
@@ -216,17 +216,17 @@ struct spi_master {
 
 static inline void *spi_master_get_devdata(struct spi_master *master)
 {
-	return class_get_devdata(&master->cdev);
+	return dev_get_drvdata(&master->dev);
 }
 
 static inline void spi_master_set_devdata(struct spi_master *master, void *data)
 {
-	class_set_devdata(&master->cdev, data);
+	dev_set_drvdata(&master->dev, data);
 }
 
 static inline struct spi_master *spi_master_get(struct spi_master *master)
 {
-	if (!master || !class_device_get(&master->cdev))
+	if (!master || !get_device(&master->dev))
 		return NULL;
 	return master;
 }
@@ -234,7 +234,7 @@ static inline struct spi_master *spi_master_get(struct spi_master *master)
 static inline void spi_master_put(struct spi_master *master)
 {
 	if (master)
-		class_device_put(&master->cdev);
+		put_device(&master->dev);
 }
 
 

+ 20 - 4
include/linux/sysfs.h

@@ -11,10 +11,12 @@
 #define _SYSFS_H_
 
 #include <linux/compiler.h>
+#include <linux/list.h>
 #include <asm/atomic.h>
 
 struct kobject;
 struct module;
+struct nameidata;
 
 struct attribute {
 	const char		* name;
@@ -88,13 +90,13 @@ struct sysfs_dirent {
 #ifdef CONFIG_SYSFS
 
 extern int __must_check
-sysfs_create_dir(struct kobject *);
+sysfs_create_dir(struct kobject *, struct dentry *);
 
 extern void
 sysfs_remove_dir(struct kobject *);
 
 extern int __must_check
-sysfs_rename_dir(struct kobject *, const char *new_name);
+sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
 
 extern int __must_check
 sysfs_move_dir(struct kobject *, struct kobject *);
@@ -126,11 +128,17 @@ int __must_check sysfs_create_group(struct kobject *,
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
 void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
+
+extern int sysfs_make_shadowed_dir(struct kobject *kobj,
+	void * (*follow_link)(struct dentry *, struct nameidata *));
+extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
+extern void sysfs_remove_shadow_dir(struct dentry *dir);
+
 extern int __must_check sysfs_init(void);
 
 #else /* CONFIG_SYSFS */
 
-static inline int sysfs_create_dir(struct kobject * k)
+static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
 {
 	return 0;
 }
@@ -140,7 +148,9 @@ static inline void sysfs_remove_dir(struct kobject * k)
 	;
 }
 
-static inline int sysfs_rename_dir(struct kobject * k, const char *new_name)
+static inline int sysfs_rename_dir(struct kobject * k,
+					struct dentry *new_parent,
+					const char *new_name)
 {
 	return 0;
 }
@@ -204,6 +214,12 @@ static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
 {
 }
 
+static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
+	void * (*follow_link)(struct dentry *, struct nameidata *))
+{
+	return 0;
+}
+
 static inline int __must_check sysfs_init(void)
 {
 	return 0;

+ 3 - 2
include/linux/usb.h

@@ -868,10 +868,11 @@ struct usb_class_driver {
  * use these in module_init()/module_exit()
  * and don't forget MODULE_DEVICE_TABLE(usb, ...)
  */
-extern int usb_register_driver(struct usb_driver *, struct module *);
+extern int usb_register_driver(struct usb_driver *, struct module *,
+			       const char *);
 static inline int usb_register(struct usb_driver *driver)
 {
-	return usb_register_driver(driver, THIS_MODULE);
+	return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
 }
 extern void usb_deregister(struct usb_driver *);
 

+ 1 - 1
include/pcmcia/ss.h

@@ -284,7 +284,7 @@ struct pcmcia_socket {
 #endif
 
 	/* socket device */
-	struct class_device		dev;
+	struct device			dev;
 	void				*driver_data;	/* data internal to the socket driver */
 
 };

+ 59 - 17
kernel/module.c

@@ -537,6 +537,8 @@ static int already_uses(struct module *a, struct module *b)
 static int use_module(struct module *a, struct module *b)
 {
 	struct module_use *use;
+	int no_warn;
+
 	if (b == NULL || already_uses(a, b)) return 1;
 
 	if (!strong_try_module_get(b))
@@ -552,6 +554,7 @@ static int use_module(struct module *a, struct module *b)
 
 	use->module_which_uses = a;
 	list_add(&use->list, &b->modules_which_use_me);
+	no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
 	return 1;
 }
 
@@ -569,6 +572,7 @@ static void module_unload_free(struct module *mod)
 				module_put(i);
 				list_del(&use->list);
 				kfree(use);
+				sysfs_remove_link(i->holders_dir, mod->name);
 				/* There can be at most one match. */
 				break;
 			}
@@ -1106,9 +1110,7 @@ static void module_remove_modinfo_attrs(struct module *mod)
 	kfree(mod->modinfo_attrs);
 }
 
-static int mod_sysfs_setup(struct module *mod,
-			   struct kernel_param *kparam,
-			   unsigned int num_params)
+static int mod_sysfs_init(struct module *mod)
 {
 	int err;
 
@@ -1125,21 +1127,30 @@ static int mod_sysfs_setup(struct module *mod,
 	kobj_set_kset_s(&mod->mkobj, module_subsys);
 	mod->mkobj.mod = mod;
 
-	/* delay uevent until full sysfs population */
 	kobject_init(&mod->mkobj.kobj);
+
+out:
+	return err;
+}
+
+static int mod_sysfs_setup(struct module *mod,
+			   struct kernel_param *kparam,
+			   unsigned int num_params)
+{
+	int err;
+
+	/* delay uevent until full sysfs population */
 	err = kobject_add(&mod->mkobj.kobj);
 	if (err)
 		goto out;
 
-	mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers");
-	if (!mod->drivers_dir) {
-		err = -ENOMEM;
+	mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders");
+	if (!mod->holders_dir)
 		goto out_unreg;
-	}
 
 	err = module_param_sysfs_setup(mod, kparam, num_params);
 	if (err)
-		goto out_unreg_drivers;
+		goto out_unreg_holders;
 
 	err = module_add_modinfo_attrs(mod);
 	if (err)
@@ -1150,8 +1161,8 @@ static int mod_sysfs_setup(struct module *mod,
 
 out_unreg_param:
 	module_param_sysfs_remove(mod);
-out_unreg_drivers:
-	kobject_unregister(mod->drivers_dir);
+out_unreg_holders:
+	kobject_unregister(mod->holders_dir);
 out_unreg:
 	kobject_del(&mod->mkobj.kobj);
 	kobject_put(&mod->mkobj.kobj);
@@ -1163,7 +1174,10 @@ static void mod_kobject_remove(struct module *mod)
 {
 	module_remove_modinfo_attrs(mod);
 	module_param_sysfs_remove(mod);
-	kobject_unregister(mod->drivers_dir);
+	if (mod->mkobj.drivers_dir)
+		kobject_unregister(mod->mkobj.drivers_dir);
+	if (mod->holders_dir)
+		kobject_unregister(mod->holders_dir);
 
 	kobject_unregister(&mod->mkobj.kobj);
 }
@@ -1768,6 +1782,10 @@ static struct module *load_module(void __user *umod,
 	/* Now we've moved module, initialize linked lists, etc. */
 	module_unload_init(mod);
 
+	/* Initialize kobject, so we can reference it. */
+	if (mod_sysfs_init(mod) != 0)
+		goto cleanup;
+
 	/* Set up license info based on the info section */
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
@@ -2340,19 +2358,43 @@ static char *make_driver_name(struct device_driver *drv)
 	return driver_name;
 }
 
+static void module_create_drivers_dir(struct module_kobject *mk)
+{
+	if (!mk || mk->drivers_dir)
+		return;
+
+	mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers");
+}
+
 void module_add_driver(struct module *mod, struct device_driver *drv)
 {
 	char *driver_name;
 	int no_warn;
+	struct module_kobject *mk = NULL;
+
+	if (!drv)
+		return;
+
+	if (mod)
+		mk = &mod->mkobj;
+	else if (drv->mod_name) {
+		struct kobject *mkobj;
+
+		/* Lookup built-in module entry in /sys/modules */
+		mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
+		if (mkobj)
+			mk = container_of(mkobj, struct module_kobject, kobj);
+	}
 
-	if (!mod || !drv)
+	if (!mk)
 		return;
 
 	/* Don't check return codes; these calls are idempotent */
-	no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module");
+	no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
 	driver_name = make_driver_name(drv);
 	if (driver_name) {
-		no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj,
+		module_create_drivers_dir(mk);
+		no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
 					    driver_name);
 		kfree(driver_name);
 	}
@@ -2367,10 +2409,10 @@ void module_remove_driver(struct device_driver *drv)
 		return;
 
 	sysfs_remove_link(&drv->kobj, "module");
-	if (drv->owner && drv->owner->drivers_dir) {
+	if (drv->owner && drv->owner->mkobj.drivers_dir) {
 		driver_name = make_driver_name(drv);
 		if (driver_name) {
-			sysfs_remove_link(drv->owner->drivers_dir,
+			sysfs_remove_link(drv->owner->mkobj.drivers_dir,
 					  driver_name);
 			kfree(driver_name);
 		}

+ 20 - 8
kernel/params.c

@@ -30,6 +30,8 @@
 #define DEBUGP(fmt, a...)
 #endif
 
+static struct kobj_type module_ktype;
+
 static inline char dash2underscore(char c)
 {
 	if (c == '-')
@@ -561,14 +563,11 @@ static void __init kernel_param_sysfs_setup(const char *name,
 	mk->mod = THIS_MODULE;
 	kobj_set_kset_s(mk, module_subsys);
 	kobject_set_name(&mk->kobj, name);
-	ret = kobject_register(&mk->kobj);
+	kobject_init(&mk->kobj);
+	ret = kobject_add(&mk->kobj);
 	BUG_ON(ret < 0);
-
-	/* no need to keep the kobject if no parameter is exported */
-	if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
-		kobject_unregister(&mk->kobj);
-		kfree(mk);
-	}
+	param_sysfs_setup(mk, kparam, num_params, name_skip);
+	kobject_uevent(&mk->kobj, KOBJ_ADD);
 }
 
 /*
@@ -674,6 +673,19 @@ static struct sysfs_ops module_sysfs_ops = {
 	.store = module_attr_store,
 };
 
+static int uevent_filter(struct kset *kset, struct kobject *kobj)
+{
+	struct kobj_type *ktype = get_ktype(kobj);
+
+	if (ktype == &module_ktype)
+		return 1;
+	return 0;
+}
+
+static struct kset_uevent_ops module_uevent_ops = {
+	.filter = uevent_filter,
+};
+
 #else
 static struct sysfs_ops module_sysfs_ops = {
 	.show = NULL,
@@ -685,7 +697,7 @@ static struct kobj_type module_ktype = {
 	.sysfs_ops =	&module_sysfs_ops,
 };
 
-decl_subsys(module, &module_ktype, NULL);
+decl_subsys(module, &module_ktype, &module_uevent_ops);
 
 /*
  * param_sysfs_init - wrapper for built-in params support

+ 61 - 12
lib/kobject.c

@@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
 	return error;
 }
 
-static int create_dir(struct kobject * kobj)
+static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
 {
 	int error = 0;
 	if (kobject_name(kobj)) {
-		error = sysfs_create_dir(kobj);
+		error = sysfs_create_dir(kobj, shadow_parent);
 		if (!error) {
 			if ((error = populate_dir(kobj)))
 				sysfs_remove_dir(kobj);
@@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path);
  */
 void kobject_init(struct kobject * kobj)
 {
+	if (!kobj)
+		return;
 	kref_init(&kobj->kref);
 	INIT_LIST_HEAD(&kobj->entry);
 	init_waitqueue_head(&kobj->poll);
@@ -156,9 +158,10 @@ static void unlink(struct kobject * kobj)
 /**
  *	kobject_add - add an object to the hierarchy.
  *	@kobj:	object.
+ *	@shadow_parent: sysfs directory to add to.
  */
 
-int kobject_add(struct kobject * kobj)
+int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
 {
 	int error = 0;
 	struct kobject * parent;
@@ -189,12 +192,11 @@ int kobject_add(struct kobject * kobj)
 	}
 	kobj->parent = parent;
 
-	error = create_dir(kobj);
+	error = create_dir(kobj, shadow_parent);
 	if (error) {
 		/* unlink does the kobject_put() for us */
 		unlink(kobj);
-		if (parent)
-			kobject_put(parent);
+		kobject_put(parent);
 
 		/* be noisy on error issues */
 		if (error == -EEXIST)
@@ -211,6 +213,15 @@ int kobject_add(struct kobject * kobj)
 	return error;
 }
 
+/**
+ *	kobject_add - add an object to the hierarchy.
+ *	@kobj:	object.
+ */
+int kobject_add(struct kobject * kobj)
+{
+	return kobject_shadow_add(kobj, NULL);
+}
+
 
 /**
  *	kobject_register - initialize and add an object.
@@ -303,7 +314,29 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
 	kobj = kobject_get(kobj);
 	if (!kobj)
 		return -EINVAL;
-	error = sysfs_rename_dir(kobj, new_name);
+	if (!kobj->parent)
+		return -EINVAL;
+	error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
+	kobject_put(kobj);
+
+	return error;
+}
+
+/**
+ *	kobject_rename - change the name of an object
+ *	@kobj:	object in question.
+ *	@new_name: object's new name
+ */
+
+int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
+			  const char *new_name)
+{
+	int error = 0;
+
+	kobj = kobject_get(kobj);
+	if (!kobj)
+		return -EINVAL;
+	error = sysfs_rename_dir(kobj, new_parent, new_name);
 	kobject_put(kobj);
 
 	return error;
@@ -312,7 +345,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
 /**
  *	kobject_move - move object to another parent
  *	@kobj:	object in question.
- *	@new_parent: object's new parent
+ *	@new_parent: object's new parent (can be NULL)
  */
 
 int kobject_move(struct kobject *kobj, struct kobject *new_parent)
@@ -328,8 +361,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
 		return -EINVAL;
 	new_parent = kobject_get(new_parent);
 	if (!new_parent) {
-		error = -EINVAL;
-		goto out;
+		if (kobj->kset)
+			new_parent = kobject_get(&kobj->kset->kobj);
 	}
 	/* old object path */
 	devpath = kobject_get_path(kobj, GFP_KERNEL);
@@ -366,6 +399,8 @@ out:
 
 void kobject_del(struct kobject * kobj)
 {
+	if (!kobj)
+		return;
 	sysfs_remove_dir(kobj);
 	unlink(kobj);
 }
@@ -377,6 +412,8 @@ void kobject_del(struct kobject * kobj)
 
 void kobject_unregister(struct kobject * kobj)
 {
+	if (!kobj)
+		return;
 	pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
 	kobject_uevent(kobj, KOBJ_REMOVE);
 	kobject_del(kobj);
@@ -414,8 +451,7 @@ void kobject_cleanup(struct kobject * kobj)
 		t->release(kobj);
 	if (s)
 		kset_put(s);
-	if (parent) 
-		kobject_put(parent);
+	kobject_put(parent);
 }
 
 static void kobject_release(struct kref *kref)
@@ -523,6 +559,8 @@ int kset_add(struct kset * k)
 
 int kset_register(struct kset * k)
 {
+	if (!k)
+		return -EINVAL;
 	kset_init(k);
 	return kset_add(k);
 }
@@ -535,6 +573,8 @@ int kset_register(struct kset * k)
 
 void kset_unregister(struct kset * k)
 {
+	if (!k)
+		return;
 	kobject_unregister(&k->kobj);
 }
 
@@ -586,6 +626,9 @@ int subsystem_register(struct subsystem * s)
 {
 	int error;
 
+	if (!s)
+		return -EINVAL;
+
 	subsystem_init(s);
 	pr_debug("subsystem %s: registering\n",s->kset.kobj.name);
 
@@ -598,6 +641,8 @@ int subsystem_register(struct subsystem * s)
 
 void subsystem_unregister(struct subsystem * s)
 {
+	if (!s)
+		return;
 	pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
 	kset_unregister(&s->kset);
 }
@@ -612,6 +657,10 @@ void subsystem_unregister(struct subsystem * s)
 int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
 {
 	int error = 0;
+
+	if (!s || !a)
+		return -EINVAL;
+
 	if (subsys_get(s)) {
 		error = sysfs_create_file(&s->kset.kobj,&a->attr);
 		subsys_put(s);

+ 1 - 1
net/bridge/br_if.c

@@ -286,7 +286,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
 	kobject_init(&p->kobj);
 	kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
 	p->kobj.ktype = &brport_ktype;
-	p->kobj.parent = &(dev->class_dev.kobj);
+	p->kobj.parent = &(dev->dev.kobj);
 	p->kobj.kset = NULL;
 
 	return p;

+ 127 - 107
net/bridge/br_sysfs_br.c

@@ -21,18 +21,17 @@
 
 #include "br_private.h"
 
-#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_dev(obj)	container_of(obj, struct device, kobj)
 #define to_bridge(cd)	((struct net_bridge *)(to_net_dev(cd)->priv))
 
 /*
  * Common code for storing bridge parameters.
  */
-static ssize_t store_bridge_parm(struct class_device *cd,
+static ssize_t store_bridge_parm(struct device *d,
 				 const char *buf, size_t len,
 				 void (*set)(struct net_bridge *, unsigned long))
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	char *endp;
 	unsigned long val;
 
@@ -50,9 +49,10 @@ static ssize_t store_bridge_parm(struct class_device *cd,
 }
 
 
-static ssize_t show_forward_delay(struct class_device *cd, char *buf)
+static ssize_t show_forward_delay(struct device *d,
+				  struct device_attribute *attr, char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
 }
 
@@ -64,18 +64,20 @@ static void set_forward_delay(struct net_bridge *br, unsigned long val)
 		br->bridge_forward_delay = delay;
 }
 
-static ssize_t store_forward_delay(struct class_device *cd, const char *buf,
-				   size_t len)
+static ssize_t store_forward_delay(struct device *d,
+				   struct device_attribute *attr,
+				   const char *buf, size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_forward_delay);
+	return store_bridge_parm(d, buf, len, set_forward_delay);
 }
-static CLASS_DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
-			 show_forward_delay, store_forward_delay);
+static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
+		   show_forward_delay, store_forward_delay);
 
-static ssize_t show_hello_time(struct class_device *cd, char *buf)
+static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
+			       char *buf)
 {
 	return sprintf(buf, "%lu\n",
-		       jiffies_to_clock_t(to_bridge(cd)->hello_time));
+		       jiffies_to_clock_t(to_bridge(d)->hello_time));
 }
 
 static void set_hello_time(struct net_bridge *br, unsigned long val)
@@ -86,19 +88,20 @@ static void set_hello_time(struct net_bridge *br, unsigned long val)
 		br->bridge_hello_time = t;
 }
 
-static ssize_t store_hello_time(struct class_device *cd, const char *buf,
+static ssize_t store_hello_time(struct device *d,
+				struct device_attribute *attr, const char *buf,
 				size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_hello_time);
+	return store_bridge_parm(d, buf, len, set_hello_time);
 }
+static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
+		   store_hello_time);
 
-static CLASS_DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
-			 store_hello_time);
-
-static ssize_t show_max_age(struct class_device *cd, char *buf)
+static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
+			    char *buf)
 {
 	return sprintf(buf, "%lu\n",
-		       jiffies_to_clock_t(to_bridge(cd)->max_age));
+		       jiffies_to_clock_t(to_bridge(d)->max_age));
 }
 
 static void set_max_age(struct net_bridge *br, unsigned long val)
@@ -109,18 +112,17 @@ static void set_max_age(struct net_bridge *br, unsigned long val)
 		br->bridge_max_age = t;
 }
 
-static ssize_t store_max_age(struct class_device *cd, const char *buf,
-				size_t len)
+static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
+			     const char *buf, size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_max_age);
+	return store_bridge_parm(d, buf, len, set_max_age);
 }
+static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
 
-static CLASS_DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age,
-			 store_max_age);
-
-static ssize_t show_ageing_time(struct class_device *cd, char *buf)
+static ssize_t show_ageing_time(struct device *d,
+				struct device_attribute *attr, char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
 }
 
@@ -129,17 +131,19 @@ static void set_ageing_time(struct net_bridge *br, unsigned long val)
 	br->ageing_time = clock_t_to_jiffies(val);
 }
 
-static ssize_t store_ageing_time(struct class_device *cd, const char *buf,
-				 size_t len)
+static ssize_t store_ageing_time(struct device *d,
+				 struct device_attribute *attr,
+				 const char *buf, size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_ageing_time);
+	return store_bridge_parm(d, buf, len, set_ageing_time);
 }
+static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
+		   store_ageing_time);
 
-static CLASS_DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
-			 store_ageing_time);
-static ssize_t show_stp_state(struct class_device *cd, char *buf)
+static ssize_t show_stp_state(struct device *d,
+			      struct device_attribute *attr, char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%d\n", br->stp_enabled);
 }
 
@@ -148,18 +152,19 @@ static void set_stp_state(struct net_bridge *br, unsigned long val)
 	br->stp_enabled = val;
 }
 
-static ssize_t store_stp_state(struct class_device *cd,
-			       const char *buf, size_t len)
+static ssize_t store_stp_state(struct device *d,
+			       struct device_attribute *attr, const char *buf,
+			       size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_stp_state);
+	return store_bridge_parm(d, buf, len, set_stp_state);
 }
+static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
+		   store_stp_state);
 
-static CLASS_DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
-			 store_stp_state);
-
-static ssize_t show_priority(struct class_device *cd, char *buf)
+static ssize_t show_priority(struct device *d, struct device_attribute *attr,
+			     char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%d\n",
 		       (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
 }
@@ -169,92 +174,107 @@ static void set_priority(struct net_bridge *br, unsigned long val)
 	br_stp_set_bridge_priority(br, (u16) val);
 }
 
-static ssize_t store_priority(struct class_device *cd,
+static ssize_t store_priority(struct device *d, struct device_attribute *attr,
 			       const char *buf, size_t len)
 {
-	return store_bridge_parm(cd, buf, len, set_priority);
+	return store_bridge_parm(d, buf, len, set_priority);
 }
-static CLASS_DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority,
-			 store_priority);
+static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority);
 
-static ssize_t show_root_id(struct class_device *cd, char *buf)
+static ssize_t show_root_id(struct device *d, struct device_attribute *attr,
+			    char *buf)
 {
-	return br_show_bridge_id(buf, &to_bridge(cd)->designated_root);
+	return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
 }
-static CLASS_DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
+static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
 
-static ssize_t show_bridge_id(struct class_device *cd, char *buf)
+static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr,
+			      char *buf)
 {
-	return br_show_bridge_id(buf, &to_bridge(cd)->bridge_id);
+	return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
 }
-static CLASS_DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
+static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
 
-static ssize_t show_root_port(struct class_device *cd, char *buf)
+static ssize_t show_root_port(struct device *d, struct device_attribute *attr,
+			      char *buf)
 {
-	return sprintf(buf, "%d\n", to_bridge(cd)->root_port);
+	return sprintf(buf, "%d\n", to_bridge(d)->root_port);
 }
-static CLASS_DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
+static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
 
-static ssize_t show_root_path_cost(struct class_device *cd, char *buf)
+static ssize_t show_root_path_cost(struct device *d,
+				   struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", to_bridge(cd)->root_path_cost);
+	return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost);
 }
-static CLASS_DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
+static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
 
-static ssize_t show_topology_change(struct class_device *cd, char *buf)
+static ssize_t show_topology_change(struct device *d,
+				    struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", to_bridge(cd)->topology_change);
+	return sprintf(buf, "%d\n", to_bridge(d)->topology_change);
 }
-static CLASS_DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
+static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
 
-static ssize_t show_topology_change_detected(struct class_device *cd, char *buf)
+static ssize_t show_topology_change_detected(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%d\n", br->topology_change_detected);
 }
-static CLASS_DEVICE_ATTR(topology_change_detected, S_IRUGO, show_topology_change_detected, NULL);
+static DEVICE_ATTR(topology_change_detected, S_IRUGO,
+		   show_topology_change_detected, NULL);
 
-static ssize_t show_hello_timer(struct class_device *cd, char *buf)
+static ssize_t show_hello_timer(struct device *d,
+				struct device_attribute *attr, char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer));
 }
-static CLASS_DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
+static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
 
-static ssize_t show_tcn_timer(struct class_device *cd, char *buf)
+static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr,
+			      char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer));
 }
-static CLASS_DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
+static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
 
-static ssize_t show_topology_change_timer(struct class_device *cd, char *buf)
+static ssize_t show_topology_change_timer(struct device *d,
+					  struct device_attribute *attr,
+					  char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer));
 }
-static CLASS_DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer, NULL);
+static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer,
+		   NULL);
 
-static ssize_t show_gc_timer(struct class_device *cd, char *buf)
+static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr,
+			     char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer));
 }
-static CLASS_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
+static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
 
-static ssize_t show_group_addr(struct class_device *cd, char *buf)
+static ssize_t show_group_addr(struct device *d,
+			       struct device_attribute *attr, char *buf)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	return sprintf(buf, "%x:%x:%x:%x:%x:%x\n",
 		       br->group_addr[0], br->group_addr[1],
 		       br->group_addr[2], br->group_addr[3],
 		       br->group_addr[4], br->group_addr[5]);
 }
 
-static ssize_t store_group_addr(struct class_device *cd, const char *buf,
-				    size_t len)
+static ssize_t store_group_addr(struct device *d,
+				struct device_attribute *attr,
+				const char *buf, size_t len)
 {
-	struct net_bridge *br = to_bridge(cd);
+	struct net_bridge *br = to_bridge(d);
 	unsigned new_addr[6];
 	int i;
 
@@ -286,28 +306,28 @@ static ssize_t store_group_addr(struct class_device *cd, const char *buf,
 	return len;
 }
 
-static CLASS_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
-			 show_group_addr, store_group_addr);
+static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
+		   show_group_addr, store_group_addr);
 
 
 static struct attribute *bridge_attrs[] = {
-	&class_device_attr_forward_delay.attr,
-	&class_device_attr_hello_time.attr,
-	&class_device_attr_max_age.attr,
-	&class_device_attr_ageing_time.attr,
-	&class_device_attr_stp_state.attr,
-	&class_device_attr_priority.attr,
-	&class_device_attr_bridge_id.attr,
-	&class_device_attr_root_id.attr,
-	&class_device_attr_root_path_cost.attr,
-	&class_device_attr_root_port.attr,
-	&class_device_attr_topology_change.attr,
-	&class_device_attr_topology_change_detected.attr,
-	&class_device_attr_hello_timer.attr,
-	&class_device_attr_tcn_timer.attr,
-	&class_device_attr_topology_change_timer.attr,
-	&class_device_attr_gc_timer.attr,
-	&class_device_attr_group_addr.attr,
+	&dev_attr_forward_delay.attr,
+	&dev_attr_hello_time.attr,
+	&dev_attr_max_age.attr,
+	&dev_attr_ageing_time.attr,
+	&dev_attr_stp_state.attr,
+	&dev_attr_priority.attr,
+	&dev_attr_bridge_id.attr,
+	&dev_attr_root_id.attr,
+	&dev_attr_root_path_cost.attr,
+	&dev_attr_root_port.attr,
+	&dev_attr_topology_change.attr,
+	&dev_attr_topology_change_detected.attr,
+	&dev_attr_hello_timer.attr,
+	&dev_attr_tcn_timer.attr,
+	&dev_attr_topology_change_timer.attr,
+	&dev_attr_gc_timer.attr,
+	&dev_attr_group_addr.attr,
 	NULL
 };
 
@@ -325,8 +345,8 @@ static struct attribute_group bridge_group = {
 static ssize_t brforward_read(struct kobject *kobj, char *buf,
 			   loff_t off, size_t count)
 {
-	struct class_device *cdev = to_class_dev(kobj);
-	struct net_bridge *br = to_bridge(cdev);
+	struct device *dev = to_dev(kobj);
+	struct net_bridge *br = to_bridge(dev);
 	int n;
 
 	/* must read whole records */
@@ -363,7 +383,7 @@ static struct bin_attribute bridge_forward = {
  */
 int br_sysfs_addbr(struct net_device *dev)
 {
-	struct kobject *brobj = &dev->class_dev.kobj;
+	struct kobject *brobj = &dev->dev.kobj;
 	struct net_bridge *br = netdev_priv(dev);
 	int err;
 
@@ -395,9 +415,9 @@ int br_sysfs_addbr(struct net_device *dev)
 	}
 	return 0;
  out3:
-	sysfs_remove_bin_file(&dev->class_dev.kobj, &bridge_forward);
+	sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
  out2:
-	sysfs_remove_group(&dev->class_dev.kobj, &bridge_group);
+	sysfs_remove_group(&dev->dev.kobj, &bridge_group);
  out1:
 	return err;
 
@@ -405,7 +425,7 @@ int br_sysfs_addbr(struct net_device *dev)
 
 void br_sysfs_delbr(struct net_device *dev)
 {
-	struct kobject *kobj = &dev->class_dev.kobj;
+	struct kobject *kobj = &dev->dev.kobj;
 	struct net_bridge *br = netdev_priv(dev);
 
 	kobject_unregister(&br->ifobj);

+ 1 - 1
net/bridge/br_sysfs_if.c

@@ -211,7 +211,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
 	struct brport_attribute **a;
 	int err;
 
-	err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj, 
+	err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj,
 				SYSFS_BRIDGE_PORT_LINK);
 	if (err)
 		goto out2;

+ 3 - 3
net/core/dev.c

@@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
 	else
 		strlcpy(dev->name, newname, IFNAMSIZ);
 
-	err = class_device_rename(&dev->class_dev, dev->name);
+	err = device_rename(&dev->dev, dev->name);
 	if (!err) {
 		hlist_del(&dev->name_hlist);
 		hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
@@ -3221,8 +3221,8 @@ void free_netdev(struct net_device *dev)
 	BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
 	dev->reg_state = NETREG_RELEASED;
 
-	/* will free via class release */
-	class_device_put(&dev->class_dev);
+	/* will free via device release */
+	put_device(&dev->dev);
 #else
 	kfree((char *)dev - dev->padded);
 #endif

+ 93 - 82
net/core/net-sysfs.c

@@ -18,9 +18,6 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 
-#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_long_hex[] = "%#lx\n";
 static const char fmt_dec[] = "%d\n";
@@ -32,10 +29,11 @@ static inline int dev_isalive(const struct net_device *dev)
 }
 
 /* use same locking rules as GIF* ioctl's */
-static ssize_t netdev_show(const struct class_device *cd, char *buf,
+static ssize_t netdev_show(const struct device *dev,
+			   struct device_attribute *attr, char *buf,
 			   ssize_t (*format)(const struct net_device *, char *))
 {
-	struct net_device *net = to_net_dev(cd);
+	struct net_device *net = to_net_dev(dev);
 	ssize_t ret = -EINVAL;
 
 	read_lock(&dev_base_lock);
@@ -52,14 +50,15 @@ static ssize_t format_##field(const struct net_device *net, char *buf)	\
 {									\
 	return sprintf(buf, format_string, net->field);			\
 }									\
-static ssize_t show_##field(struct class_device *cd, char *buf)		\
+static ssize_t show_##field(struct device *dev,				\
+			    struct device_attribute *attr, char *buf)	\
 {									\
-	return netdev_show(cd, buf, format_##field);			\
+	return netdev_show(dev, attr, buf, format_##field);		\
 }
 
 
 /* use same locking and permission rules as SIF* ioctl's */
-static ssize_t netdev_store(struct class_device *dev,
+static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t len,
 			    int (*set)(struct net_device *, unsigned long))
 {
@@ -104,7 +103,8 @@ static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
 	return cp - buf;
 }
 
-static ssize_t show_address(struct class_device *dev, char *buf)
+static ssize_t show_address(struct device *dev, struct device_attribute *attr,
+			    char *buf)
 {
 	struct net_device *net = to_net_dev(dev);
 	ssize_t ret = -EINVAL;
@@ -116,7 +116,8 @@ static ssize_t show_address(struct class_device *dev, char *buf)
 	return ret;
 }
 
-static ssize_t show_broadcast(struct class_device *dev, char *buf)
+static ssize_t show_broadcast(struct device *dev,
+			    struct device_attribute *attr, char *buf)
 {
 	struct net_device *net = to_net_dev(dev);
 	if (dev_isalive(net))
@@ -124,7 +125,8 @@ static ssize_t show_broadcast(struct class_device *dev, char *buf)
 	return -EINVAL;
 }
 
-static ssize_t show_carrier(struct class_device *dev, char *buf)
+static ssize_t show_carrier(struct device *dev,
+			    struct device_attribute *attr, char *buf)
 {
 	struct net_device *netdev = to_net_dev(dev);
 	if (netif_running(netdev)) {
@@ -133,7 +135,8 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
 	return -EINVAL;
 }
 
-static ssize_t show_dormant(struct class_device *dev, char *buf)
+static ssize_t show_dormant(struct device *dev,
+			    struct device_attribute *attr, char *buf)
 {
 	struct net_device *netdev = to_net_dev(dev);
 
@@ -153,7 +156,8 @@ static const char *operstates[] = {
 	"up"
 };
 
-static ssize_t show_operstate(struct class_device *dev, char *buf)
+static ssize_t show_operstate(struct device *dev,
+			      struct device_attribute *attr, char *buf)
 {
 	const struct net_device *netdev = to_net_dev(dev);
 	unsigned char operstate;
@@ -178,9 +182,10 @@ static int change_mtu(struct net_device *net, unsigned long new_mtu)
 	return dev_set_mtu(net, (int) new_mtu);
 }
 
-static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_mtu(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t len)
 {
-	return netdev_store(dev, buf, len, change_mtu);
+	return netdev_store(dev, attr, buf, len, change_mtu);
 }
 
 NETDEVICE_SHOW(flags, fmt_hex);
@@ -190,9 +195,10 @@ static int change_flags(struct net_device *net, unsigned long new_flags)
 	return dev_change_flags(net, (unsigned) new_flags);
 }
 
-static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_flags(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t len)
 {
-	return netdev_store(dev, buf, len, change_flags);
+	return netdev_store(dev, attr, buf, len, change_flags);
 }
 
 NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
@@ -203,9 +209,11 @@ static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
 	return 0;
 }
 
-static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_tx_queue_len(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t len)
 {
-	return netdev_store(dev, buf, len, change_tx_queue_len);
+	return netdev_store(dev, attr, buf, len, change_tx_queue_len);
 }
 
 NETDEVICE_SHOW(weight, fmt_dec);
@@ -216,12 +224,13 @@ static int change_weight(struct net_device *net, unsigned long new_weight)
 	return 0;
 }
 
-static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_weight(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t len)
 {
-	return netdev_store(dev, buf, len, change_weight);
+	return netdev_store(dev, attr, buf, len, change_weight);
 }
 
-static struct class_device_attribute net_class_attributes[] = {
+static struct device_attribute net_class_attributes[] = {
 	__ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
 	__ATTR(iflink, S_IRUGO, show_iflink, NULL),
 	__ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
@@ -242,10 +251,11 @@ static struct class_device_attribute net_class_attributes[] = {
 };
 
 /* Show a given an attribute in the statistics group */
-static ssize_t netstat_show(const struct class_device *cd, char *buf, 
+static ssize_t netstat_show(const struct device *d,
+			    struct device_attribute *attr, char *buf,
 			    unsigned long offset)
 {
-	struct net_device *dev = to_net_dev(cd);
+	struct net_device *dev = to_net_dev(d);
 	struct net_device_stats *stats;
 	ssize_t ret = -EINVAL;
 
@@ -265,12 +275,13 @@ static ssize_t netstat_show(const struct class_device *cd, char *buf,
 
 /* generate a read-only statistics attribute */
 #define NETSTAT_ENTRY(name)						\
-static ssize_t show_##name(struct class_device *cd, char *buf) 		\
+static ssize_t show_##name(struct device *d,				\
+			   struct device_attribute *attr, char *buf) 	\
 {									\
-	return netstat_show(cd, buf, 					\
+	return netstat_show(d, attr, buf,				\
 			    offsetof(struct net_device_stats, name));	\
 }									\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
 NETSTAT_ENTRY(rx_packets);
 NETSTAT_ENTRY(tx_packets);
@@ -297,29 +308,29 @@ NETSTAT_ENTRY(rx_compressed);
 NETSTAT_ENTRY(tx_compressed);
 
 static struct attribute *netstat_attrs[] = {
-	&class_device_attr_rx_packets.attr,
-	&class_device_attr_tx_packets.attr,
-	&class_device_attr_rx_bytes.attr,
-	&class_device_attr_tx_bytes.attr,
-	&class_device_attr_rx_errors.attr,
-	&class_device_attr_tx_errors.attr,
-	&class_device_attr_rx_dropped.attr,
-	&class_device_attr_tx_dropped.attr,
-	&class_device_attr_multicast.attr,
-	&class_device_attr_collisions.attr,
-	&class_device_attr_rx_length_errors.attr,
-	&class_device_attr_rx_over_errors.attr,
-	&class_device_attr_rx_crc_errors.attr,
-	&class_device_attr_rx_frame_errors.attr,
-	&class_device_attr_rx_fifo_errors.attr,
-	&class_device_attr_rx_missed_errors.attr,
-	&class_device_attr_tx_aborted_errors.attr,
-	&class_device_attr_tx_carrier_errors.attr,
-	&class_device_attr_tx_fifo_errors.attr,
-	&class_device_attr_tx_heartbeat_errors.attr,
-	&class_device_attr_tx_window_errors.attr,
-	&class_device_attr_rx_compressed.attr,
-	&class_device_attr_tx_compressed.attr,
+	&dev_attr_rx_packets.attr,
+	&dev_attr_tx_packets.attr,
+	&dev_attr_rx_bytes.attr,
+	&dev_attr_tx_bytes.attr,
+	&dev_attr_rx_errors.attr,
+	&dev_attr_tx_errors.attr,
+	&dev_attr_rx_dropped.attr,
+	&dev_attr_tx_dropped.attr,
+	&dev_attr_multicast.attr,
+	&dev_attr_collisions.attr,
+	&dev_attr_rx_length_errors.attr,
+	&dev_attr_rx_over_errors.attr,
+	&dev_attr_rx_crc_errors.attr,
+	&dev_attr_rx_frame_errors.attr,
+	&dev_attr_rx_fifo_errors.attr,
+	&dev_attr_rx_missed_errors.attr,
+	&dev_attr_tx_aborted_errors.attr,
+	&dev_attr_tx_carrier_errors.attr,
+	&dev_attr_tx_fifo_errors.attr,
+	&dev_attr_tx_heartbeat_errors.attr,
+	&dev_attr_tx_window_errors.attr,
+	&dev_attr_rx_compressed.attr,
+	&dev_attr_tx_compressed.attr,
 	NULL
 };
 
@@ -331,11 +342,11 @@ static struct attribute_group netstat_group = {
 
 #ifdef WIRELESS_EXT
 /* helper function that does all the locking etc for wireless stats */
-static ssize_t wireless_show(struct class_device *cd, char *buf,
+static ssize_t wireless_show(struct device *d, char *buf,
 			     ssize_t (*format)(const struct iw_statistics *,
 					       char *))
 {
-	struct net_device *dev = to_net_dev(cd);
+	struct net_device *dev = to_net_dev(d);
 	const struct iw_statistics *iw = NULL;
 	ssize_t ret = -EINVAL;
 	
@@ -358,11 +369,12 @@ static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \
 {									\
 	return sprintf(buf, format_string, iw->field);			\
 }									\
-static ssize_t show_iw_##name(struct class_device *cd, char *buf)	\
+static ssize_t show_iw_##name(struct device *d,				\
+			      struct device_attribute *attr, char *buf)	\
 {									\
-	return wireless_show(cd, buf, format_iw_##name);		\
+	return wireless_show(d, buf, format_iw_##name);			\
 }									\
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
+static DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
 
 WIRELESS_SHOW(status, status, fmt_hex);
 WIRELESS_SHOW(link, qual.qual, fmt_dec);
@@ -376,16 +388,16 @@ WIRELESS_SHOW(retries, discard.retries, fmt_dec);
 WIRELESS_SHOW(beacon, miss.beacon, fmt_dec);
 
 static struct attribute *wireless_attrs[] = {
-	&class_device_attr_status.attr,
-	&class_device_attr_link.attr,
-	&class_device_attr_level.attr,
-	&class_device_attr_noise.attr,
-	&class_device_attr_nwid.attr,
-	&class_device_attr_crypt.attr,
-	&class_device_attr_fragment.attr,
-	&class_device_attr_retries.attr,
-	&class_device_attr_misc.attr,
-	&class_device_attr_beacon.attr,
+	&dev_attr_status.attr,
+	&dev_attr_link.attr,
+	&dev_attr_level.attr,
+	&dev_attr_noise.attr,
+	&dev_attr_nwid.attr,
+	&dev_attr_crypt.attr,
+	&dev_attr_fragment.attr,
+	&dev_attr_retries.attr,
+	&dev_attr_misc.attr,
+	&dev_attr_beacon.attr,
 	NULL
 };
 
@@ -396,10 +408,10 @@ static struct attribute_group wireless_group = {
 #endif
 
 #ifdef CONFIG_HOTPLUG
-static int netdev_uevent(struct class_device *cd, char **envp,
+static int netdev_uevent(struct device *d, char **envp,
 			 int num_envp, char *buf, int size)
 {
-	struct net_device *dev = to_net_dev(cd);
+	struct net_device *dev = to_net_dev(d);
 	int i = 0;
 	int n;
 
@@ -419,12 +431,11 @@ static int netdev_uevent(struct class_device *cd, char **envp,
 
 /*
  *	netdev_release -- destroy and free a dead device. 
- *	Called when last reference to class_device kobject is gone.
+ *	Called when last reference to device kobject is gone.
  */
-static void netdev_release(struct class_device *cd)
+static void netdev_release(struct device *d)
 {
-	struct net_device *dev 
-		= container_of(cd, struct net_device, class_dev);
+	struct net_device *dev = to_net_dev(d);
 
 	BUG_ON(dev->reg_state != NETREG_RELEASED);
 
@@ -433,31 +444,31 @@ static void netdev_release(struct class_device *cd)
 
 static struct class net_class = {
 	.name = "net",
-	.release = netdev_release,
-	.class_dev_attrs = net_class_attributes,
+	.dev_release = netdev_release,
+	.dev_attrs = net_class_attributes,
 #ifdef CONFIG_HOTPLUG
-	.uevent = netdev_uevent,
+	.dev_uevent = netdev_uevent,
 #endif
 };
 
 void netdev_unregister_sysfs(struct net_device * net)
 {
-	class_device_del(&(net->class_dev));
+	device_del(&(net->dev));
 }
 
 /* Create sysfs entries for network device. */
 int netdev_register_sysfs(struct net_device *net)
 {
-	struct class_device *class_dev = &(net->class_dev);
+	struct device *dev = &(net->dev);
 	struct attribute_group **groups = net->sysfs_groups;
 
-	class_device_initialize(class_dev);
-	class_dev->class = &net_class;
-	class_dev->class_data = net;
-	class_dev->groups = groups;
+	device_initialize(dev);
+	dev->class = &net_class;
+	dev->platform_data = net;
+	dev->groups = groups;
 
 	BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
-	strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
+	strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
 
 	if (net->get_stats)
 		*groups++ = &netstat_group;
@@ -467,7 +478,7 @@ int netdev_register_sysfs(struct net_device *net)
 		*groups++ = &wireless_group;
 #endif
 
-	return class_device_add(class_dev);
+	return device_add(dev);
 }
 
 int netdev_sysfs_init(void)

+ 1 - 1
net/core/skbuff.c

@@ -268,7 +268,7 @@ nodata:
 struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
 		unsigned int length, gfp_t gfp_mask)
 {
-	int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1;
+	int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
 	struct sk_buff *skb;
 
  	skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);