diff -druN linux-2.6.32.53-libre2/Documentation/development-process/5.Posting linux-2.6.32.54-libre2/Documentation/development-process/5.Posting
--- linux-2.6.32.53-libre2/Documentation/development-process/5.Posting	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/Documentation/development-process/5.Posting	2012-01-12 14:53:50.000000000 -0500
@@ -267,10 +267,10 @@
    the linux-kernel list.
 
  - If you are fixing a bug, think about whether the fix should go into the
-   next stable update.  If so, stable@kernel.org should get a copy of the
-   patch.  Also add a "Cc: stable@kernel.org" to the tags within the patch
-   itself; that will cause the stable team to get a notification when your
-   fix goes into the mainline.
+   next stable update.  If so, stable@vger.kernel.org should get a copy of
+   the patch.  Also add a "Cc: stable@vger.kernel.org" to the tags within
+   the patch itself; that will cause the stable team to get a notification
+   when your fix goes into the mainline.
 
 When selecting recipients for a patch, it is good to have an idea of who
 you think will eventually accept the patch and get it merged.  While it
diff -druN linux-2.6.32.53-libre2/Documentation/HOWTO linux-2.6.32.54-libre2/Documentation/HOWTO
--- linux-2.6.32.53-libre2/Documentation/HOWTO	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/Documentation/HOWTO	2012-01-12 14:53:50.000000000 -0500
@@ -275,8 +275,8 @@
 If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
 kernel is the current stable kernel.
 
-2.6.x.y are maintained by the "stable" team <stable@kernel.org>, and are
-released as needs dictate.  The normal release period is approximately 
+2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
+are released as needs dictate.  The normal release period is approximately
 two weeks, but it can be longer if there are no pressing problems.  A
 security-related problem, instead, can cause a release to happen almost
 instantly.
diff -druN linux-2.6.32.53-libre2/Documentation/usb/usbmon.txt linux-2.6.32.54-libre2/Documentation/usb/usbmon.txt
--- linux-2.6.32.53-libre2/Documentation/usb/usbmon.txt	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/Documentation/usb/usbmon.txt	2012-01-12 14:53:50.000000000 -0500
@@ -43,10 +43,11 @@
 
 2. Find which bus connects to the desired device
 
-Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to
-the device. Usually you do it by looking for the vendor string. If you have
-many similar devices, unplug one and compare two /proc/bus/usb/devices outputs.
-The T-line will have a bus number. Example:
+Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds
+to the device. Usually you do it by looking for the vendor string. If you have
+many similar devices, unplug one and compare the two
+/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number.
+Example:
 
 T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
 D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
@@ -54,7 +55,10 @@
 S:  Manufacturer=ATEN
 S:  Product=UC100KM V2.00
 
-Bus=03 means it's bus 3.
+"Bus=03" means it's bus 3. Alternatively, you can look at the output from
+"lsusb" and get the bus number from the appropriate line. Example:
+
+Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00
 
 3. Start 'cat'
 
diff -druN linux-2.6.32.53-libre2/drivers/base/firmware_class.c linux-2.6.32.54-libre2/drivers/base/firmware_class.c
--- linux-2.6.32.53-libre2/drivers/base/firmware_class.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/base/firmware_class.c	2012-01-12 14:53:50.000000000 -0500
@@ -161,13 +161,13 @@
 	int loading = simple_strtol(buf, NULL, 10);
 	int i;
 
+	mutex_lock(&fw_lock);
+
+	if (!fw_priv->fw)
+		goto out;
+
 	switch (loading) {
 	case 1:
-		mutex_lock(&fw_lock);
-		if (!fw_priv->fw) {
-			mutex_unlock(&fw_lock);
-			break;
-		}
 		firmware_free_data(fw_priv->fw);
 		memset(fw_priv->fw, 0, sizeof(struct firmware));
 		/* If the pages are not owned by 'struct firmware' */
@@ -178,7 +178,6 @@
 		fw_priv->page_array_size = 0;
 		fw_priv->nr_pages = 0;
 		set_bit(FW_STATUS_LOADING, &fw_priv->status);
-		mutex_unlock(&fw_lock);
 		break;
 	case 0:
 		if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
@@ -209,7 +208,8 @@
 		fw_load_abort(fw_priv);
 		break;
 	}
-
+out:
+	mutex_unlock(&fw_lock);
 	return count;
 }
 
diff -druN linux-2.6.32.53-libre2/drivers/net/usb/asix.c linux-2.6.32.54-libre2/drivers/net/usb/asix.c
--- linux-2.6.32.53-libre2/drivers/net/usb/asix.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/net/usb/asix.c	2012-01-12 14:53:50.000000000 -0500
@@ -339,7 +339,7 @@
 
 		skb_pull(skb, (size + 1) & 0xfffe);
 
-		if (skb->len == 0)
+		if (skb->len < sizeof(header))
 			break;
 
 		head = (u8 *) skb->data;
@@ -1522,6 +1522,10 @@
 	// ASIX 88772a
 	USB_DEVICE(0x0db0, 0xa877),
 	.driver_info = (unsigned long) &ax88772_info,
+}, {
+	// Asus USB Ethernet Adapter
+	USB_DEVICE (0x0b95, 0x7e2b),
+	.driver_info = (unsigned long) &ax88772_info,
 },
 	{ },		// END
 };
diff -druN linux-2.6.32.53-libre2/drivers/scsi/device_handler/scsi_dh.c linux-2.6.32.54-libre2/drivers/scsi/device_handler/scsi_dh.c
--- linux-2.6.32.53-libre2/drivers/scsi/device_handler/scsi_dh.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/scsi/device_handler/scsi_dh.c	2012-01-12 14:53:50.000000000 -0500
@@ -432,7 +432,12 @@
 
 	spin_lock_irqsave(q->queue_lock, flags);
 	sdev = q->queuedata;
-	if (sdev && sdev->scsi_dh_data)
+	if (!sdev) {
+		spin_unlock_irqrestore(q->queue_lock, flags);
+		return SCSI_DH_NOSYS;
+	}
+
+	if (sdev->scsi_dh_data)
 		scsi_dh = sdev->scsi_dh_data->scsi_dh;
 	if (!scsi_dh || !get_device(&sdev->sdev_gendev))
 		err = SCSI_DH_NOSYS;
diff -druN linux-2.6.32.53-libre2/drivers/usb/class/cdc-acm.c linux-2.6.32.54-libre2/drivers/usb/class/cdc-acm.c
--- linux-2.6.32.53-libre2/drivers/usb/class/cdc-acm.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/class/cdc-acm.c	2012-01-12 14:53:50.000000000 -0500
@@ -1264,6 +1264,8 @@
 		i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
 		if (i < 0) {
 			kfree(acm->country_codes);
+			acm->country_codes = NULL;
+			acm->country_code_size = 0;
 			goto skip_countries;
 		}
 
@@ -1272,6 +1274,8 @@
 		if (i < 0) {
 			device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
 			kfree(acm->country_codes);
+			acm->country_codes = NULL;
+			acm->country_code_size = 0;
 			goto skip_countries;
 		}
 	}
diff -druN linux-2.6.32.53-libre2/drivers/usb/core/quirks.c linux-2.6.32.54-libre2/drivers/usb/core/quirks.c
--- linux-2.6.32.53-libre2/drivers/usb/core/quirks.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/core/quirks.c	2012-01-12 14:53:50.000000000 -0500
@@ -114,9 +114,12 @@
 	{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
 			USB_QUIRK_CONFIG_INTF_STRINGS },
 
-	/* Guillemot Webcam Hercules Dualpix Exchange*/
+	/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
 	{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Guillemot Webcam Hercules Dualpix Exchange*/
+	{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* M-Systems Flash Disk Pioneers */
 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff -druN linux-2.6.32.53-libre2/drivers/usb/misc/isight_firmware.c linux-2.6.32.54-libre2/drivers/usb/misc/isight_firmware.c
--- linux-2.6.32.53-libre2/drivers/usb/misc/isight_firmware.c	2012-01-07 10:27:25.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/misc/isight_firmware.c	2012-01-12 17:24:25.000000000 -0500
@@ -54,8 +54,9 @@
 
 	ptr = firmware->data;
 
+	buf[0] = 0x01;
 	if (usb_control_msg
-	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
 	     300) != 1) {
 		printk(KERN_ERR
 		       "Failed to initialise isight firmware loader\n");
@@ -99,8 +100,9 @@
 		}
 	}
 
+	buf[0] = 0x00;
 	if (usb_control_msg
-	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
 	     300) != 1) {
 		printk(KERN_ERR "isight firmware loading completion failed\n");
 		ret = -ENODEV;
diff -druN linux-2.6.32.53-libre2/drivers/usb/serial/cp210x.c linux-2.6.32.54-libre2/drivers/usb/serial/cp210x.c
--- linux-2.6.32.53-libre2/drivers/usb/serial/cp210x.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/serial/cp210x.c	2012-01-12 14:53:50.000000000 -0500
@@ -94,6 +94,7 @@
 	{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
 	{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
 	{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
+	{ USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
 	{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
 	{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
diff -druN linux-2.6.32.53-libre2/drivers/usb/serial/omninet.c linux-2.6.32.54-libre2/drivers/usb/serial/omninet.c
--- linux-2.6.32.53-libre2/drivers/usb/serial/omninet.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/serial/omninet.c	2012-01-12 14:53:50.000000000 -0500
@@ -317,7 +317,7 @@
 	int room = 0; /* Default: no room */
 
 	/* FIXME: no consistent locking for write_urb_busy */
-	if (wport->write_urb_busy)
+	if (!wport->write_urb_busy)
 		room = wport->bulk_out_size - OMNINET_HEADERLEN;
 
 	dbg("%s - returns %d", __func__, room);
diff -druN linux-2.6.32.53-libre2/drivers/usb/storage/usb.c linux-2.6.32.54-libre2/drivers/usb/storage/usb.c
--- linux-2.6.32.53-libre2/drivers/usb/storage/usb.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/usb/storage/usb.c	2012-01-12 14:53:50.000000000 -0500
@@ -1025,6 +1025,7 @@
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	usb_storage_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 static int __init usb_stor_init(void)
diff -druN linux-2.6.32.53-libre2/drivers/video/offb.c linux-2.6.32.54-libre2/drivers/video/offb.c
--- linux-2.6.32.53-libre2/drivers/video/offb.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/drivers/video/offb.c	2012-01-12 14:53:50.000000000 -0500
@@ -100,36 +100,32 @@
 			  u_int transp, struct fb_info *info)
 {
 	struct offb_par *par = (struct offb_par *) info->par;
-	int i, depth;
-	u32 *pal = info->pseudo_palette;
 
-	depth = info->var.bits_per_pixel;
-	if (depth == 16)
-		depth = (info->var.green.length == 5) ? 15 : 16;
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+		u32 *pal = info->pseudo_palette;
+		u32 cr = red >> (16 - info->var.red.length);
+		u32 cg = green >> (16 - info->var.green.length);
+		u32 cb = blue >> (16 - info->var.blue.length);
+		u32 value;
 
-	if (regno > 255 ||
-	    (depth == 16 && regno > 63) ||
-	    (depth == 15 && regno > 31))
-		return 1;
+		if (regno >= 16)
+			return -EINVAL;
 
-	if (regno < 16) {
-		switch (depth) {
-		case 15:
-			pal[regno] = (regno << 10) | (regno << 5) | regno;
-			break;
-		case 16:
-			pal[regno] = (regno << 11) | (regno << 5) | regno;
-			break;
-		case 24:
-			pal[regno] = (regno << 16) | (regno << 8) | regno;
-			break;
-		case 32:
-			i = (regno << 8) | regno;
-			pal[regno] = (i << 16) | i;
-			break;
+		value = (cr << info->var.red.offset) |
+			(cg << info->var.green.offset) |
+			(cb << info->var.blue.offset);
+		if (info->var.transp.length > 0) {
+			u32 mask = (1 << info->var.transp.length) - 1;
+			mask <<= info->var.transp.offset;
+			value |= mask;
 		}
+		pal[regno] = value;
+		return 0;
 	}
 
+	if (regno > 255)
+		return -EINVAL;
+
 	red >>= 8;
 	green >>= 8;
 	blue >>= 8;
@@ -381,7 +377,7 @@
 				int pitch, unsigned long address,
 				int foreign_endian, struct device_node *dp)
 {
-	unsigned long res_size = pitch * height * (depth + 7) / 8;
+	unsigned long res_size = pitch * height;
 	struct offb_par *par = &default_par;
 	unsigned long res_start = address;
 	struct fb_fix_screeninfo *fix;
diff -druN linux-2.6.32.53-libre2/fs/reiserfs/super.c linux-2.6.32.54-libre2/fs/reiserfs/super.c
--- linux-2.6.32.53-libre2/fs/reiserfs/super.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/fs/reiserfs/super.c	2012-01-12 14:53:50.000000000 -0500
@@ -445,16 +445,20 @@
 static void reiserfs_kill_sb(struct super_block *s)
 {
 	if (REISERFS_SB(s)) {
-		if (REISERFS_SB(s)->xattr_root) {
-			d_invalidate(REISERFS_SB(s)->xattr_root);
-			dput(REISERFS_SB(s)->xattr_root);
-			REISERFS_SB(s)->xattr_root = NULL;
-		}
-		if (REISERFS_SB(s)->priv_root) {
-			d_invalidate(REISERFS_SB(s)->priv_root);
-			dput(REISERFS_SB(s)->priv_root);
-			REISERFS_SB(s)->priv_root = NULL;
-		}
+		/*
+		 * Force any pending inode evictions to occur now. Any
+		 * inodes to be removed that have extended attributes
+		 * associated with them need to clean them up before
+		 * we can release the extended attribute root dentries.
+		 * shrink_dcache_for_umount will BUG if we don't release
+		 * those before it's called so ->put_super is too late.
+		 */
+		shrink_dcache_sb(s);
+
+		dput(REISERFS_SB(s)->xattr_root);
+		REISERFS_SB(s)->xattr_root = NULL;
+		dput(REISERFS_SB(s)->priv_root);
+		REISERFS_SB(s)->priv_root = NULL;
 	}
 
 	kill_block_super(s);
@@ -1149,7 +1153,8 @@
 			kfree(REISERFS_SB(s)->s_qf_names[i]);
 		REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
 	}
-	REISERFS_SB(s)->s_jquota_fmt = *qfmt;
+	if (*qfmt)
+		REISERFS_SB(s)->s_jquota_fmt = *qfmt;
 }
 #endif
 
diff -druN linux-2.6.32.53-libre2/fs/xfs/linux-2.6/xfs_acl.c linux-2.6.32.54-libre2/fs/xfs/linux-2.6/xfs_acl.c
--- linux-2.6.32.53-libre2/fs/xfs/linux-2.6/xfs_acl.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/fs/xfs/linux-2.6/xfs_acl.c	2012-01-12 14:53:50.000000000 -0500
@@ -37,9 +37,11 @@
 	struct posix_acl_entry *acl_e;
 	struct posix_acl *acl;
 	struct xfs_acl_entry *ace;
-	int count, i;
+	unsigned int count, i;
 
 	count = be32_to_cpu(aclp->acl_cnt);
+	if (count > XFS_ACL_MAX_ENTRIES)
+		return ERR_PTR(-EFSCORRUPTED);
 
 	acl = posix_acl_alloc(count, GFP_KERNEL);
 	if (!acl)
diff -druN linux-2.6.32.53-libre2/kernel/cpu.c linux-2.6.32.54-libre2/kernel/cpu.c
--- linux-2.6.32.53-libre2/kernel/cpu.c	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/kernel/cpu.c	2012-01-12 14:53:50.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/kthread.h>
 #include <linux/stop_machine.h>
 #include <linux/mutex.h>
+#include <linux/suspend.h>
 
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -442,6 +443,79 @@
 	return 0;
 }
 core_initcall(alloc_frozen_cpus);
+
+/*
+ * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
+ * hotplug when tasks are about to be frozen. Also, don't allow the freezer
+ * to continue until any currently running CPU hotplug operation gets
+ * completed.
+ * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
+ * 'cpu_add_remove_lock'. And this same lock is also taken by the regular
+ * CPU hotplug path and released only after it is complete. Thus, we
+ * (and hence the freezer) will block here until any currently running CPU
+ * hotplug operation gets completed.
+ */
+void cpu_hotplug_disable_before_freeze(void)
+{
+	cpu_maps_update_begin();
+	cpu_hotplug_disabled = 1;
+	cpu_maps_update_done();
+}
+
+
+/*
+ * When tasks have been thawed, re-enable regular CPU hotplug (which had been
+ * disabled while beginning to freeze tasks).
+ */
+void cpu_hotplug_enable_after_thaw(void)
+{
+	cpu_maps_update_begin();
+	cpu_hotplug_disabled = 0;
+	cpu_maps_update_done();
+}
+
+/*
+ * When callbacks for CPU hotplug notifications are being executed, we must
+ * ensure that the state of the system with respect to the tasks being frozen
+ * or not, as reported by the notification, remains unchanged *throughout the
+ * duration* of the execution of the callbacks.
+ * Hence we need to prevent the freezer from racing with regular CPU hotplug.
+ *
+ * This synchronization is implemented by mutually excluding regular CPU
+ * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
+ * Hibernate notifications.
+ */
+static int
+cpu_hotplug_pm_callback(struct notifier_block *nb,
+			unsigned long action, void *ptr)
+{
+	switch (action) {
+
+	case PM_SUSPEND_PREPARE:
+	case PM_HIBERNATION_PREPARE:
+		cpu_hotplug_disable_before_freeze();
+		break;
+
+	case PM_POST_SUSPEND:
+	case PM_POST_HIBERNATION:
+		cpu_hotplug_enable_after_thaw();
+		break;
+
+	default:
+		return NOTIFY_DONE;
+	}
+
+	return NOTIFY_OK;
+}
+
+
+int cpu_hotplug_pm_sync_init(void)
+{
+	pm_notifier(cpu_hotplug_pm_callback, 0);
+	return 0;
+}
+core_initcall(cpu_hotplug_pm_sync_init);
+
 #endif /* CONFIG_PM_SLEEP_SMP */
 
 /**
diff -druN linux-2.6.32.53-libre2/MAINTAINERS linux-2.6.32.54-libre2/MAINTAINERS
--- linux-2.6.32.53-libre2/MAINTAINERS	2012-01-06 18:39:52.000000000 -0500
+++ linux-2.6.32.54-libre2/MAINTAINERS	2012-01-12 14:53:50.000000000 -0500
@@ -5010,7 +5010,7 @@
 
 STABLE BRANCH
 M:	Greg Kroah-Hartman <greg@kroah.com>
-L:	stable@kernel.org
+L:	stable@vger.kernel.org
 S:	Maintained
 
 STAGING SUBSYSTEM
diff -druN linux-2.6.32.53-libre2/Makefile linux-2.6.32.54-libre2/Makefile
--- linux-2.6.32.53-libre2/Makefile	2012-01-07 09:59:48.000000000 -0500
+++ linux-2.6.32.54-libre2/Makefile	2012-01-12 17:04:46.000000000 -0500
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 32
-EXTRAVERSION = .53-libre2
+EXTRAVERSION = .54-libre2
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
