Index: usb-devel/drivers/media/usb/usbvision/usbvision-video.c
===================================================================
--- usb-devel.orig/drivers/media/usb/usbvision/usbvision-video.c
+++ usb-devel/drivers/media/usb/usbvision/usbvision-video.c
@@ -131,6 +131,26 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(USBVISION_VERSION_STRING);
 MODULE_ALIAS(DRIVER_ALIAS);
 
+#include <linux/kernfs.h>
+#include <linux/kobject.h>
+
+static void usbvision_check(struct usb_usbvision *usbvision, char *msg)
+{
+	struct kernfs_node *kn;
+
+	if (!video_is_registered(&usbvision->rdev)) {
+		dev_info(&usbvision->rdev.dev, "AS Not registered: %s\n", msg);
+	} else {
+		kn = kernfs_find_and_get(usbvision->rdev.dev.kobj.sd, "power");
+		if (kn) {
+			kernfs_put(kn);
+			dev_info(&usbvision->rdev.dev, "AS Power ok: %s\n", msg);
+		} else {
+			dev_err(&usbvision->rdev.dev, "AS Power gone: %s\n", msg);
+		}
+	}
+}
+
 
 /*****************************************************************************/
 /* SYSFS Code - Copied from the stv680.c usb module.			     */
@@ -314,6 +334,10 @@ static int usbvision_v4l2_open(struct fi
 	if (mutex_lock_interruptible(&usbvision->v4l2_lock))
 		return -ERESTARTSYS;
 
+	if (usbvision->remove_pending) {
+		err_code = -ENODEV;
+		goto unlock;
+	}
 	if (usbvision->user) {
 		err_code = -EBUSY;
 	} else {
@@ -377,6 +401,7 @@ unlock:
 static int usbvision_v4l2_close(struct file *file)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
+	int r;
 
 	PDEBUG(DBG_IO, "close");
 
@@ -391,9 +416,10 @@ static int usbvision_v4l2_close(struct f
 	usbvision_scratch_free(usbvision);
 
 	usbvision->user--;
+	r = usbvision->remove_pending;
 	mutex_unlock(&usbvision->v4l2_lock);
 
-	if (usbvision->remove_pending) {
+	if (r) {
 		printk(KERN_INFO "%s: Final disconnect\n", __func__);
 		usbvision_release(usbvision);
 		return 0;
@@ -453,6 +479,9 @@ static int vidioc_querycap(struct file *
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
 
+	if (!usbvision->dev)
+		return -ENODEV;
+
 	strscpy(vc->driver, "USBVision", sizeof(vc->driver));
 	strscpy(vc->card,
 		usbvision_device_data[usbvision->dev_model].model_string,
@@ -1073,6 +1102,11 @@ static int usbvision_radio_open(struct f
 
 	if (mutex_lock_interruptible(&usbvision->v4l2_lock))
 		return -ERESTARTSYS;
+
+	if (usbvision->remove_pending) {
+		err_code = -ENODEV;
+		goto out;
+	}
 	err_code = v4l2_fh_open(file);
 	if (err_code)
 		goto out;
@@ -1105,21 +1139,28 @@ out:
 static int usbvision_radio_close(struct file *file)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
+	int r;
 
 	PDEBUG(DBG_IO, "");
 
+	usbvision_check(usbvision, "radio close 1");
 	mutex_lock(&usbvision->v4l2_lock);
+	usbvision_check(usbvision, "radio close 2");
 	/* Set packet size to 0 */
 	usbvision->iface_alt = 0;
-	usb_set_interface(usbvision->dev, usbvision->iface,
+	if (usbvision->dev)
+		usb_set_interface(usbvision->dev, usbvision->iface,
 				    usbvision->iface_alt);
 
+	usbvision_check(usbvision, "radio close 3");
 	usbvision_audio_off(usbvision);
 	usbvision->radio = 0;
 	usbvision->user--;
+	r = usbvision->remove_pending;
+	usbvision_check(usbvision, "radio close 4");
 	mutex_unlock(&usbvision->v4l2_lock);
 
-	if (usbvision->remove_pending) {
+	if (r) {
 		printk(KERN_INFO "%s: Final disconnect\n", __func__);
 		v4l2_fh_release(file);
 		usbvision_release(usbvision);
@@ -1236,6 +1277,7 @@ static void usbvision_unregister_video(s
 	if (video_is_registered(&usbvision->rdev)) {
 		PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
 		       video_device_node_name(&usbvision->rdev));
+		usbvision_check(usbvision, "unregister_video");
 		video_unregister_device(&usbvision->rdev);
 	}
 
@@ -1551,6 +1593,7 @@ err_usb:
 static void usbvision_disconnect(struct usb_interface *intf)
 {
 	struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf));
+	int u;
 
 	PDEBUG(DBG_PROBE, "");
 
@@ -1567,13 +1610,14 @@ static void usbvision_disconnect(struct
 	v4l2_device_disconnect(&usbvision->v4l2_dev);
 	usbvision_i2c_unregister(usbvision);
 	usbvision->remove_pending = 1;	/* Now all ISO data will be ignored */
+	u = usbvision->user;
 
 	usb_put_dev(usbvision->dev);
 	usbvision->dev = NULL;	/* USB device is no more */
 
 	mutex_unlock(&usbvision->v4l2_lock);
 
-	if (usbvision->user) {
+	if (u) {
 		printk(KERN_INFO "%s: In use, disconnect pending\n",
 		       __func__);
 		wake_up_interruptible(&usbvision->wait_frame);
Index: usb-devel/drivers/base/power/sysfs.c
===================================================================
--- usb-devel.orig/drivers/base/power/sysfs.c
+++ usb-devel/drivers/base/power/sysfs.c
@@ -11,6 +11,10 @@
 #include <linux/jiffies.h>
 #include "power.h"
 
+#include <linux/kernfs.h>
+extern void ASadd(struct kernfs_node *parent);
+extern void ASremove(struct kernfs_node *parent);
+
 /*
  *	control - Report/change current runtime PM setting of the device
  *
@@ -652,6 +656,8 @@ int dpm_sysfs_add(struct device *dev)
 	rc = sysfs_create_group(&dev->kobj, &pm_attr_group);
 	if (rc)
 		return rc;
+	if (strncmp(dev_name(dev), "radio", 5) == 0)
+		ASadd(&dev->kobj.sd);
 
 	if (pm_runtime_callbacks_present(dev)) {
 		rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group);
@@ -676,6 +682,8 @@ int dpm_sysfs_add(struct device *dev)
  err_runtime:
 	sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group);
  err_out:
+	if (strncmp(dev_name(dev), "radio", 5) == 0)
+		ASremove(&dev->kobj.sd);
 	sysfs_remove_group(&dev->kobj, &pm_attr_group);
 	return rc;
 }
@@ -734,5 +742,7 @@ void dpm_sysfs_remove(struct device *dev
 	dev_pm_qos_constraints_destroy(dev);
 	rpm_sysfs_remove(dev);
 	sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
+	if (strncmp(dev_name(dev), "radio", 5) == 0)
+		ASremove(&dev->kobj.sd);
 	sysfs_remove_group(&dev->kobj, &pm_attr_group);
 }
Index: usb-devel/fs/kernfs/dir.c
===================================================================
--- usb-devel.orig/fs/kernfs/dir.c
+++ usb-devel/fs/kernfs/dir.c
@@ -25,6 +25,46 @@ static DEFINE_SPINLOCK(kernfs_idr_lock);
 
 #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb)
 
+static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent,
+					  const unsigned char *name,
+					  const void *ns);
+
+static LIST_HEAD(ASlist);
+static DEFINE_MUTEX(ASmutex);
+
+void ASadd(struct kernfs_node *parent)
+{
+	mutex_lock(&ASmutex);
+	list_add(&parent->ASnode, &ASlist);
+	mutex_unlock(&ASmutex);
+}
+EXPORT_SYMBOL_GPL(ASadd);
+
+void ASremove(struct kernfs_node *parent)
+{
+	mutex_lock(&ASmutex);
+	list_del(&parent->ASnode);
+	mutex_unlock(&ASmutex);
+}
+EXPORT_SYMBOL_GPL(ASremove);
+
+static void AScheck(void)
+{
+	struct kernfs_node *parent, *tmp;
+	kernfs_node *kn;
+
+	mutex_lock(&ASmutex);
+	list_for_each_entry_safe(parent, tmp, &ASlist, ASnode) {
+		kn = kernfs_find_ns(parent, "power", NULL);
+		if (!kn) {
+			printk(KERN_WARNING "Missing power for %s\n", parent->name);
+			dump_stack();
+			list_del_init(&parent->ASnode);
+		}
+	}
+	mutex_unlock(&ASmutex);
+}
+
 static bool kernfs_active(struct kernfs_node *kn)
 {
 	lockdep_assert_held(&kernfs_mutex);
@@ -462,6 +502,7 @@ static void kernfs_drain(struct kernfs_n
 	lockdep_assert_held(&kernfs_mutex);
 	WARN_ON_ONCE(kernfs_active(kn));
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 
 	if (kernfs_lockdep(kn)) {
@@ -482,6 +523,7 @@ static void kernfs_drain(struct kernfs_n
 	kernfs_drain_open_files(kn);
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 }
 
 /**
@@ -568,6 +610,7 @@ static int kernfs_dop_revalidate(struct
 
 	kn = kernfs_dentry_node(dentry);
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	/* The kernfs node has been deactivated */
 	if (!kernfs_active(kn))
@@ -586,9 +629,11 @@ static int kernfs_dop_revalidate(struct
 	    kernfs_info(dentry->d_sb)->ns != kn->ns)
 		goto out_bad;
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	return 1;
 out_bad:
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 out_bad_unlocked:
 	return 0;
@@ -769,6 +814,7 @@ int kernfs_add_one(struct kernfs_node *k
 	int ret;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	ret = -EINVAL;
 	has_ns = kernfs_ns_enabled(parent);
@@ -800,6 +846,7 @@ int kernfs_add_one(struct kernfs_node *k
 		ps_iattrs->ia_mtime = ps_iattrs->ia_ctime;
 	}
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 
 	/*
@@ -814,6 +861,7 @@ int kernfs_add_one(struct kernfs_node *k
 	return 0;
 
 out_unlock:
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	return ret;
 }
@@ -932,8 +980,10 @@ struct kernfs_node *kernfs_walk_and_get_
 	struct kernfs_node *kn;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 	kn = kernfs_walk_ns(parent, path, ns);
 	kernfs_get(kn);
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 
 	return kn;
@@ -1080,6 +1130,7 @@ static struct dentry *kernfs_iop_lookup(
 	const void *ns = NULL;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	if (kernfs_ns_enabled(parent))
 		ns = kernfs_info(dir->i_sb)->ns;
@@ -1102,6 +1153,7 @@ static struct dentry *kernfs_iop_lookup(
 	/* instantiate and hash dentry */
 	ret = d_splice_alias(inode, dentry);
  out_unlock:
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	return ret;
 }
@@ -1258,6 +1310,7 @@ void kernfs_activate(struct kernfs_node
 	struct kernfs_node *pos;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	pos = NULL;
 	while ((pos = kernfs_next_descendant_post(pos, kn))) {
@@ -1271,6 +1324,7 @@ void kernfs_activate(struct kernfs_node
 		pos->flags |= KERNFS_ACTIVATED;
 	}
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 }
 
@@ -1350,7 +1404,9 @@ static void __kernfs_remove(struct kernf
 void kernfs_remove(struct kernfs_node *kn)
 {
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 	__kernfs_remove(kn);
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 }
 
@@ -1439,6 +1495,7 @@ bool kernfs_remove_self(struct kernfs_no
 	bool ret;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 	kernfs_break_active_protection(kn);
 
 	/*
@@ -1466,9 +1523,11 @@ bool kernfs_remove_self(struct kernfs_no
 			    atomic_read(&kn->active) == KN_DEACTIVATED_BIAS)
 				break;
 
+			AScheck();
 			mutex_unlock(&kernfs_mutex);
 			schedule();
 			mutex_lock(&kernfs_mutex);
+			AScheck();
 		}
 		finish_wait(waitq, &wait);
 		WARN_ON_ONCE(!RB_EMPTY_NODE(&kn->rb));
@@ -1481,6 +1540,7 @@ bool kernfs_remove_self(struct kernfs_no
 	 */
 	kernfs_unbreak_active_protection(kn);
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	return ret;
 }
@@ -1506,11 +1566,13 @@ int kernfs_remove_by_name_ns(struct kern
 	}
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	kn = kernfs_find_ns(parent, name, ns);
 	if (kn)
 		__kernfs_remove(kn);
 
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 
 	if (kn)
@@ -1538,6 +1600,7 @@ int kernfs_rename_ns(struct kernfs_node
 		return -EINVAL;
 
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	error = -ENOENT;
 	if (!kernfs_active(kn) || !kernfs_active(new_parent) ||
@@ -1591,6 +1654,7 @@ int kernfs_rename_ns(struct kernfs_node
 
 	error = 0;
  out:
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	return error;
 }
@@ -1667,6 +1731,7 @@ static int kernfs_fop_readdir(struct fil
 	if (!dir_emit_dots(file, ctx))
 		return 0;
 	mutex_lock(&kernfs_mutex);
+	AScheck();
 
 	if (kernfs_ns_enabled(parent))
 		ns = kernfs_info(dentry->d_sb)->ns;
@@ -1683,11 +1748,14 @@ static int kernfs_fop_readdir(struct fil
 		file->private_data = pos;
 		kernfs_get(pos);
 
+		AScheck();
 		mutex_unlock(&kernfs_mutex);
 		if (!dir_emit(ctx, name, len, ino, type))
 			return 0;
 		mutex_lock(&kernfs_mutex);
+		AScheck();
 	}
+	AScheck();
 	mutex_unlock(&kernfs_mutex);
 	file->private_data = NULL;
 	ctx->pos = INT_MAX;
Index: usb-devel/include/linux/kernfs.h
===================================================================
--- usb-devel.orig/include/linux/kernfs.h
+++ usb-devel/include/linux/kernfs.h
@@ -160,6 +160,7 @@ struct kernfs_node {
 	unsigned short		flags;
 	umode_t			mode;
 	struct kernfs_iattrs	*iattr;
+	struct list_head	ASnode;
 };
 
 /*