diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Tue Oct  8 17:55:22 2002
+++ b/drivers/base/core.c	Tue Oct  8 17:55:22 2002
@@ -175,7 +175,7 @@
 	INIT_LIST_HEAD(&dev->intf_list);
 	spin_lock_init(&dev->lock);
 	atomic_set(&dev->refcount,2);
-	
+	dev->present = 1;
 	spin_lock(&device_lock);
 	if (dev->parent) {
 		get_device_locked(dev->parent);
@@ -219,7 +219,7 @@
 struct device * get_device_locked(struct device * dev)
 {
 	struct device * ret = dev;
-	if (dev && atomic_read(&dev->refcount) > 0)
+	if (dev && dev->present && atomic_read(&dev->refcount) > 0)
 		atomic_inc(&dev->refcount);
 	else
 		ret = NULL;
@@ -241,8 +241,35 @@
  */
 void put_device(struct device * dev)
 {
+	struct device * parent;
 	if (!atomic_dec_and_lock(&dev->refcount,&device_lock))
 		return;
+	parent = dev->parent;
+	dev->parent = NULL;
+	spin_unlock(&device_lock);
+
+	BUG_ON(dev->present);
+
+	if (dev->release)
+		dev->release(dev);
+
+	if (parent)
+		put_device(parent);
+}
+
+/**
+ * device_unregister - unlink device
+ * @dev:	device going away
+ *
+ * The device has been removed from the system, so we disavow knowledge
+ * of it. It might not be the final reference to the device, so we mark
+ * it as !present, so no more references to it can be acquired.
+ * In the end, we decrement the final reference count for it.
+ */
+void device_unregister(struct device * dev)
+{
+	spin_lock(&device_lock);
+	dev->present = 0;
 	list_del_init(&dev->node);
 	list_del_init(&dev->g_list);
 	list_del_init(&dev->bus_list);
@@ -267,11 +294,7 @@
 	/* remove the driverfs directory */
 	device_remove_dir(dev);
 
-	if (dev->release)
-		dev->release(dev);
-
-	if (dev->parent)
-		put_device(dev->parent);
+	put_device(dev);
 }
 
 static int __init device_init(void)
@@ -287,5 +310,6 @@
 core_initcall(device_init);
 
 EXPORT_SYMBOL(device_register);
+EXPORT_SYMBOL(device_unregister);
 EXPORT_SYMBOL(get_device);
 EXPORT_SYMBOL(put_device);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Tue Oct  8 17:55:22 2002
+++ b/include/linux/device.h	Tue Oct  8 17:55:22 2002
@@ -289,6 +289,7 @@
 	void		*platform_data;	/* Platform specific data (e.g. ACPI,
 					   BIOS data relevant to device) */
 
+	u32		present;
 	u32		current_state;  /* Current operating state. In
 					   ACPI-speak, this is D0-D3, D0
 					   being fully functional, and D3
@@ -327,7 +328,7 @@
  * High level routines for use by the bus drivers
  */
 extern int device_register(struct device * dev);
-
+extern void device_unregister(struct device * dev);
 
 /* driverfs interface for exporting device attributes */
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/