diff -druNp linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head.S linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head.S
--- linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head.S	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head.S	2013-06-18 21:17:03.000000000 -0400
@@ -10,6 +10,7 @@
  */
 #include <linux/linkage.h>
 
+	.arch	armv7-a
 /*
  * Debugging stuff
  *
diff -druNp linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head-sa1100.S linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head-sa1100.S
--- linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head-sa1100.S	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head-sa1100.S	2013-06-18 21:17:03.000000000 -0400
@@ -11,6 +11,7 @@
 #include <asm/mach-types.h>
 
 		.section        ".start", "ax"
+		.arch	armv4
 
 __SA1100_start:
 
diff -druNp linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head-shark.S linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head-shark.S
--- linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/head-shark.S	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/head-shark.S	2013-06-18 21:17:03.000000000 -0400
@@ -18,6 +18,7 @@
 	
 		.section	".start", "ax"
 
+		.arch armv4
 		b	__beginning
 	
 __ofw_data:	.long	0				@ the number of memory blocks
diff -druNp linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/Makefile linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/Makefile
--- linux-libre-3.2.46-gnu1/arch/arm/boot/compressed/Makefile	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/arm/boot/compressed/Makefile	2013-06-18 21:17:03.000000000 -0400
@@ -123,7 +123,6 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CF
 endif
 
 ccflags-y := -fpic -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
diff -druNp linux-libre-3.2.46-gnu1/arch/arm/kernel/topology.c linux-libre-3.2.47-gnu1/arch/arm/kernel/topology.c
--- linux-libre-3.2.46-gnu1/arch/arm/kernel/topology.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/arm/kernel/topology.c	2013-06-18 21:17:03.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/node.h>
@@ -42,6 +43,7 @@
 #define MPIDR_LEVEL2_SHIFT 16
 
 struct cputopo_arm cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
 
 const struct cpumask *cpu_coregroup_mask(int cpu)
 {
diff -druNp linux-libre-3.2.46-gnu1/arch/powerpc/kernel/exceptions-64s.S linux-libre-3.2.47-gnu1/arch/powerpc/kernel/exceptions-64s.S
--- linux-libre-3.2.46-gnu1/arch/powerpc/kernel/exceptions-64s.S	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/powerpc/kernel/exceptions-64s.S	2013-06-18 21:17:03.000000000 -0400
@@ -463,7 +463,7 @@ machine_check_common:
 	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
 	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
 	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-        STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
+	STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
         STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 	STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
diff -druNp linux-libre-3.2.46-gnu1/arch/powerpc/kernel/traps.c linux-libre-3.2.47-gnu1/arch/powerpc/kernel/traps.c
--- linux-libre-3.2.46-gnu1/arch/powerpc/kernel/traps.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/powerpc/kernel/traps.c	2013-06-18 21:17:03.000000000 -0400
@@ -1036,6 +1036,16 @@ void __kprobes program_check_exception(s
 		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
 }
 
+/*
+ * This occurs when running in hypervisor mode on POWER6 or later
+ * and an illegal instruction is encountered.
+ */
+void __kprobes emulation_assist_interrupt(struct pt_regs *regs)
+{
+	regs->msr |= REASON_ILLEGAL;
+	program_check_exception(regs);
+}
+
 void alignment_exception(struct pt_regs *regs)
 {
 	int sig, code, fixed = 0;
diff -druNp linux-libre-3.2.46-gnu1/arch/x86/kernel/relocate_kernel_64.S linux-libre-3.2.47-gnu1/arch/x86/kernel/relocate_kernel_64.S
--- linux-libre-3.2.46-gnu1/arch/x86/kernel/relocate_kernel_64.S	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/arch/x86/kernel/relocate_kernel_64.S	2013-06-18 21:17:03.000000000 -0400
@@ -160,7 +160,7 @@ identity_mapped:
 	xorq    %rbp, %rbp
 	xorq	%r8,  %r8
 	xorq	%r9,  %r9
-	xorq	%r10, %r9
+	xorq	%r10, %r10
 	xorq	%r11, %r11
 	xorq	%r12, %r12
 	xorq	%r13, %r13
diff -druNp linux-libre-3.2.46-gnu1/drivers/acpi/video.c linux-libre-3.2.47-gnu1/drivers/acpi/video.c
--- linux-libre-3.2.46-gnu1/drivers/acpi/video.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/acpi/video.c	2013-06-18 21:17:03.000000000 -0400
@@ -447,6 +447,38 @@ static struct dmi_system_id video_dmi_ta
 		DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"),
 		},
 	},
+	{
+	 .callback = video_ignore_initial_backlight,
+	 .ident = "HP Pavilion dm4",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
+		},
+	},
+	{
+	 .callback = video_ignore_initial_backlight,
+	 .ident = "HP Pavilion g6 Notebook PC",
+	 .matches = {
+		 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+		 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"),
+		},
+	},
+	{
+	 .callback = video_ignore_initial_backlight,
+	 .ident = "HP 1000 Notebook PC",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"),
+		},
+	},
+	{
+	 .callback = video_ignore_initial_backlight,
+	 .ident = "HP Pavilion m4",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"),
+		},
+	},
 	{}
 };
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/ata/ata_piix.c linux-libre-3.2.47-gnu1/drivers/ata/ata_piix.c
--- linux-libre-3.2.46-gnu1/drivers/ata/ata_piix.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/ata/ata_piix.c	2013-06-18 21:17:03.000000000 -0400
@@ -151,6 +151,7 @@ enum piix_controller_ids {
 	piix_pata_vmw,			/* PIIX4 for VMware, spurious DMA_ERR */
 	ich8_sata_snb,
 	ich8_2port_sata_snb,
+	ich8_2port_sata_byt,
 };
 
 struct piix_map_db {
@@ -356,6 +357,9 @@ static const struct pci_device_id piix_p
 	{ 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
 	/* SATA Controller IDE (Wellsburg) */
 	{ 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (BayTrail) */
+	{ 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
+	{ 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
 
 	{ }	/* terminate list */
 };
@@ -521,6 +525,7 @@ static const struct piix_map_db *piix_ma
 	[tolapai_sata]		= &tolapai_map_db,
 	[ich8_sata_snb]		= &ich8_map_db,
 	[ich8_2port_sata_snb]	= &ich8_2port_map_db,
+	[ich8_2port_sata_byt]	= &ich8_2port_map_db,
 };
 
 static struct ata_port_info piix_port_info[] = {
@@ -672,6 +677,15 @@ static struct ata_port_info piix_port_in
 		.port_ops	= &piix_sata_ops,
 	},
 
+	[ich8_2port_sata_byt] =
+	{
+		.flags          = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16,
+		.pio_mask       = ATA_PIO4,
+		.mwdma_mask     = ATA_MWDMA2,
+		.udma_mask      = ATA_UDMA6,
+		.port_ops       = &piix_sata_ops,
+	},
+
 };
 
 static struct pci_bits piix_enable_bits[] = {
diff -druNp linux-libre-3.2.46-gnu1/drivers/ata/libata-core.c linux-libre-3.2.47-gnu1/drivers/ata/libata-core.c
--- linux-libre-3.2.46-gnu1/drivers/ata/libata-core.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/ata/libata-core.c	2013-06-18 21:17:03.000000000 -0400
@@ -1598,6 +1598,12 @@ unsigned ata_exec_internal_sg(struct ata
 	qc->tf = *tf;
 	if (cdb)
 		memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+
+	/* some SATA bridges need us to indicate data xfer direction */
+	if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) &&
+	    dma_dir == DMA_FROM_DEVICE)
+		qc->tf.feature |= ATAPI_DMADIR;
+
 	qc->flags |= ATA_QCFLAG_RESULT_TF;
 	qc->dma_dir = dma_dir;
 	if (dma_dir != DMA_NONE) {
diff -druNp linux-libre-3.2.46-gnu1/drivers/block/cciss.c linux-libre-3.2.47-gnu1/drivers/block/cciss.c
--- linux-libre-3.2.46-gnu1/drivers/block/cciss.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/block/cciss.c	2013-06-18 21:17:03.000000000 -0400
@@ -161,8 +161,6 @@ static irqreturn_t do_cciss_msix_intr(in
 static int cciss_open(struct block_device *bdev, fmode_t mode);
 static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode);
 static int cciss_release(struct gendisk *disk, fmode_t mode);
-static int do_ioctl(struct block_device *bdev, fmode_t mode,
-		    unsigned int cmd, unsigned long arg);
 static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
 		       unsigned int cmd, unsigned long arg);
 static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
@@ -229,7 +227,7 @@ static const struct block_device_operati
 	.owner = THIS_MODULE,
 	.open = cciss_unlocked_open,
 	.release = cciss_release,
-	.ioctl = do_ioctl,
+	.ioctl = cciss_ioctl,
 	.getgeo = cciss_getgeo,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = cciss_compat_ioctl,
@@ -1140,16 +1138,6 @@ static int cciss_release(struct gendisk
 	return 0;
 }
 
-static int do_ioctl(struct block_device *bdev, fmode_t mode,
-		    unsigned cmd, unsigned long arg)
-{
-	int ret;
-	mutex_lock(&cciss_mutex);
-	ret = cciss_ioctl(bdev, mode, cmd, arg);
-	mutex_unlock(&cciss_mutex);
-	return ret;
-}
-
 #ifdef CONFIG_COMPAT
 
 static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
@@ -1176,7 +1164,7 @@ static int cciss_compat_ioctl(struct blo
 	case CCISS_REGNEWD:
 	case CCISS_RESCANDISK:
 	case CCISS_GETLUNINFO:
-		return do_ioctl(bdev, mode, cmd, arg);
+		return cciss_ioctl(bdev, mode, cmd, arg);
 
 	case CCISS_PASSTHRU32:
 		return cciss_ioctl32_passthru(bdev, mode, cmd, arg);
@@ -1216,7 +1204,7 @@ static int cciss_ioctl32_passthru(struct
 	if (err)
 		return -EFAULT;
 
-	err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
+	err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
 	if (err)
 		return err;
 	err |=
@@ -1258,7 +1246,7 @@ static int cciss_ioctl32_big_passthru(st
 	if (err)
 		return -EFAULT;
 
-	err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
+	err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
 	if (err)
 		return err;
 	err |=
@@ -1308,11 +1296,14 @@ static int cciss_getpciinfo(ctlr_info_t
 static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
 {
 	cciss_coalint_struct intinfo;
+	unsigned long flags;
 
 	if (!argp)
 		return -EINVAL;
+	spin_lock_irqsave(&h->lock, flags);
 	intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
 	intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+	spin_unlock_irqrestore(&h->lock, flags);
 	if (copy_to_user
 	    (argp, &intinfo, sizeof(cciss_coalint_struct)))
 		return -EFAULT;
@@ -1353,12 +1344,15 @@ static int cciss_setintinfo(ctlr_info_t
 static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
 {
 	NodeName_type NodeName;
+	unsigned long flags;
 	int i;
 
 	if (!argp)
 		return -EINVAL;
+	spin_lock_irqsave(&h->lock, flags);
 	for (i = 0; i < 16; i++)
 		NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+	spin_unlock_irqrestore(&h->lock, flags);
 	if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
 		return -EFAULT;
 	return 0;
@@ -1395,10 +1389,13 @@ static int cciss_setnodename(ctlr_info_t
 static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
 {
 	Heartbeat_type heartbeat;
+	unsigned long flags;
 
 	if (!argp)
 		return -EINVAL;
+	spin_lock_irqsave(&h->lock, flags);
 	heartbeat = readl(&h->cfgtable->HeartBeat);
+	spin_unlock_irqrestore(&h->lock, flags);
 	if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
 		return -EFAULT;
 	return 0;
@@ -1407,10 +1404,13 @@ static int cciss_getheartbeat(ctlr_info_
 static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
 {
 	BusTypes_type BusTypes;
+	unsigned long flags;
 
 	if (!argp)
 		return -EINVAL;
+	spin_lock_irqsave(&h->lock, flags);
 	BusTypes = readl(&h->cfgtable->BusTypes);
+	spin_unlock_irqrestore(&h->lock, flags);
 	if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
 		return -EFAULT;
 	return 0;
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/drm_irq.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/drm_irq.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/drm_irq.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/drm_irq.c	2013-06-18 21:17:03.000000000 -0400
@@ -981,7 +981,7 @@ EXPORT_SYMBOL(drm_vblank_off);
  */
 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
 {
-	/* vblank is not initialized (IRQ not installed ?) */
+	/* vblank is not initialized (IRQ not installed ?), or has been freed */
 	if (!dev->num_crtcs)
 		return;
 	/*
@@ -1003,6 +1003,10 @@ void drm_vblank_post_modeset(struct drm_
 {
 	unsigned long irqflags;
 
+	/* vblank is not initialized (IRQ not installed ?), or has been freed */
+	if (!dev->num_crtcs)
+		return;
+
 	if (dev->vblank_inmodeset[crtc]) {
 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
 		dev->vblank_disable_allowed = 1;
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/i915/intel_lvds.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2013-06-18 21:17:03.000000000 -0400
@@ -740,10 +740,10 @@ static const struct dmi_system_id intel_
 	},
 	{
 		.callback = intel_no_lvds_dmi_callback,
-		.ident = "Hewlett-Packard HP t5740e Thin Client",
+		.ident = "Hewlett-Packard HP t5740",
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"),
+			DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
 		},
 	},
 	{
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/i915/intel_sdvo.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2013-06-18 21:17:03.000000000 -0400
@@ -1582,11 +1582,14 @@ static void intel_sdvo_get_lvds_modes(st
 	 * Assume that the preferred modes are
 	 * arranged in priority order.
 	 */
-	intel_ddc_get_modes(connector, intel_sdvo->i2c);
-	if (list_empty(&connector->probed_modes) == false)
-		goto end;
+	intel_ddc_get_modes(connector, &intel_sdvo->ddc);
 
-	/* Fetch modes from VBT */
+	/*
+	 * Fetch modes from VBT. For SDVO prefer the VBT mode since some
+	 * SDVO->LVDS transcoders can't cope with the EDID mode. Since
+	 * drm_mode_probed_add adds the mode at the head of the list we add it
+	 * last.
+	 */
 	if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
 		newmode = drm_mode_duplicate(connector->dev,
 					     dev_priv->sdvo_lvds_vbt_mode);
@@ -1598,7 +1601,6 @@ static void intel_sdvo_get_lvds_modes(st
 		}
 	}
 
-end:
 	list_for_each_entry(newmode, &connector->probed_modes, head) {
 		if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
 			intel_sdvo->sdvo_lvds_fixed_mode =
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/evergreen.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/evergreen.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/evergreen.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/evergreen.c	2013-06-18 21:17:03.000000000 -0400
@@ -3086,6 +3086,12 @@ static int evergreen_startup(struct rade
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r = r600_irq_init(rdev);
 	if (r) {
 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -3218,10 +3224,6 @@ int evergreen_init(struct radeon_device
 	if (r)
 		return r;
 
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
-
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/ni.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/ni.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/ni.c	2013-05-31 10:18:24.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/ni.c	2013-06-19 00:36:38.000000000 -0400
@@ -1348,6 +1348,12 @@ static int cayman_startup(struct radeon_
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r = r600_irq_init(rdev);
 	if (r) {
 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -1465,10 +1471,6 @@ int cayman_init(struct radeon_device *rd
 	if (r)
 		return r;
 
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
-
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r100.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r100.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r100.c	2013-05-31 10:18:15.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r100.c	2013-06-19 00:36:29.000000000 -0400
@@ -3899,6 +3899,12 @@ static int r100_startup(struct radeon_de
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r100_irq_set(rdev);
 	rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -4044,9 +4050,6 @@ int r100_init(struct radeon_device *rdev
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r300.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r300.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r300.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r300.c	2013-06-18 21:17:03.000000000 -0400
@@ -1397,6 +1397,12 @@ static int r300_startup(struct radeon_de
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r100_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -1521,9 +1527,6 @@ int r300_init(struct radeon_device *rdev
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r420.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r420.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r420.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r420.c	2013-06-18 21:17:03.000000000 -0400
@@ -255,6 +255,12 @@ static int r420_startup(struct radeon_de
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r100_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -391,10 +397,6 @@ int r420_init(struct radeon_device *rdev
 	if (r) {
 		return r;
 	}
-	r = radeon_irq_kms_init(rdev);
-	if (r) {
-		return r;
-	}
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r) {
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r520.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r520.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r520.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r520.c	2013-06-18 21:17:03.000000000 -0400
@@ -188,6 +188,12 @@ static int r520_startup(struct radeon_de
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	rs600_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -281,9 +287,6 @@ int r520_init(struct radeon_device *rdev
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r600.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r600.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/r600.c	2013-05-31 10:18:19.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/r600.c	2013-06-19 00:36:33.000000000 -0400
@@ -2409,6 +2409,12 @@ int r600_startup(struct radeon_device *r
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r = r600_irq_init(rdev);
 	if (r) {
 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -2552,10 +2558,6 @@ int r600_init(struct radeon_device *rdev
 	if (r)
 		return r;
 
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
-
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/radeon_device.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2013-06-18 21:17:03.000000000 -0400
@@ -359,18 +359,17 @@ bool radeon_card_posted(struct radeon_de
 		return false;
 
 	/* first check CRTCs */
-	if (ASIC_IS_DCE41(rdev)) {
+	if (ASIC_IS_DCE4(rdev)) {
 		reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
 			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
-		if (reg & EVERGREEN_CRTC_MASTER_EN)
-			return true;
-	} else if (ASIC_IS_DCE4(rdev)) {
-		reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
-			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
-			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
-			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
-			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
-			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+			if (rdev->num_crtc >= 4) {
+				reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
+					RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+			}
+			if (rdev->num_crtc >= 6) {
+				reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
+					RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+			}
 		if (reg & EVERGREEN_CRTC_MASTER_EN)
 			return true;
 	} else if (ASIC_IS_AVIVO(rdev)) {
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs400.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs400.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs400.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs400.c	2013-06-18 21:17:03.000000000 -0400
@@ -411,6 +411,12 @@ static int rs400_startup(struct radeon_d
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r100_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -519,9 +525,6 @@ int rs400_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs600.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs600.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs600.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs600.c	2013-06-18 21:17:03.000000000 -0400
@@ -848,6 +848,12 @@ static int rs600_startup(struct radeon_d
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	rs600_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -963,9 +969,6 @@ int rs600_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs690.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs690.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rs690.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rs690.c	2013-06-18 21:17:03.000000000 -0400
@@ -622,6 +622,12 @@ static int rs690_startup(struct radeon_d
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	rs600_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -738,9 +744,6 @@ int rs690_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rv515.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rv515.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rv515.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rv515.c	2013-06-18 21:17:03.000000000 -0400
@@ -380,6 +380,12 @@ static int rv515_startup(struct radeon_d
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	rs600_irq_set(rdev);
 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
@@ -500,9 +506,6 @@ int rv515_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
 	/* Memory manager */
 	r = radeon_bo_init(rdev);
 	if (r)
diff -druNp linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rv770.c linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rv770.c
--- linux-libre-3.2.46-gnu1/drivers/gpu/drm/radeon/rv770.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/gpu/drm/radeon/rv770.c	2013-06-18 21:17:03.000000000 -0400
@@ -1092,6 +1092,12 @@ static int rv770_startup(struct radeon_d
 		return r;
 
 	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
 	r = r600_irq_init(rdev);
 	if (r) {
 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -1220,10 +1226,6 @@ int rv770_init(struct radeon_device *rde
 	if (r)
 		return r;
 
-	r = radeon_irq_kms_init(rdev);
-	if (r)
-		return r;
-
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/hwmon/adm1021.c linux-libre-3.2.47-gnu1/drivers/hwmon/adm1021.c
--- linux-libre-3.2.46-gnu1/drivers/hwmon/adm1021.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/hwmon/adm1021.c	2013-06-18 21:17:03.000000000 -0400
@@ -311,26 +311,68 @@ static int adm1021_detect(struct i2c_cli
 	man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
 	dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
 
+	if (man_id < 0 || dev_id < 0)
+		return -ENODEV;
+
 	if (man_id == 0x4d && dev_id == 0x01)
 		type_name = "max1617a";
 	else if (man_id == 0x41) {
 		if ((dev_id & 0xF0) == 0x30)
 			type_name = "adm1023";
-		else
+		else if ((dev_id & 0xF0) == 0x00)
 			type_name = "adm1021";
+		else
+			return -ENODEV;
 	} else if (man_id == 0x49)
 		type_name = "thmc10";
 	else if (man_id == 0x23)
 		type_name = "gl523sm";
 	else if (man_id == 0x54)
 		type_name = "mc1066";
-	/* LM84 Mfr ID in a different place, and it has more unused bits */
-	else if (conv_rate == 0x00
-		 && (config & 0x7F) == 0x00
-		 && (status & 0xAB) == 0x00)
-		type_name = "lm84";
-	else
-		type_name = "max1617";
+	else {
+		int lte, rte, lhi, rhi, llo, rlo;
+
+		/* extra checks for LM84 and MAX1617 to avoid misdetections */
+
+		llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0));
+		rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1));
+
+		/* fail if any of the additional register reads failed */
+		if (llo < 0 || rlo < 0)
+			return -ENODEV;
+
+		lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0));
+		rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1));
+		lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0));
+		rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1));
+
+		/*
+		 * Fail for negative temperatures and negative high limits.
+		 * This check also catches read errors on the tested registers.
+		 */
+		if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0)
+			return -ENODEV;
+
+		/* fail if all registers hold the same value */
+		if (lte == rte && lte == lhi && lte == rhi && lte == llo
+		    && lte == rlo)
+			return -ENODEV;
+
+		/*
+		 * LM84 Mfr ID is in a different place,
+		 * and it has more unused bits.
+		 */
+		if (conv_rate == 0x00
+		    && (config & 0x7F) == 0x00
+		    && (status & 0xAB) == 0x00) {
+			type_name = "lm84";
+		} else {
+			/* fail if low limits are larger than high limits */
+			if ((s8)llo > lhi || (s8)rlo > rhi)
+				return -ENODEV;
+			type_name = "max1617";
+		}
+	}
 
 	pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
 		 type_name, i2c_adapter_id(adapter), client->addr);
diff -druNp linux-libre-3.2.46-gnu1/drivers/md/raid10.c linux-libre-3.2.47-gnu1/drivers/md/raid10.c
--- linux-libre-3.2.46-gnu1/drivers/md/raid10.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/md/raid10.c	2013-06-18 21:17:03.000000000 -0400
@@ -390,7 +390,17 @@ static void raid10_end_write_request(str
 		sector_t first_bad;
 		int bad_sectors;
 
-		set_bit(R10BIO_Uptodate, &r10_bio->state);
+		/*
+		 * Do not set R10BIO_Uptodate if the current device is
+		 * rebuilding or Faulty. This is because we cannot use
+		 * such device for properly reading the data back (we could
+		 * potentially use it, if the current write would have felt
+		 * before rdev->recovery_offset, but for simplicity we don't
+		 * check this here.
+		 */
+		if (test_bit(In_sync, &conf->mirrors[dev].rdev->flags) &&
+		    !test_bit(Faulty, &conf->mirrors[dev].rdev->flags))
+			set_bit(R10BIO_Uptodate, &r10_bio->state);
 
 		/* Maybe we can clear some bad blocks. */
 		if (is_badblock(conf->mirrors[dev].rdev,
diff -druNp linux-libre-3.2.46-gnu1/drivers/md/raid1.c linux-libre-3.2.47-gnu1/drivers/md/raid1.c
--- linux-libre-3.2.46-gnu1/drivers/md/raid1.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/md/raid1.c	2013-06-18 21:17:03.000000000 -0400
@@ -407,7 +407,17 @@ static void raid1_end_write_request(stru
 
 		r1_bio->bios[mirror] = NULL;
 		to_put = bio;
-		set_bit(R1BIO_Uptodate, &r1_bio->state);
+		/*
+		 * Do not set R1BIO_Uptodate if the current device is
+		 * rebuilding or Faulty. This is because we cannot use
+		 * such device for properly reading the data back (we could
+		 * potentially use it, if the current write would have felt
+		 * before rdev->recovery_offset, but for simplicity we don't
+		 * check this here.
+		 */
+		if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) &&
+		    !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags))
+			set_bit(R1BIO_Uptodate, &r1_bio->state);
 
 		/* Maybe we can clear some bad blocks. */
 		if (is_badblock(conf->mirrors[mirror].rdev,
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/ethernet/broadcom/tg3.c linux-libre-3.2.47-gnu1/drivers/net/ethernet/broadcom/tg3.c
--- linux-libre-3.2.46-gnu1/drivers/net/ethernet/broadcom/tg3.c	2013-05-31 10:22:40.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/ethernet/broadcom/tg3.c	2013-06-19 00:40:54.000000000 -0400
@@ -1611,6 +1611,9 @@ static int tg3_poll_fw(struct tg3 *tp)
 	int i;
 	u32 val;
 
+	if (tg3_flag(tp, NO_FWARE_REPORTED))
+		return 0;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		/* Wait up to 20ms for init done. */
 		for (i = 0; i < 200; i++) {
@@ -8273,6 +8276,14 @@ static void tg3_setup_rxbd_thresholds(st
 		tw32(JMB_REPLENISH_LWM, bdcache_maxcnt);
 }
 
+static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp)
+{
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+		return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719;
+	else
+		return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720;
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
@@ -8911,6 +8922,20 @@ static int tg3_reset_hw(struct tg3 *tp,
 	tw32_f(RDMAC_MODE, rdmac_mode);
 	udelay(40);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+		for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) {
+			if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp))
+				break;
+		}
+		if (i < TG3_NUM_RDMA_CHANNELS) {
+			val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
+			val |= tg3_lso_rd_dma_workaround_bit(tp);
+			tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
+			tg3_flag_set(tp, 5719_5720_RDMA_BUG);
+		}
+	}
+
 	tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
 	if (!tg3_flag(tp, 5705_PLUS))
 		tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
@@ -9157,6 +9182,13 @@ static int tg3_reset_hw(struct tg3 *tp,
  */
 static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 {
+	/* Chip may have been just powered on. If so, the boot code may still
+	 * be running initialization. Wait for it to finish to avoid races in
+	 * accessing the hardware.
+	 */
+	tg3_enable_register_access(tp);
+	tg3_poll_fw(tp);
+
 	tg3_switch_clocks(tp);
 
 	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
@@ -9191,6 +9223,16 @@ static void tg3_periodic_fetch_stats(str
 	TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST);
 	TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST);
 	TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST);
+	if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) &&
+		     (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low +
+		      sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) {
+		u32 val;
+
+		val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
+		val &= ~tg3_lso_rd_dma_workaround_bit(tp);
+		tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
+		tg3_flag_clear(tp, 5719_5720_RDMA_BUG);
+	}
 
 	TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS);
 	TG3_STAT_ADD32(&sp->rx_fragments, MAC_RX_STATS_FRAGMENTS);
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/ethernet/broadcom/tg3.h linux-libre-3.2.47-gnu1/drivers/net/ethernet/broadcom/tg3.h
--- linux-libre-3.2.46-gnu1/drivers/net/ethernet/broadcom/tg3.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/ethernet/broadcom/tg3.h	2013-06-18 21:17:03.000000000 -0400
@@ -1368,7 +1368,12 @@
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL	0x00004910
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K	 0x00030000
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K	 0x000c0000
-/* 0x4914 --> 0x4c00 unused */
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719	 0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720	 0x00200000
+/* 0x4914 --> 0x4be0 unused */
+
+#define TG3_NUM_RDMA_CHANNELS		4
+#define TG3_RDMA_LENGTH			0x00004be0
 
 /* Write DMA control registers */
 #define WDMAC_MODE			0x00004c00
@@ -2921,6 +2926,7 @@ enum TG3_FLAGS {
 	TG3_FLAG_APE_HAS_NCSI,
 	TG3_FLAG_5717_PLUS,
 	TG3_FLAG_4K_FIFO_LIMIT,
+	TG3_FLAG_5719_5720_RDMA_BUG,
 	TG3_FLAG_RESET_TASK_PENDING,
 
 	/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/init.c linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/init.c
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/init.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/init.c	2013-06-18 21:17:03.000000000 -0400
@@ -691,8 +691,7 @@ void ath9k_set_hw_capab(struct ath_softc
 		BIT(NL80211_IFTYPE_ADHOC) |
 		BIT(NL80211_IFTYPE_MESH_POINT);
 
-	if (AR_SREV_5416(sc->sc_ah))
-		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
@@ -714,10 +713,6 @@ void ath9k_set_hw_capab(struct ath_softc
 	sc->ant_rx = hw->wiphy->available_antennas_rx;
 	sc->ant_tx = hw->wiphy->available_antennas_tx;
 
-#ifdef CONFIG_ATH9K_RATE_CONTROL
-	hw->rate_control_algorithm = "ath9k_rate_control";
-#endif
-
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 			&sc->sbands[IEEE80211_BAND_2GHZ];
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/Kconfig linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/Kconfig
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/Kconfig	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/Kconfig	2013-06-18 21:17:03.000000000 -0400
@@ -50,13 +50,17 @@ config ATH9K_DEBUGFS
 
 	  Also required for changing debug message flags at run time.
 
-config ATH9K_RATE_CONTROL
+config ATH9K_LEGACY_RATE_CONTROL
 	bool "Atheros ath9k rate control"
 	depends on ATH9K
-	default y
+	default n
 	---help---
 	  Say Y, if you want to use the ath9k specific rate control
-	  module instead of minstrel_ht.
+	  module instead of minstrel_ht. Be warned that there are various
+	  issues with the ath9k RC and minstrel is a more robust algorithm.
+	  Note that even if this option is selected, "ath9k_rate_control"
+	  has to be passed to mac80211 using the module parameter,
+	  ieee80211_default_rc_algo.
 
 config ATH9K_HTC
        tristate "Atheros HTC based wireless cards support"
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/Makefile linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/Makefile
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2013-06-18 21:17:03.000000000 -0400
@@ -5,7 +5,7 @@ ath9k-y +=	beacon.o \
 		recv.o \
 		xmit.o \
 
-ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
+ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
 ath9k-$(CONFIG_ATH9K_PCI) += pci.o
 ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/rc.h linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/rc.h
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2013-06-18 21:17:03.000000000 -0400
@@ -221,7 +221,7 @@ struct ath_rate_priv {
 	struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 };
 
-#ifdef CONFIG_ATH9K_RATE_CONTROL
+#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
 int ath_rate_control_register(void);
 void ath_rate_control_unregister(void);
 #else
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/b43/main.c linux-libre-3.2.47-gnu1/drivers/net/wireless/b43/main.c
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/b43/main.c	2013-05-31 10:23:18.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/b43/main.c	2013-06-19 00:41:32.000000000 -0400
@@ -2412,7 +2412,7 @@ static int b43_maybe_reject_firmware(str
 	for (i = 0; i < B43_NR_FWTYPES; i++) {
 		errmsg = ctx->errors[i];
 		if (strlen(errmsg))
-			b43err(dev->wl, errmsg);
+			b43err(dev->wl, "%s", errmsg);
 	}
 	b43_print_fw_helptext(dev->wl, 1);
 	err = -ENOENT;
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/b43legacy/main.c linux-libre-3.2.47-gnu1/drivers/net/wireless/b43legacy/main.c
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-31 10:23:21.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/b43legacy/main.c	2013-06-19 00:41:35.000000000 -0400
@@ -3834,6 +3834,8 @@ static void b43legacy_remove(struct ssb_
 	cancel_work_sync(&wldev->restart_work);
 
 	B43legacy_WARN_ON(!wl);
+	if (!wldev->fw.ucode)
+		return;			/* NULL if fw never loaded */
 	if (wl->current_dev == wldev)
 		ieee80211_unregister_hw(wl->hw);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-sta.c linux-libre-3.2.47-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
--- linux-libre-3.2.46-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-sta.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-sta.c	2013-06-18 21:17:03.000000000 -0400
@@ -604,7 +604,7 @@ void iwl_restore_stations(struct iwl_pri
 					memcpy(&lq, priv->stations[i].lq,
 					       sizeof(struct iwl_link_quality_cmd));
 
-				if (!memcmp(&lq, &zero_lq, sizeof(lq)))
+				if (memcmp(&lq, &zero_lq, sizeof(lq)))
 					send_lq = true;
 			}
 			spin_unlock_irqrestore(&priv->shrd->sta_lock,
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/xen-netback/netback.c linux-libre-3.2.47-gnu1/drivers/net/xen-netback/netback.c
--- linux-libre-3.2.46-gnu1/drivers/net/xen-netback/netback.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/xen-netback/netback.c	2013-06-18 21:17:03.000000000 -0400
@@ -46,11 +46,33 @@
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
 
+/*
+ * This is the maximum slots a skb can have. If a guest sends a skb
+ * which exceeds this limit it is considered malicious.
+ */
+#define FATAL_SKB_SLOTS_DEFAULT 20
+static unsigned int fatal_skb_slots = FATAL_SKB_SLOTS_DEFAULT;
+module_param(fatal_skb_slots, uint, 0444);
+
+/*
+ * To avoid confusion, we define XEN_NETBK_LEGACY_SLOTS_MAX indicating
+ * the maximum slots a valid packet can use. Now this value is defined
+ * to be XEN_NETIF_NR_SLOTS_MIN, which is supposed to be supported by
+ * all backend.
+ */
+#define XEN_NETBK_LEGACY_SLOTS_MAX XEN_NETIF_NR_SLOTS_MIN
+
+typedef unsigned int pending_ring_idx_t;
+#define INVALID_PENDING_RING_IDX (~0U)
+
 struct pending_tx_info {
-	struct xen_netif_tx_request req;
+	struct xen_netif_tx_request req; /* coalesced tx request */
 	struct xenvif *vif;
+	pending_ring_idx_t head; /* head != INVALID_PENDING_RING_IDX
+				  * if it is head of one or more tx
+				  * reqs
+				  */
 };
-typedef unsigned int pending_ring_idx_t;
 
 struct netbk_rx_meta {
 	int id;
@@ -101,7 +123,11 @@ struct xen_netbk {
 	atomic_t netfront_count;
 
 	struct pending_tx_info pending_tx_info[MAX_PENDING_REQS];
-	struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS];
+	/* Coalescing tx requests before copying makes number of grant
+	 * copy ops greater or equal to number of slots required. In
+	 * worst case a tx request consumes 2 gnttab_copy.
+	 */
+	struct gnttab_copy tx_copy_ops[2*MAX_PENDING_REQS];
 
 	u16 pending_ring[MAX_PENDING_REQS];
 
@@ -117,6 +143,16 @@ struct xen_netbk {
 static struct xen_netbk *xen_netbk;
 static int xen_netbk_group_nr;
 
+/*
+ * If head != INVALID_PENDING_RING_IDX, it means this tx request is head of
+ * one or more merged tx requests, otherwise it is the continuation of
+ * previous tx request.
+ */
+static inline int pending_tx_is_head(struct xen_netbk *netbk, RING_IDX idx)
+{
+	return netbk->pending_tx_info[idx].head != INVALID_PENDING_RING_IDX;
+}
+
 void xen_netbk_add_xenvif(struct xenvif *vif)
 {
 	int i;
@@ -249,6 +285,7 @@ static int max_required_rx_slots(struct
 {
 	int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE);
 
+	/* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */
 	if (vif->can_sg || vif->gso || vif->gso_prefix)
 		max += MAX_SKB_FRAGS + 1; /* extra_info + frags */
 
@@ -627,6 +664,7 @@ static void xen_netbk_rx_action(struct x
 		__skb_queue_tail(&rxq, skb);
 
 		/* Filled the batch queue? */
+		/* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */
 		if (count + MAX_SKB_FRAGS >= XEN_NETIF_RX_RING_SIZE)
 			break;
 	}
@@ -874,47 +912,99 @@ static int netbk_count_requests(struct x
 				int work_to_do)
 {
 	RING_IDX cons = vif->tx.req_cons;
-	int frags = 0;
+	int slots = 0;
+	int drop_err = 0;
+	int more_data;
 
 	if (!(first->flags & XEN_NETTXF_more_data))
 		return 0;
 
 	do {
-		if (frags >= work_to_do) {
-			netdev_err(vif->dev, "Need more frags\n");
+		struct xen_netif_tx_request dropped_tx = { 0 };
+
+		if (slots >= work_to_do) {
+			netdev_err(vif->dev,
+				   "Asked for %d slots but exceeds this limit\n",
+				   work_to_do);
 			netbk_fatal_tx_err(vif);
 			return -ENODATA;
 		}
 
-		if (unlikely(frags >= MAX_SKB_FRAGS)) {
-			netdev_err(vif->dev, "Too many frags\n");
+		/* This guest is really using too many slots and
+		 * considered malicious.
+		 */
+		if (unlikely(slots >= fatal_skb_slots)) {
+			netdev_err(vif->dev,
+				   "Malicious frontend using %d slots, threshold %u\n",
+				   slots, fatal_skb_slots);
 			netbk_fatal_tx_err(vif);
 			return -E2BIG;
 		}
 
-		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),
+		/* Xen network protocol had implicit dependency on
+		 * MAX_SKB_FRAGS. XEN_NETBK_LEGACY_SLOTS_MAX is set to
+		 * the historical MAX_SKB_FRAGS value 18 to honor the
+		 * same behavior as before. Any packet using more than
+		 * 18 slots but less than fatal_skb_slots slots is
+		 * dropped
+		 */
+		if (!drop_err && slots >= XEN_NETBK_LEGACY_SLOTS_MAX) {
+			if (net_ratelimit())
+				netdev_dbg(vif->dev,
+					   "Too many slots (%d) exceeding limit (%d), dropping packet\n",
+					   slots, XEN_NETBK_LEGACY_SLOTS_MAX);
+			drop_err = -E2BIG;
+		}
+
+		if (drop_err)
+			txp = &dropped_tx;
+
+		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
 		       sizeof(*txp));
-		if (txp->size > first->size) {
-			netdev_err(vif->dev, "Frag is bigger than frame.\n");
-			netbk_fatal_tx_err(vif);
-			return -EIO;
+
+		/* If the guest submitted a frame >= 64 KiB then
+		 * first->size overflowed and following slots will
+		 * appear to be larger than the frame.
+		 *
+		 * This cannot be fatal error as there are buggy
+		 * frontends that do this.
+		 *
+		 * Consume all slots and drop the packet.
+		 */
+		if (!drop_err && txp->size > first->size) {
+			if (net_ratelimit())
+				netdev_dbg(vif->dev,
+					   "Invalid tx request, slot size %u > remaining size %u\n",
+					   txp->size, first->size);
+			drop_err = -EIO;
 		}
 
 		first->size -= txp->size;
-		frags++;
+		slots++;
 
 		if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
-			netdev_err(vif->dev, "txp->offset: %x, size: %u\n",
+			netdev_err(vif->dev, "Cross page boundary, txp->offset: %x, size: %u\n",
 				 txp->offset, txp->size);
 			netbk_fatal_tx_err(vif);
 			return -EINVAL;
 		}
-	} while ((txp++)->flags & XEN_NETTXF_more_data);
-	return frags;
+
+		more_data = txp->flags & XEN_NETTXF_more_data;
+
+		if (!drop_err)
+			txp++;
+
+	} while (more_data);
+
+	if (drop_err) {
+		netbk_tx_err(vif, first, cons + slots);
+		return drop_err;
+	}
+
+	return slots;
 }
 
 static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk,
-					 struct sk_buff *skb,
 					 u16 pending_idx)
 {
 	struct page *page;
@@ -935,50 +1025,114 @@ static struct gnttab_copy *xen_netbk_get
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	skb_frag_t *frags = shinfo->frags;
 	u16 pending_idx = *((u16 *)skb->data);
-	int i, start;
+	u16 head_idx = 0;
+	int slot, start;
+	struct page *page;
+	pending_ring_idx_t index, start_idx = 0;
+	uint16_t dst_offset;
+	unsigned int nr_slots;
+	struct pending_tx_info *first = NULL;
+
+	/* At this point shinfo->nr_frags is in fact the number of
+	 * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
+	 */
+	nr_slots = shinfo->nr_frags;
 
 	/* Skip first skb fragment if it is on same page as header fragment. */
 	start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);
 
-	for (i = start; i < shinfo->nr_frags; i++, txp++) {
-		struct page *page;
-		pending_ring_idx_t index;
+	/* Coalesce tx requests, at this point the packet passed in
+	 * should be <= 64K. Any packets larger than 64K have been
+	 * handled in netbk_count_requests().
+	 */
+	for (shinfo->nr_frags = slot = start; slot < nr_slots;
+	     shinfo->nr_frags++) {
 		struct pending_tx_info *pending_tx_info =
 			netbk->pending_tx_info;
 
-		index = pending_index(netbk->pending_cons++);
-		pending_idx = netbk->pending_ring[index];
-		page = xen_netbk_alloc_page(netbk, skb, pending_idx);
+		page = alloc_page(GFP_KERNEL|__GFP_COLD);
 		if (!page)
 			goto err;
 
-		netbk->mmap_pages[pending_idx] = page;
+		dst_offset = 0;
+		first = NULL;
+		while (dst_offset < PAGE_SIZE && slot < nr_slots) {
+			gop->flags = GNTCOPY_source_gref;
 
-		gop->source.u.ref = txp->gref;
-		gop->source.domid = vif->domid;
-		gop->source.offset = txp->offset;
+			gop->source.u.ref = txp->gref;
+			gop->source.domid = vif->domid;
+			gop->source.offset = txp->offset;
 
-		gop->dest.u.gmfn = virt_to_mfn(page_address(page));
-		gop->dest.domid = DOMID_SELF;
-		gop->dest.offset = txp->offset;
+			gop->dest.domid = DOMID_SELF;
 
-		gop->len = txp->size;
-		gop->flags = GNTCOPY_source_gref;
+			gop->dest.offset = dst_offset;
+			gop->dest.u.gmfn = virt_to_mfn(page_address(page));
 
-		gop++;
+			if (dst_offset + txp->size > PAGE_SIZE) {
+				/* This page can only merge a portion
+				 * of tx request. Do not increment any
+				 * pointer / counter here. The txp
+				 * will be dealt with in future
+				 * rounds, eventually hitting the
+				 * `else` branch.
+				 */
+				gop->len = PAGE_SIZE - dst_offset;
+				txp->offset += gop->len;
+				txp->size -= gop->len;
+				dst_offset += gop->len; /* quit loop */
+			} else {
+				/* This tx request can be merged in the page */
+				gop->len = txp->size;
+				dst_offset += gop->len;
 
-		memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
-		xenvif_get(vif);
-		pending_tx_info[pending_idx].vif = vif;
-		frag_set_pending_idx(&frags[i], pending_idx);
+				index = pending_index(netbk->pending_cons++);
+
+				pending_idx = netbk->pending_ring[index];
+
+				memcpy(&pending_tx_info[pending_idx].req, txp,
+				       sizeof(*txp));
+				xenvif_get(vif);
+
+				pending_tx_info[pending_idx].vif = vif;
+
+				/* Poison these fields, corresponding
+				 * fields for head tx req will be set
+				 * to correct values after the loop.
+				 */
+				netbk->mmap_pages[pending_idx] = (void *)(~0UL);
+				pending_tx_info[pending_idx].head =
+					INVALID_PENDING_RING_IDX;
+
+				if (!first) {
+					first = &pending_tx_info[pending_idx];
+					start_idx = index;
+					head_idx = pending_idx;
+				}
+
+				txp++;
+				slot++;
+			}
+
+			gop++;
+		}
+
+		first->req.offset = 0;
+		first->req.size = dst_offset;
+		first->head = start_idx;
+		set_page_ext(page, netbk, head_idx);
+		netbk->mmap_pages[head_idx] = page;
+		frag_set_pending_idx(&frags[shinfo->nr_frags], head_idx);
 	}
 
+	BUG_ON(shinfo->nr_frags > MAX_SKB_FRAGS);
+
 	return gop;
 err:
 	/* Unwind, freeing all pages and sending error responses. */
-	while (i-- > start) {
-		xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]),
-				      XEN_NETIF_RSP_ERROR);
+	while (shinfo->nr_frags-- > start) {
+		xen_netbk_idx_release(netbk,
+				frag_get_pending_idx(&frags[shinfo->nr_frags]),
+				XEN_NETIF_RSP_ERROR);
 	}
 	/* The head too, if necessary. */
 	if (start)
@@ -994,8 +1148,10 @@ static int xen_netbk_tx_check_gop(struct
 	struct gnttab_copy *gop = *gopp;
 	u16 pending_idx = *((u16 *)skb->data);
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
+	struct pending_tx_info *tx_info;
 	int nr_frags = shinfo->nr_frags;
 	int i, err, start;
+	u16 peek; /* peek into next tx request */
 
 	/* Check status of header. */
 	err = gop->status;
@@ -1007,11 +1163,20 @@ static int xen_netbk_tx_check_gop(struct
 
 	for (i = start; i < nr_frags; i++) {
 		int j, newerr;
+		pending_ring_idx_t head;
 
 		pending_idx = frag_get_pending_idx(&shinfo->frags[i]);
+		tx_info = &netbk->pending_tx_info[pending_idx];
+		head = tx_info->head;
 
 		/* Check error status: if okay then remember grant handle. */
-		newerr = (++gop)->status;
+		do {
+			newerr = (++gop)->status;
+			if (newerr)
+				break;
+			peek = netbk->pending_ring[pending_index(++head)];
+		} while (!pending_tx_is_head(netbk, peek));
+
 		if (likely(!newerr)) {
 			/* Had a previous error? Invalidate this fragment. */
 			if (unlikely(err))
@@ -1236,11 +1401,12 @@ static unsigned xen_netbk_tx_build_gops(
 	struct sk_buff *skb;
 	int ret;
 
-	while (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
+	while ((nr_pending_reqs(netbk) + XEN_NETBK_LEGACY_SLOTS_MAX
+		< MAX_PENDING_REQS) &&
 		!list_empty(&netbk->net_schedule_list)) {
 		struct xenvif *vif;
 		struct xen_netif_tx_request txreq;
-		struct xen_netif_tx_request txfrags[MAX_SKB_FRAGS];
+		struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX];
 		struct page *page;
 		struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX-1];
 		u16 pending_idx;
@@ -1328,7 +1494,7 @@ static unsigned xen_netbk_tx_build_gops(
 		pending_idx = netbk->pending_ring[index];
 
 		data_len = (txreq.size > PKT_PROT_LEN &&
-			    ret < MAX_SKB_FRAGS) ?
+			    ret < XEN_NETBK_LEGACY_SLOTS_MAX) ?
 			PKT_PROT_LEN : txreq.size;
 
 		skb = alloc_skb(data_len + NET_SKB_PAD + NET_IP_ALIGN,
@@ -1355,15 +1521,13 @@ static unsigned xen_netbk_tx_build_gops(
 		}
 
 		/* XXX could copy straight to head */
-		page = xen_netbk_alloc_page(netbk, skb, pending_idx);
+		page = xen_netbk_alloc_page(netbk, pending_idx);
 		if (!page) {
 			kfree_skb(skb);
 			netbk_tx_err(vif, &txreq, idx);
 			continue;
 		}
 
-		netbk->mmap_pages[pending_idx] = page;
-
 		gop->source.u.ref = txreq.gref;
 		gop->source.domid = vif->domid;
 		gop->source.offset = txreq.offset;
@@ -1380,6 +1544,7 @@ static unsigned xen_netbk_tx_build_gops(
 		memcpy(&netbk->pending_tx_info[pending_idx].req,
 		       &txreq, sizeof(txreq));
 		netbk->pending_tx_info[pending_idx].vif = vif;
+		netbk->pending_tx_info[pending_idx].head = index;
 		*((u16 *)skb->data) = pending_idx;
 
 		__skb_put(skb, data_len);
@@ -1510,7 +1675,10 @@ static void xen_netbk_idx_release(struct
 {
 	struct xenvif *vif;
 	struct pending_tx_info *pending_tx_info;
-	pending_ring_idx_t index;
+	pending_ring_idx_t head;
+	u16 peek; /* peek into next tx request */
+
+	BUG_ON(netbk->mmap_pages[pending_idx] == (void *)(~0UL));
 
 	/* Already complete? */
 	if (netbk->mmap_pages[pending_idx] == NULL)
@@ -1519,19 +1687,40 @@ static void xen_netbk_idx_release(struct
 	pending_tx_info = &netbk->pending_tx_info[pending_idx];
 
 	vif = pending_tx_info->vif;
+	head = pending_tx_info->head;
 
-	make_tx_response(vif, &pending_tx_info->req, status);
+	BUG_ON(!pending_tx_is_head(netbk, head));
+	BUG_ON(netbk->pending_ring[pending_index(head)] != pending_idx);
 
-	index = pending_index(netbk->pending_prod++);
-	netbk->pending_ring[index] = pending_idx;
+	do {
+		pending_ring_idx_t index;
+		pending_ring_idx_t idx = pending_index(head);
+		u16 info_idx = netbk->pending_ring[idx];
 
-	xenvif_put(vif);
+		pending_tx_info = &netbk->pending_tx_info[info_idx];
+		make_tx_response(vif, &pending_tx_info->req, status);
+
+		/* Setting any number other than
+		 * INVALID_PENDING_RING_IDX indicates this slot is
+		 * starting a new packet / ending a previous packet.
+		 */
+		pending_tx_info->head = 0;
+
+		index = pending_index(netbk->pending_prod++);
+		netbk->pending_ring[index] = netbk->pending_ring[info_idx];
+
+		xenvif_put(vif);
+
+		peek = netbk->pending_ring[pending_index(++head)];
+
+	} while (!pending_tx_is_head(netbk, peek));
 
 	netbk->mmap_pages[pending_idx]->mapping = 0;
 	put_page(netbk->mmap_pages[pending_idx]);
 	netbk->mmap_pages[pending_idx] = NULL;
 }
 
+
 static void make_tx_response(struct xenvif *vif,
 			     struct xen_netif_tx_request *txp,
 			     s8       st)
@@ -1584,8 +1773,9 @@ static inline int rx_work_todo(struct xe
 static inline int tx_work_todo(struct xen_netbk *netbk)
 {
 
-	if (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
-			!list_empty(&netbk->net_schedule_list))
+	if ((nr_pending_reqs(netbk) + XEN_NETBK_LEGACY_SLOTS_MAX
+	     < MAX_PENDING_REQS) &&
+	     !list_empty(&netbk->net_schedule_list))
 		return 1;
 
 	return 0;
@@ -1668,6 +1858,13 @@ static int __init netback_init(void)
 	if (!xen_pv_domain())
 		return -ENODEV;
 
+	if (fatal_skb_slots < XEN_NETBK_LEGACY_SLOTS_MAX) {
+		printk(KERN_INFO
+		       "xen-netback: fatal_skb_slots too small (%d), bump it to XEN_NETBK_LEGACY_SLOTS_MAX (%d)\n",
+		       fatal_skb_slots, XEN_NETBK_LEGACY_SLOTS_MAX);
+		fatal_skb_slots = XEN_NETBK_LEGACY_SLOTS_MAX;
+	}
+
 	xen_netbk_group_nr = num_online_cpus();
 	xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr);
 	if (!xen_netbk) {
diff -druNp linux-libre-3.2.46-gnu1/drivers/net/xen-netfront.c linux-libre-3.2.47-gnu1/drivers/net/xen-netfront.c
--- linux-libre-3.2.46-gnu1/drivers/net/xen-netfront.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/net/xen-netfront.c	2013-06-18 21:17:03.000000000 -0400
@@ -36,7 +36,7 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <linux/if_ether.h>
-#include <linux/tcp.h>
+#include <net/tcp.h>
 #include <linux/udp.h>
 #include <linux/moduleparam.h>
 #include <linux/mm.h>
@@ -490,6 +490,16 @@ static int xennet_start_xmit(struct sk_b
 	unsigned int offset = offset_in_page(data);
 	unsigned int len = skb_headlen(skb);
 
+	/* If skb->len is too big for wire format, drop skb and alert
+	 * user about misconfiguration.
+	 */
+	if (unlikely(skb->len > XEN_NETIF_MAX_TX_SIZE)) {
+		net_alert_ratelimited(
+			"xennet: skb->len = %u, too big for wire format\n",
+			skb->len);
+		goto drop;
+	}
+
 	frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
 	if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
 		printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
@@ -1043,7 +1053,8 @@ err:
 
 static int xennet_change_mtu(struct net_device *dev, int mtu)
 {
-	int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+	int max = xennet_can_sg(dev) ?
+		XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER : ETH_DATA_LEN;
 
 	if (mtu > max)
 		return -EINVAL;
@@ -1318,6 +1329,8 @@ static struct net_device * __devinit xen
 	SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
 	SET_NETDEV_DEV(netdev, &dev->dev);
 
+	netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER);
+
 	np->netdev = netdev;
 
 	netif_carrier_off(netdev);
diff -druNp linux-libre-3.2.46-gnu1/drivers/platform/x86/thinkpad_acpi.c linux-libre-3.2.47-gnu1/drivers/platform/x86/thinkpad_acpi.c
--- linux-libre-3.2.46-gnu1/drivers/platform/x86/thinkpad_acpi.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/platform/x86/thinkpad_acpi.c	2013-06-18 21:17:03.000000000 -0400
@@ -8665,6 +8665,13 @@ static int __must_check __init get_think
 		tp->model_str = kstrdup(s, GFP_KERNEL);
 		if (!tp->model_str)
 			return -ENOMEM;
+	} else {
+		s = dmi_get_system_info(DMI_BIOS_VENDOR);
+		if (s && !(strnicmp(s, "Lenovo", 6))) {
+			tp->model_str = kstrdup(s, GFP_KERNEL);
+			if (!tp->model_str)
+				return -ENOMEM;
+		}
 	}
 
 	s = dmi_get_system_info(DMI_PRODUCT_NAME);
diff -druNp linux-libre-3.2.46-gnu1/drivers/rapidio/devices/tsi721.c linux-libre-3.2.47-gnu1/drivers/rapidio/devices/tsi721.c
--- linux-libre-3.2.46-gnu1/drivers/rapidio/devices/tsi721.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/rapidio/devices/tsi721.c	2013-06-18 21:17:03.000000000 -0400
@@ -555,7 +555,7 @@ static irqreturn_t tsi721_irqhandler(int
 	/* For MSI mode re-enable device-level interrupts */
 	if (priv->flags & TSI721_USING_MSI) {
 		dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
-			TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH;
+			TSI721_DEV_INT_SMSG_CH;
 		iowrite32(dev_int, priv->regs + TSI721_DEV_INTE);
 	}
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/rtc/rtc-twl.c linux-libre-3.2.47-gnu1/drivers/rtc/rtc-twl.c
--- linux-libre-3.2.46-gnu1/drivers/rtc/rtc-twl.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/rtc/rtc-twl.c	2013-06-18 21:17:03.000000000 -0400
@@ -490,6 +490,7 @@ static int __devinit twl_rtc_probe(struc
 	}
 
 	platform_set_drvdata(pdev, rtc);
+	device_init_wakeup(&pdev->dev, 1);
 	return 0;
 
 out2:
diff -druNp linux-libre-3.2.46-gnu1/drivers/staging/gma500/cdv_intel_display.c linux-libre-3.2.47-gnu1/drivers/staging/gma500/cdv_intel_display.c
--- linux-libre-3.2.46-gnu1/drivers/staging/gma500/cdv_intel_display.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/staging/gma500/cdv_intel_display.c	2013-06-18 21:17:03.000000000 -0400
@@ -1457,6 +1457,19 @@ static void cdv_intel_crtc_destroy(struc
 	kfree(psb_intel_crtc);
 }
 
+static void cdv_intel_crtc_disable(struct drm_crtc *crtc)
+{
+	struct gtt_range *gt;
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+	if (crtc->fb) {
+		gt = to_psb_fb(crtc->fb)->gtt;
+		psb_gtt_unpin(gt);
+	}
+}
+
 const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
 	.dpms = cdv_intel_crtc_dpms,
 	.mode_fixup = cdv_intel_crtc_mode_fixup,
@@ -1464,6 +1477,7 @@ const struct drm_crtc_helper_funcs cdv_i
 	.mode_set_base = cdv_intel_pipe_set_base,
 	.prepare = cdv_intel_crtc_prepare,
 	.commit = cdv_intel_crtc_commit,
+	.disable = cdv_intel_crtc_disable,
 };
 
 const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
diff -druNp linux-libre-3.2.46-gnu1/drivers/staging/gma500/framebuffer.c linux-libre-3.2.47-gnu1/drivers/staging/gma500/framebuffer.c
--- linux-libre-3.2.46-gnu1/drivers/staging/gma500/framebuffer.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/staging/gma500/framebuffer.c	2013-06-18 21:17:03.000000000 -0400
@@ -831,8 +831,8 @@ void psb_modeset_init(struct drm_device
 	for (i = 0; i < dev_priv->num_pipe; i++)
 		psb_intel_crtc_init(dev, i, mode_dev);
 
-	dev->mode_config.max_width = 2048;
-	dev->mode_config.max_height = 2048;
+	dev->mode_config.max_width = 4096;
+	dev->mode_config.max_height = 4096;
 
 	psb_setup_outputs(dev);
 }
diff -druNp linux-libre-3.2.46-gnu1/drivers/staging/gma500/psb_intel_display.c linux-libre-3.2.47-gnu1/drivers/staging/gma500/psb_intel_display.c
--- linux-libre-3.2.46-gnu1/drivers/staging/gma500/psb_intel_display.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/staging/gma500/psb_intel_display.c	2013-06-18 21:17:03.000000000 -0400
@@ -1255,6 +1255,19 @@ void psb_intel_crtc_destroy(struct drm_c
 	kfree(psb_intel_crtc);
 }
 
+static void psb_intel_crtc_disable(struct drm_crtc *crtc)
+{
+	struct gtt_range *gt;
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+	if (crtc->fb) {
+		gt = to_psb_fb(crtc->fb)->gtt;
+		psb_gtt_unpin(gt);
+	}
+}
+
 const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
 	.dpms = psb_intel_crtc_dpms,
 	.mode_fixup = psb_intel_crtc_mode_fixup,
@@ -1262,6 +1275,7 @@ const struct drm_crtc_helper_funcs psb_i
 	.mode_set_base = psb_intel_pipe_set_base,
 	.prepare = psb_intel_crtc_prepare,
 	.commit = psb_intel_crtc_commit,
+	.disable = psb_intel_crtc_disable,
 };
 
 const struct drm_crtc_funcs psb_intel_crtc_funcs = {
diff -druNp linux-libre-3.2.46-gnu1/drivers/target/iscsi/iscsi_target_parameters.c linux-libre-3.2.47-gnu1/drivers/target/iscsi/iscsi_target_parameters.c
--- linux-libre-3.2.46-gnu1/drivers/target/iscsi/iscsi_target_parameters.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/target/iscsi/iscsi_target_parameters.c	2013-06-18 21:17:03.000000000 -0400
@@ -713,9 +713,9 @@ static int iscsi_add_notunderstood_respo
 	}
 	INIT_LIST_HEAD(&extra_response->er_list);
 
-	strncpy(extra_response->key, key, strlen(key) + 1);
-	strncpy(extra_response->value, NOTUNDERSTOOD,
-			strlen(NOTUNDERSTOOD) + 1);
+	strlcpy(extra_response->key, key, sizeof(extra_response->key));
+	strlcpy(extra_response->value, NOTUNDERSTOOD,
+		sizeof(extra_response->value));
 
 	list_add_tail(&extra_response->er_list,
 			&param_list->extra_response_list);
@@ -1572,8 +1572,6 @@ int iscsi_decode_text_input(
 
 		if (phase & PHASE_SECURITY) {
 			if (iscsi_check_for_auth_key(key) > 0) {
-				char *tmpptr = key + strlen(key);
-				*tmpptr = '=';
 				kfree(tmpbuf);
 				return 1;
 			}
diff -druNp linux-libre-3.2.46-gnu1/drivers/target/iscsi/iscsi_target_parameters.h linux-libre-3.2.47-gnu1/drivers/target/iscsi/iscsi_target_parameters.h
--- linux-libre-3.2.46-gnu1/drivers/target/iscsi/iscsi_target_parameters.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/target/iscsi/iscsi_target_parameters.h	2013-06-18 21:17:03.000000000 -0400
@@ -1,8 +1,10 @@
 #ifndef ISCSI_PARAMETERS_H
 #define ISCSI_PARAMETERS_H
 
+#include <scsi/iscsi_proto.h>
+
 struct iscsi_extra_response {
-	char key[64];
+	char key[KEY_MAXLEN];
 	char value[32];
 	struct list_head er_list;
 } ____cacheline_aligned;
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/dwc3/gadget.c linux-libre-3.2.47-gnu1/drivers/usb/dwc3/gadget.c
--- linux-libre-3.2.46-gnu1/drivers/usb/dwc3/gadget.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/dwc3/gadget.c	2013-06-18 21:17:03.000000000 -0400
@@ -1310,10 +1310,19 @@ static void dwc3_gadget_free_endpoints(s
 
 	for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
 		dep = dwc->eps[epnum];
-		dwc3_free_trb_pool(dep);
-
-		if (epnum != 0 && epnum != 1)
+		/*
+		 * Physical endpoints 0 and 1 are special; they form the
+		 * bi-directional USB endpoint 0.
+		 *
+		 * For those two physical endpoints, we don't allocate a TRB
+		 * pool nor do we add them the endpoints list. Due to that, we
+		 * shouldn't do these two operations otherwise we would end up
+		 * with all sorts of bugs when removing dwc3.ko.
+		 */
+		if (epnum != 0 && epnum != 1) {
+			dwc3_free_trb_pool(dep);
 			list_del(&dep->endpoint.ep_list);
+		}
 
 		kfree(dep);
 	}
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/host/ehci-sched.c linux-libre-3.2.47-gnu1/drivers/usb/host/ehci-sched.c
--- linux-libre-3.2.46-gnu1/drivers/usb/host/ehci-sched.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/host/ehci-sched.c	2013-06-18 21:17:03.000000000 -0400
@@ -236,7 +236,7 @@ static inline unsigned char tt_start_ufr
 }
 
 static const unsigned char
-max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
+max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
 
 /* carryover low/fullspeed bandwidth that crosses uframe boundries */
 static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/host/xhci.c linux-libre-3.2.47-gnu1/drivers/usb/host/xhci.c
--- linux-libre-3.2.46-gnu1/drivers/usb/host/xhci.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/host/xhci.c	2013-06-18 21:17:03.000000000 -0400
@@ -938,6 +938,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
 	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
 	struct usb_hcd		*secondary_hcd;
 	int			retval = 0;
+	bool			comp_timer_running = false;
 
 	/* Wait a bit if either of the roothubs need to settle from the
 	 * transition into bus suspend.
@@ -975,6 +976,13 @@ int xhci_resume(struct xhci_hcd *xhci, b
 
 	/* If restore operation fails, re-initialize the HC during resume */
 	if ((temp & STS_SRE) || hibernated) {
+
+		if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
+				!(xhci_all_ports_seen_u0(xhci))) {
+			del_timer_sync(&xhci->comp_mode_recovery_timer);
+			xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
+		}
+
 		/* Let the USB core know _both_ roothubs lost power. */
 		usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
 		usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
@@ -1017,6 +1025,8 @@ int xhci_resume(struct xhci_hcd *xhci, b
 		retval = xhci_init(hcd->primary_hcd);
 		if (retval)
 			return retval;
+		comp_timer_running = true;
+
 		xhci_dbg(xhci, "Start the primary HCD\n");
 		retval = xhci_run(hcd->primary_hcd);
 		if (!retval) {
@@ -1058,7 +1068,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
 	 * to suffer the Compliance Mode issue again. It doesn't matter if
 	 * ports have entered previously to U0 before system's suspension.
 	 */
-	if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
 		compliance_mode_recovery_timer_init(xhci);
 
 	/* Re-enable port polling. */
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/host/xhci-mem.c linux-libre-3.2.47-gnu1/drivers/usb/host/xhci-mem.c
--- linux-libre-3.2.46-gnu1/drivers/usb/host/xhci-mem.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/host/xhci-mem.c	2013-06-18 21:17:03.000000000 -0400
@@ -1755,6 +1755,9 @@ void xhci_mem_cleanup(struct xhci_hcd *x
 	}
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
+	if (!xhci->rh_bw)
+		goto no_bw;
+
 	num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
 	for (i = 0; i < num_ports; i++) {
 		struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
@@ -1773,6 +1776,7 @@ void xhci_mem_cleanup(struct xhci_hcd *x
 		}
 	}
 
+no_bw:
 	xhci->num_usb2_ports = 0;
 	xhci->num_usb3_ports = 0;
 	xhci->num_active_eps = 0;
@@ -2184,6 +2188,9 @@ int xhci_mem_init(struct xhci_hcd *xhci,
 	u32 page_size;
 	int i;
 
+	INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+	INIT_LIST_HEAD(&xhci->cancel_cmd_list);
+
 	page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
 	xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
 	for (i = 0; i < 16; i++) {
@@ -2262,7 +2269,6 @@ int xhci_mem_init(struct xhci_hcd *xhci,
 	xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, false, flags);
 	if (!xhci->cmd_ring)
 		goto fail;
-	INIT_LIST_HEAD(&xhci->cancel_cmd_list);
 	xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
 	xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
 			(unsigned long long)xhci->cmd_ring->first_seg->dma);
@@ -2363,8 +2369,6 @@ int xhci_mem_init(struct xhci_hcd *xhci,
 	if (xhci_setup_port_arrays(xhci, flags))
 		goto fail;
 
-	INIT_LIST_HEAD(&xhci->lpm_failed_devs);
-
 	return 0;
 
 fail:
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/ark3116.c linux-libre-3.2.47-gnu1/drivers/usb/serial/ark3116.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/ark3116.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/ark3116.c	2013-06-18 21:17:03.000000000 -0400
@@ -49,7 +49,7 @@ static int debug;
 #define DRIVER_NAME "ark3116"
 
 /* usb timeout of 1 second */
-#define ARK_TIMEOUT (1*HZ)
+#define ARK_TIMEOUT 1000
 
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x6547, 0x0232) },
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/cypress_m8.c linux-libre-3.2.47-gnu1/drivers/usb/serial/cypress_m8.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/cypress_m8.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/cypress_m8.c	2013-06-18 21:17:03.000000000 -0400
@@ -96,6 +96,7 @@ static const struct usb_device_id id_tab
 static const struct usb_device_id id_table_cyphidcomrs232[] = {
 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
 	{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+	{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
 	{ }						/* Terminating entry */
 };
 
@@ -109,6 +110,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
 	{ USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+	{ USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
 	{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
 	{ }						/* Terminating entry */
 };
@@ -267,6 +269,12 @@ static struct usb_serial_driver cypress_
  * Cypress serial helper functions
  *****************************************************************************/
 
+/* FRWD Dongle hidcom needs to skip reset and speed checks */
+static inline bool is_frwd(struct usb_device *dev)
+{
+	return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
+		(le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
+}
 
 static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
 {
@@ -276,6 +284,10 @@ static int analyze_baud_rate(struct usb_
 	if (unstable_bauds)
 		return new_rate;
 
+	/* FRWD Dongle uses 115200 bps */
+	if (is_frwd(port->serial->dev))
+		return new_rate;
+
 	/*
 	 * The general purpose firmware for the Cypress M8 allows for
 	 * a maximum speed of 57600bps (I have no idea whether DeLorme
@@ -488,7 +500,11 @@ static int generic_startup(struct usb_se
 		return -ENOMEM;
 	}
 
-	usb_reset_configuration(serial->dev);
+	/* Skip reset for FRWD device. It is a workaound:
+	   device hangs if it receives SET_CONFIGURE in Configured
+	   state. */
+	if (!is_frwd(serial->dev))
+		usb_reset_configuration(serial->dev);
 
 	priv->cmd_ctrl = 0;
 	priv->line_control = 0;
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/cypress_m8.h linux-libre-3.2.47-gnu1/drivers/usb/serial/cypress_m8.h
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/cypress_m8.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/cypress_m8.h	2013-06-18 21:17:03.000000000 -0400
@@ -24,6 +24,10 @@
 #define VENDOR_ID_CYPRESS		0x04b4
 #define PRODUCT_ID_CYPHIDCOM		0x5500
 
+/* FRWD Dongle - a GPS sports watch */
+#define VENDOR_ID_FRWD			0x6737
+#define PRODUCT_ID_CYPHIDCOM_FRWD	0x0001
+
 /* Powercom UPS, chip CY7C63723 */
 #define VENDOR_ID_POWERCOM		0x0d9f
 #define PRODUCT_ID_UPS			0x0002
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/ftdi_sio.c linux-libre-3.2.47-gnu1/drivers/usb/serial/ftdi_sio.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/ftdi_sio.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/ftdi_sio.c	2013-06-18 21:17:03.000000000 -0400
@@ -2169,6 +2169,9 @@ static void ftdi_set_termios(struct tty_
 
 	cflag = termios->c_cflag;
 
+	if (!old_termios)
+		goto no_skip;
+
 	if (old_termios->c_cflag == termios->c_cflag
 	    && old_termios->c_ispeed == termios->c_ispeed
 	    && old_termios->c_ospeed == termios->c_ospeed)
@@ -2182,6 +2185,7 @@ static void ftdi_set_termios(struct tty_
 	    (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
 		goto no_data_parity_stop_changes;
 
+no_skip:
 	/* Set number of data bits, parity, stop bits */
 
 	urb_value = 0;
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/iuu_phoenix.c linux-libre-3.2.47-gnu1/drivers/usb/serial/iuu_phoenix.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/iuu_phoenix.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/iuu_phoenix.c	2013-06-18 21:17:03.000000000 -0400
@@ -327,7 +327,7 @@ static int bulk_immediate(struct usb_ser
 	    usb_bulk_msg(serial->dev,
 			 usb_sndbulkpipe(serial->dev,
 					 port->bulk_out_endpointAddress), buf,
-			 count, &actual, HZ * 1);
+			 count, &actual, 1000);
 
 	if (status != IUU_OPERATION_OK)
 		dbg("%s - error = %2x", __func__, status);
@@ -350,7 +350,7 @@ static int read_immediate(struct usb_ser
 	    usb_bulk_msg(serial->dev,
 			 usb_rcvbulkpipe(serial->dev,
 					 port->bulk_in_endpointAddress), buf,
-			 count, &actual, HZ * 1);
+			 count, &actual, 1000);
 
 	if (status != IUU_OPERATION_OK)
 		dbg("%s - error = %2x", __func__, status);
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/keyspan.c linux-libre-3.2.47-gnu1/drivers/usb/serial/keyspan.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/keyspan.c	2013-05-31 10:27:35.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/keyspan.c	2013-06-19 00:45:49.000000000 -0400
@@ -1833,7 +1833,7 @@ static int keyspan_usa26_send_setup(stru
 	d_details = s_priv->device_details;
 	device_port = port->number - port->serial->minor;
 
-	outcont_urb = d_details->outcont_endpoints[port->number];
+	outcont_urb = d_details->outcont_endpoints[device_port];
 	this_urb = p_priv->outcont_urb;
 
 	dbg("%s - endpoint %d", __func__, usb_pipeendpoint(this_urb->pipe));
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/mos7720.c linux-libre-3.2.47-gnu1/drivers/usb/serial/mos7720.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/mos7720.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/mos7720.c	2013-06-18 21:17:03.000000000 -0400
@@ -44,7 +44,7 @@
 #define DRIVER_DESC "Moschip USB Serial Driver"
 
 /* default urb timeout */
-#define MOS_WDR_TIMEOUT	(HZ * 5)
+#define MOS_WDR_TIMEOUT	5000
 
 #define MOS_MAX_PORT	0x02
 #define MOS_WRITE	0x0E
@@ -234,11 +234,22 @@ static int read_mos_reg(struct usb_seria
 	__u8 requesttype = (__u8)0xc0;
 	__u16 index = get_reg_index(reg);
 	__u16 value = get_reg_value(reg, serial_portnum);
-	int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
-				     index, data, 1, MOS_WDR_TIMEOUT);
-	if (status < 0)
+	u8 *buf;
+	int status;
+
+	buf = kmalloc(1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	status = usb_control_msg(usbdev, pipe, request, requesttype, value,
+				     index, buf, 1, MOS_WDR_TIMEOUT);
+	if (status == 1)
+		*data = *buf;
+	else if (status < 0)
 		dev_err(&usbdev->dev,
 			"mos7720: usb_control_msg() failed: %d", status);
+	kfree(buf);
+
 	return status;
 }
 
@@ -1700,7 +1711,7 @@ static void change_port_settings(struct
 		mos7720_port->shadowMCR |= (UART_MCR_XONANY);
 		/* To set hardware flow control to the specified *
 		 * serial port, in SP1/2_CONTROL_REG             */
-		if (port->number)
+		if (port_number)
 			write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
 		else
 			write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
@@ -2112,7 +2123,7 @@ static int mos7720_startup(struct usb_se
 
 	/* setting configuration feature to one */
 	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
+			(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
 
 	/* start the interrupt urb */
 	ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
@@ -2157,7 +2168,7 @@ static void mos7720_release(struct usb_s
 		/* wait for synchronous usb calls to return */
 		if (mos_parport->msg_pending)
 			wait_for_completion_timeout(&mos_parport->syncmsg_compl,
-						    MOS_WDR_TIMEOUT);
+					    msecs_to_jiffies(MOS_WDR_TIMEOUT));
 
 		parport_remove_port(mos_parport->pp);
 		usb_set_serial_data(serial, NULL);
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/option.c linux-libre-3.2.47-gnu1/drivers/usb/serial/option.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/option.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/option.c	2013-06-18 21:17:03.000000000 -0400
@@ -593,6 +593,8 @@ static const struct usb_device_id option
 		.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff),	/* Huawei E1820 */
+		.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
 	{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/pl2303.c linux-libre-3.2.47-gnu1/drivers/usb/serial/pl2303.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/pl2303.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/pl2303.c	2013-06-18 21:17:03.000000000 -0400
@@ -270,7 +270,7 @@ static void pl2303_set_termios(struct tt
 	   serial settings even to the same values as before. Thus
 	   we actually need to filter in this specific case */
 
-	if (!tty_termios_hw_change(tty->termios, old_termios))
+	if (old_termios && !tty_termios_hw_change(tty->termios, old_termios))
 		return;
 
 	cflag = tty->termios->c_cflag;
@@ -279,7 +279,8 @@ static void pl2303_set_termios(struct tt
 	if (!buf) {
 		dev_err(&port->dev, "%s - out of memory.\n", __func__);
 		/* Report back no change occurred */
-		*tty->termios = *old_termios;
+		if (old_termios)
+			*tty->termios = *old_termios;
 		return;
 	}
 
@@ -419,7 +420,7 @@ static void pl2303_set_termios(struct tt
 	control = priv->line_control;
 	if ((cflag & CBAUD) == B0)
 		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-	else if ((old_termios->c_cflag & CBAUD) == B0)
+	else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
 		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
 	if (control != priv->line_control) {
 		control = priv->line_control;
@@ -480,7 +481,6 @@ static void pl2303_close(struct usb_seri
 
 static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	int result;
@@ -498,7 +498,7 @@ static int pl2303_open(struct tty_struct
 
 	/* Setup termios */
 	if (tty)
-		pl2303_set_termios(tty, port, &tmp_termios);
+		pl2303_set_termios(tty, port, NULL);
 
 	dbg("%s - submitting read urb", __func__);
 	result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/qcserial.c linux-libre-3.2.47-gnu1/drivers/usb/serial/qcserial.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/qcserial.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/qcserial.c	2013-06-18 21:17:03.000000000 -0400
@@ -115,6 +115,7 @@ static const struct usb_device_id id_tab
 	{USB_DEVICE(0x1199, 0x9019)},	/* Sierra Wireless Gobi 3000 Modem device */
 	{USB_DEVICE(0x12D1, 0x14F0)},	/* Sony Gobi 3000 QDL */
 	{USB_DEVICE(0x12D1, 0x14F1)},	/* Sony Gobi 3000 Composite */
+	{USB_DEVICE(0x0AF0, 0x8120)},	/* Option GTM681W */
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/spcp8x5.c linux-libre-3.2.47-gnu1/drivers/usb/serial/spcp8x5.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/spcp8x5.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/spcp8x5.c	2013-06-18 21:17:03.000000000 -0400
@@ -338,7 +338,6 @@ static void spcp8x5_set_termios(struct t
 	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	unsigned int cflag = tty->termios->c_cflag;
-	unsigned int old_cflag = old_termios->c_cflag;
 	unsigned short uartdata;
 	unsigned char buf[2] = {0, 0};
 	int baud;
@@ -347,15 +346,15 @@ static void spcp8x5_set_termios(struct t
 
 
 	/* check that they really want us to change something */
-	if (!tty_termios_hw_change(tty->termios, old_termios))
+	if (old_termios && !tty_termios_hw_change(tty->termios, old_termios))
 		return;
 
 	/* set DTR/RTS active */
 	spin_lock_irqsave(&priv->lock, flags);
 	control = priv->line_control;
-	if ((old_cflag & CBAUD) == B0) {
+	if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
 		priv->line_control |= MCR_DTR;
-		if (!(old_cflag & CRTSCTS))
+		if (!(old_termios->c_cflag & CRTSCTS))
 			priv->line_control |= MCR_RTS;
 	}
 	if (control != priv->line_control) {
@@ -445,7 +444,6 @@ static void spcp8x5_set_termios(struct t
  * status of the device. */
 static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
 	int ret;
@@ -468,7 +466,7 @@ static int spcp8x5_open(struct tty_struc
 
 	/* Setup termios */
 	if (tty)
-		spcp8x5_set_termios(tty, port, &tmp_termios);
+		spcp8x5_set_termios(tty, port, NULL);
 
 	spcp8x5_get_msr(serial->dev, &status, priv->type);
 
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/visor.c linux-libre-3.2.47-gnu1/drivers/usb/serial/visor.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/visor.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/visor.c	2013-06-18 21:17:03.000000000 -0400
@@ -599,7 +599,9 @@ static int treo_attach(struct usb_serial
 		dest->read_urb = src->read_urb;				\
 		dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
 		dest->bulk_in_buffer = src->bulk_in_buffer;		\
+		dest->bulk_in_size = src->bulk_in_size;			\
 		dest->interrupt_in_urb = src->interrupt_in_urb;		\
+		dest->interrupt_in_urb->context = dest;			\
 		dest->interrupt_in_endpointAddress = \
 					src->interrupt_in_endpointAddress;\
 		dest->interrupt_in_buffer = src->interrupt_in_buffer;	\
diff -druNp linux-libre-3.2.46-gnu1/drivers/usb/serial/whiteheat.c linux-libre-3.2.47-gnu1/drivers/usb/serial/whiteheat.c
--- linux-libre-3.2.46-gnu1/drivers/usb/serial/whiteheat.c	2013-05-31 10:28:00.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/usb/serial/whiteheat.c	2013-06-19 00:46:14.000000000 -0400
@@ -1209,7 +1209,7 @@ static void firm_setup_port(struct tty_s
 	struct whiteheat_port_settings port_settings;
 	unsigned int cflag = tty->termios->c_cflag;
 
-	port_settings.port = port->number + 1;
+	port_settings.port = port->number - port->serial->minor + 1;
 
 	/* get the byte size */
 	switch (cflag & CSIZE) {
diff -druNp linux-libre-3.2.46-gnu1/drivers/xen/events.c linux-libre-3.2.47-gnu1/drivers/xen/events.c
--- linux-libre-3.2.46-gnu1/drivers/xen/events.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/drivers/xen/events.c	2013-06-18 21:17:03.000000000 -0400
@@ -1176,7 +1176,7 @@ static void __xen_evtchn_do_upcall(void)
 {
 	int start_word_idx, start_bit_idx;
 	int word_idx, bit_idx;
-	int i;
+	int i, irq;
 	int cpu = get_cpu();
 	struct shared_info *s = HYPERVISOR_shared_info;
 	struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
@@ -1184,6 +1184,8 @@ static void __xen_evtchn_do_upcall(void)
 
 	do {
 		unsigned long pending_words;
+		unsigned long pending_bits;
+		struct irq_desc *desc;
 
 		vcpu_info->evtchn_upcall_pending = 0;
 
@@ -1194,6 +1196,17 @@ static void __xen_evtchn_do_upcall(void)
 		/* Clear master flag /before/ clearing selector flag. */
 		wmb();
 #endif
+		if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) {
+			int evtchn = evtchn_from_irq(irq);
+			word_idx = evtchn / BITS_PER_LONG;
+			pending_bits = evtchn % BITS_PER_LONG;
+			if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) {
+				desc = irq_to_desc(irq);
+				if (desc)
+					generic_handle_irq_desc(irq, desc);
+			}
+		}
+
 		pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
 
 		start_word_idx = __this_cpu_read(current_word_idx);
@@ -1202,7 +1215,6 @@ static void __xen_evtchn_do_upcall(void)
 		word_idx = start_word_idx;
 
 		for (i = 0; pending_words != 0; i++) {
-			unsigned long pending_bits;
 			unsigned long words;
 
 			words = MASK_LSBS(pending_words, word_idx);
@@ -1231,8 +1243,7 @@ static void __xen_evtchn_do_upcall(void)
 
 			do {
 				unsigned long bits;
-				int port, irq;
-				struct irq_desc *desc;
+				int port;
 
 				bits = MASK_LSBS(pending_bits, bit_idx);
 
diff -druNp linux-libre-3.2.46-gnu1/fs/cifs/cifs_dfs_ref.c linux-libre-3.2.47-gnu1/fs/cifs/cifs_dfs_ref.c
--- linux-libre-3.2.46-gnu1/fs/cifs/cifs_dfs_ref.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/fs/cifs/cifs_dfs_ref.c	2013-06-18 21:17:03.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/vfs.h>
 #include <linux/fs.h>
+#include <linux/inet.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifsfs.h"
@@ -150,7 +151,8 @@ char *cifs_compose_mount_options(const c
 	 * assuming that we have 'unc=' and 'ip=' in
 	 * the original sb_mountdata
 	 */
-	md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12;
+	md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12 +
+			INET6_ADDRSTRLEN;
 	mountdata = kzalloc(md_len+1, GFP_KERNEL);
 	if (mountdata == NULL) {
 		rc = -ENOMEM;
diff -druNp linux-libre-3.2.46-gnu1/fs/ext4/super.c linux-libre-3.2.47-gnu1/fs/ext4/super.c
--- linux-libre-3.2.46-gnu1/fs/ext4/super.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/fs/ext4/super.c	2013-06-18 21:17:03.000000000 -0400
@@ -2260,7 +2260,9 @@ static void ext4_orphan_cleanup(struct s
 				__func__, inode->i_ino, inode->i_size);
 			jbd_debug(2, "truncating inode %lu to %lld bytes\n",
 				  inode->i_ino, inode->i_size);
+			mutex_lock(&inode->i_mutex);
 			ext4_truncate(inode);
+			mutex_unlock(&inode->i_mutex);
 			nr_truncates++;
 		} else {
 			ext4_msg(sb, KERN_DEBUG,
diff -druNp linux-libre-3.2.46-gnu1/fs/jfs/inode.c linux-libre-3.2.47-gnu1/fs/jfs/inode.c
--- linux-libre-3.2.46-gnu1/fs/jfs/inode.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/fs/jfs/inode.c	2013-06-18 21:17:03.000000000 -0400
@@ -125,7 +125,7 @@ int jfs_write_inode(struct inode *inode,
 {
 	int wait = wbc->sync_mode == WB_SYNC_ALL;
 
-	if (test_cflag(COMMIT_Nolink, inode))
+	if (inode->i_nlink == 0)
 		return 0;
 	/*
 	 * If COMMIT_DIRTY is not set, the inode isn't really dirty.
diff -druNp linux-libre-3.2.46-gnu1/fs/jfs/jfs_logmgr.c linux-libre-3.2.47-gnu1/fs/jfs/jfs_logmgr.c
--- linux-libre-3.2.46-gnu1/fs/jfs/jfs_logmgr.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/fs/jfs/jfs_logmgr.c	2013-06-18 21:17:03.000000000 -0400
@@ -1058,7 +1058,8 @@ static int lmLogSync(struct jfs_log * lo
  */
 void jfs_syncpt(struct jfs_log *log, int hard_sync)
 {	LOG_LOCK(log);
-	lmLogSync(log, hard_sync);
+	if (!test_bit(log_QUIESCE, &log->flag))
+		lmLogSync(log, hard_sync);
 	LOG_UNLOCK(log);
 }
 
diff -druNp linux-libre-3.2.46-gnu1/fs/xfs/xfs_iops.c linux-libre-3.2.47-gnu1/fs/xfs/xfs_iops.c
--- linux-libre-3.2.46-gnu1/fs/xfs/xfs_iops.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/fs/xfs/xfs_iops.c	2013-06-18 21:17:03.000000000 -0400
@@ -507,6 +507,28 @@ xfs_vn_getattr(
 	return 0;
 }
 
+static void
+xfs_setattr_mode(
+	struct xfs_trans	*tp,
+	struct xfs_inode	*ip,
+	struct iattr		*iattr)
+{
+	struct inode	*inode = VFS_I(ip);
+	umode_t		mode = iattr->ia_mode;
+
+	ASSERT(tp);
+	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+	if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+		mode &= ~S_ISGID;
+
+	ip->i_d.di_mode &= S_IFMT;
+	ip->i_d.di_mode |= mode & ~S_IFMT;
+
+	inode->i_mode &= S_IFMT;
+	inode->i_mode |= mode & ~S_IFMT;
+}
+
 int
 xfs_setattr_nonsize(
 	struct xfs_inode	*ip,
@@ -658,18 +680,8 @@ xfs_setattr_nonsize(
 	/*
 	 * Change file access modes.
 	 */
-	if (mask & ATTR_MODE) {
-		umode_t mode = iattr->ia_mode;
-
-		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
-			mode &= ~S_ISGID;
-
-		ip->i_d.di_mode &= S_IFMT;
-		ip->i_d.di_mode |= mode & ~S_IFMT;
-
-		inode->i_mode &= S_IFMT;
-		inode->i_mode |= mode & ~S_IFMT;
-	}
+	if (mask & ATTR_MODE)
+		xfs_setattr_mode(tp, ip, iattr);
 
 	/*
 	 * Change file access or modified times.
@@ -768,9 +780,8 @@ xfs_setattr_size(
 		return XFS_ERROR(error);
 
 	ASSERT(S_ISREG(ip->i_d.di_mode));
-	ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
-			ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID|
-			ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
+	ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
+			ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
 
 	lock_flags = XFS_ILOCK_EXCL;
 	if (!(flags & XFS_ATTR_NOLOCK))
@@ -902,6 +913,12 @@ xfs_setattr_size(
 		xfs_iflags_set(ip, XFS_ITRUNCATED);
 	}
 
+	/*
+	 * Change file access modes.
+	 */
+	if (mask & ATTR_MODE)
+		xfs_setattr_mode(tp, ip, iattr);
+
 	if (mask & ATTR_CTIME) {
 		inode->i_ctime = iattr->ia_ctime;
 		ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
diff -druNp linux-libre-3.2.46-gnu1/include/linux/cpu.h linux-libre-3.2.47-gnu1/include/linux/cpu.h
--- linux-libre-3.2.46-gnu1/include/linux/cpu.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/include/linux/cpu.h	2013-06-18 21:17:03.000000000 -0400
@@ -168,6 +168,8 @@ extern struct sysdev_class cpu_sysdev_cl
 
 extern void get_online_cpus(void);
 extern void put_online_cpus(void);
+extern void cpu_hotplug_disable(void);
+extern void cpu_hotplug_enable(void);
 #define hotcpu_notifier(fn, pri)	cpu_notifier(fn, pri)
 #define register_hotcpu_notifier(nb)	register_cpu_notifier(nb)
 #define unregister_hotcpu_notifier(nb)	unregister_cpu_notifier(nb)
@@ -190,6 +192,8 @@ static inline void cpu_hotplug_driver_un
 
 #define get_online_cpus()	do { } while (0)
 #define put_online_cpus()	do { } while (0)
+#define cpu_hotplug_disable()	do { } while (0)
+#define cpu_hotplug_enable()	do { } while (0)
 #define hotcpu_notifier(fn, pri)	do { (void)(fn); } while (0)
 /* These aren't inline functions due to a GCC bug. */
 #define register_hotcpu_notifier(nb)	({ (void)(nb); 0; })
diff -druNp linux-libre-3.2.46-gnu1/include/linux/net.h linux-libre-3.2.47-gnu1/include/linux/net.h
--- linux-libre-3.2.46-gnu1/include/linux/net.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/include/linux/net.h	2013-06-18 21:17:03.000000000 -0400
@@ -249,6 +249,29 @@ extern struct socket *sockfd_lookup(int
 #define		     sockfd_put(sock) fput(sock->file)
 extern int	     net_ratelimit(void);
 
+#define net_ratelimited_function(function, ...)			\
+do {								\
+	if (net_ratelimit())					\
+		function(__VA_ARGS__);				\
+} while (0)
+
+#define net_emerg_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_emerg, fmt, ##__VA_ARGS__)
+#define net_alert_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_alert, fmt, ##__VA_ARGS__)
+#define net_crit_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_crit, fmt, ##__VA_ARGS__)
+#define net_err_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_err, fmt, ##__VA_ARGS__)
+#define net_notice_ratelimited(fmt, ...)			\
+	net_ratelimited_function(pr_notice, fmt, ##__VA_ARGS__)
+#define net_warn_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__)
+#define net_info_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__)
+#define net_dbg_ratelimited(fmt, ...)				\
+	net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__)
+
 #define net_random()		random32()
 #define net_srandom(seed)	srandom32((__force u32)seed)
 
diff -druNp linux-libre-3.2.46-gnu1/include/linux/swapops.h linux-libre-3.2.47-gnu1/include/linux/swapops.h
--- linux-libre-3.2.46-gnu1/include/linux/swapops.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/include/linux/swapops.h	2013-06-18 21:17:03.000000000 -0400
@@ -136,6 +136,7 @@ static inline void make_migration_entry_
 
 extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
 					unsigned long address);
+extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte);
 #else
 
 #define make_migration_entry(page, write) swp_entry(0, 0)
@@ -147,6 +148,8 @@ static inline int is_migration_entry(swp
 static inline void make_migration_entry_read(swp_entry_t *entryp) { }
 static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
 					 unsigned long address) { }
+static inline void migration_entry_wait_huge(struct mm_struct *mm,
+					pte_t *pte) { }
 static inline int is_write_migration_entry(swp_entry_t entry)
 {
 	return 0;
diff -druNp linux-libre-3.2.46-gnu1/include/xen/interface/io/netif.h linux-libre-3.2.47-gnu1/include/xen/interface/io/netif.h
--- linux-libre-3.2.46-gnu1/include/xen/interface/io/netif.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/include/xen/interface/io/netif.h	2013-06-18 21:17:03.000000000 -0400
@@ -13,6 +13,24 @@
 #include "../grant_table.h"
 
 /*
+ * Older implementation of Xen network frontend / backend has an
+ * implicit dependency on the MAX_SKB_FRAGS as the maximum number of
+ * ring slots a skb can use. Netfront / netback may not work as
+ * expected when frontend and backend have different MAX_SKB_FRAGS.
+ *
+ * A better approach is to add mechanism for netfront / netback to
+ * negotiate this value. However we cannot fix all possible
+ * frontends, so we need to define a value which states the minimum
+ * slots backend must support.
+ *
+ * The minimum value derives from older Linux kernel's MAX_SKB_FRAGS
+ * (18), which is proved to work with most frontends. Any new backend
+ * which doesn't negotiate with frontend should expect frontend to
+ * send a valid packet using slots up to this value.
+ */
+#define XEN_NETIF_NR_SLOTS_MIN 18
+
+/*
  * Notifications after enqueuing any type of message should be conditional on
  * the appropriate req_event or rsp_event field in the shared ring.
  * If the client sends notification for rx requests then it should specify
@@ -47,6 +65,7 @@
 #define _XEN_NETTXF_extra_info		(3)
 #define  XEN_NETTXF_extra_info		(1U<<_XEN_NETTXF_extra_info)
 
+#define XEN_NETIF_MAX_TX_SIZE 0xFFFF
 struct xen_netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
     uint16_t offset;       /* Offset within buffer page */
diff -druNp linux-libre-3.2.46-gnu1/kernel/audit.c linux-libre-3.2.47-gnu1/kernel/audit.c
--- linux-libre-3.2.46-gnu1/kernel/audit.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/kernel/audit.c	2013-06-18 21:17:03.000000000 -0400
@@ -1167,7 +1167,7 @@ struct audit_buffer *audit_log_start(str
 
 			/* Wait for auditd to drain the queue a little */
 			DECLARE_WAITQUEUE(wait, current);
-			set_current_state(TASK_INTERRUPTIBLE);
+			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&audit_backlog_wait, &wait);
 
 			if (audit_backlog_limit &&
diff -druNp linux-libre-3.2.46-gnu1/kernel/cpu.c linux-libre-3.2.47-gnu1/kernel/cpu.c
--- linux-libre-3.2.46-gnu1/kernel/cpu.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/kernel/cpu.c	2013-06-18 21:17:03.000000000 -0400
@@ -124,6 +124,27 @@ static void cpu_hotplug_done(void)
 	mutex_unlock(&cpu_hotplug.lock);
 }
 
+/*
+ * Wait for currently running CPU hotplug operations to complete (if any) and
+ * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
+ * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
+ * hotplug path before performing hotplug operations. So acquiring that lock
+ * guarantees mutual exclusion from any currently running hotplug operations.
+ */
+void cpu_hotplug_disable(void)
+{
+	cpu_maps_update_begin();
+	cpu_hotplug_disabled = 1;
+	cpu_maps_update_done();
+}
+
+void cpu_hotplug_enable(void)
+{
+	cpu_maps_update_begin();
+	cpu_hotplug_disabled = 0;
+	cpu_maps_update_done();
+}
+
 #else /* #if CONFIG_HOTPLUG_CPU */
 static void cpu_hotplug_begin(void) {}
 static void cpu_hotplug_done(void) {}
@@ -479,36 +500,6 @@ static int alloc_frozen_cpus(void)
 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
@@ -527,12 +518,12 @@ cpu_hotplug_pm_callback(struct notifier_
 
 	case PM_SUSPEND_PREPARE:
 	case PM_HIBERNATION_PREPARE:
-		cpu_hotplug_disable_before_freeze();
+		cpu_hotplug_disable();
 		break;
 
 	case PM_POST_SUSPEND:
 	case PM_POST_HIBERNATION:
-		cpu_hotplug_enable_after_thaw();
+		cpu_hotplug_enable();
 		break;
 
 	default:
diff -druNp linux-libre-3.2.46-gnu1/kernel/sys.c linux-libre-3.2.47-gnu1/kernel/sys.c
--- linux-libre-3.2.46-gnu1/kernel/sys.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/kernel/sys.c	2013-06-18 21:17:03.000000000 -0400
@@ -353,6 +353,29 @@ int unregister_reboot_notifier(struct no
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
+/* Add backwards compatibility for stable trees. */
+#ifndef PF_NO_SETAFFINITY
+#define PF_NO_SETAFFINITY		PF_THREAD_BOUND
+#endif
+
+static void migrate_to_reboot_cpu(void)
+{
+	/* The boot cpu is always logical cpu 0 */
+	int cpu = 0;
+
+	cpu_hotplug_disable();
+
+	/* Make certain the cpu I'm about to reboot on is online */
+	if (!cpu_online(cpu))
+		cpu = cpumask_first(cpu_online_mask);
+
+	/* Prevent races with other tasks migrating this task */
+	current->flags |= PF_NO_SETAFFINITY;
+
+	/* Make certain I only run on the appropriate processor */
+	set_cpus_allowed_ptr(current, cpumask_of(cpu));
+}
+
 /**
  *	kernel_restart - reboot the system
  *	@cmd: pointer to buffer containing command to execute for restart
@@ -364,7 +387,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier
 void kernel_restart(char *cmd)
 {
 	kernel_restart_prepare(cmd);
-	disable_nonboot_cpus();
+	migrate_to_reboot_cpu();
 	syscore_shutdown();
 	if (!cmd)
 		printk(KERN_EMERG "Restarting system.\n");
@@ -391,7 +414,7 @@ static void kernel_shutdown_prepare(enum
 void kernel_halt(void)
 {
 	kernel_shutdown_prepare(SYSTEM_HALT);
-	disable_nonboot_cpus();
+	migrate_to_reboot_cpu();
 	syscore_shutdown();
 	printk(KERN_EMERG "System halted.\n");
 	kmsg_dump(KMSG_DUMP_HALT);
@@ -410,7 +433,7 @@ void kernel_power_off(void)
 	kernel_shutdown_prepare(SYSTEM_POWER_OFF);
 	if (pm_power_off_prepare)
 		pm_power_off_prepare();
-	disable_nonboot_cpus();
+	migrate_to_reboot_cpu();
 	syscore_shutdown();
 	printk(KERN_EMERG "Power down.\n");
 	kmsg_dump(KMSG_DUMP_POWEROFF);
diff -druNp linux-libre-3.2.46-gnu1/kernel/trace/ftrace.c linux-libre-3.2.47-gnu1/kernel/trace/ftrace.c
--- linux-libre-3.2.46-gnu1/kernel/trace/ftrace.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/kernel/trace/ftrace.c	2013-06-18 21:17:03.000000000 -0400
@@ -929,6 +929,19 @@ static __init void ftrace_profile_debugf
 
 static struct pid * const ftrace_swapper_pid = &init_struct_pid;
 
+static loff_t
+ftrace_filter_lseek(struct file *file, loff_t offset, int whence)
+{
+	loff_t ret;
+
+	if (file->f_mode & FMODE_READ)
+		ret = seq_lseek(file, offset, whence);
+	else
+		file->f_pos = ret = 1;
+
+	return ret;
+}
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 #ifndef CONFIG_FTRACE_MCOUNT_RECORD
@@ -2315,19 +2328,6 @@ ftrace_notrace_open(struct inode *inode,
 				 inode, file);
 }
 
-static loff_t
-ftrace_filter_lseek(struct file *file, loff_t offset, int origin)
-{
-	loff_t ret;
-
-	if (file->f_mode & FMODE_READ)
-		ret = seq_lseek(file, offset, origin);
-	else
-		file->f_pos = ret = 1;
-
-	return ret;
-}
-
 static int ftrace_match(char *str, char *regex, int len, int type)
 {
 	int matched = 0;
diff -druNp linux-libre-3.2.46-gnu1/Makefile linux-libre-3.2.47-gnu1/Makefile
--- linux-libre-3.2.46-gnu1/Makefile	2013-05-31 10:17:15.000000000 -0400
+++ linux-libre-3.2.47-gnu1/Makefile	2013-06-19 00:35:31.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 46
+SUBLEVEL = 47
 EXTRAVERSION =-gnu1
 NAME = Saber-toothed Squirrel
 
diff -druNp linux-libre-3.2.46-gnu1/mm/hugetlb.c linux-libre-3.2.47-gnu1/mm/hugetlb.c
--- linux-libre-3.2.46-gnu1/mm/hugetlb.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/mm/hugetlb.c	2013-06-18 21:17:03.000000000 -0400
@@ -2751,7 +2751,7 @@ int hugetlb_fault(struct mm_struct *mm,
 	if (ptep) {
 		entry = huge_ptep_get(ptep);
 		if (unlikely(is_hugetlb_entry_migration(entry))) {
-			migration_entry_wait(mm, (pmd_t *)ptep, address);
+			migration_entry_wait_huge(mm, ptep);
 			return 0;
 		} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
 			return VM_FAULT_HWPOISON_LARGE |
diff -druNp linux-libre-3.2.46-gnu1/mm/migrate.c linux-libre-3.2.47-gnu1/mm/migrate.c
--- linux-libre-3.2.46-gnu1/mm/migrate.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/mm/migrate.c	2013-06-18 21:17:03.000000000 -0400
@@ -184,15 +184,14 @@ static void remove_migration_ptes(struct
  *
  * This function is called from do_swap_page().
  */
-void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
-				unsigned long address)
+static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
+				spinlock_t *ptl)
 {
-	pte_t *ptep, pte;
-	spinlock_t *ptl;
+	pte_t pte;
 	swp_entry_t entry;
 	struct page *page;
 
-	ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
+	spin_lock(ptl);
 	pte = *ptep;
 	if (!is_swap_pte(pte))
 		goto out;
@@ -220,6 +219,20 @@ out:
 	pte_unmap_unlock(ptep, ptl);
 }
 
+void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+				unsigned long address)
+{
+	spinlock_t *ptl = pte_lockptr(mm, pmd);
+	pte_t *ptep = pte_offset_map(pmd, address);
+	__migration_entry_wait(mm, ptep, ptl);
+}
+
+void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte)
+{
+	spinlock_t *ptl = &(mm)->page_table_lock;
+	__migration_entry_wait(mm, pte, ptl);
+}
+
 #ifdef CONFIG_BLOCK
 /* Returns true if all buffers are successfully locked */
 static bool buffer_migrate_lock_buffers(struct buffer_head *head,
diff -druNp linux-libre-3.2.46-gnu1/mm/swap_state.c linux-libre-3.2.47-gnu1/mm/swap_state.c
--- linux-libre-3.2.46-gnu1/mm/swap_state.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/mm/swap_state.c	2013-06-18 21:17:03.000000000 -0400
@@ -314,8 +314,24 @@ struct page *read_swap_cache_async(swp_e
 		 * Swap entry may have been freed since our caller observed it.
 		 */
 		err = swapcache_prepare(entry);
-		if (err == -EEXIST) {	/* seems racy */
+		if (err == -EEXIST) {
 			radix_tree_preload_end();
+			/*
+			 * We might race against get_swap_page() and stumble
+			 * across a SWAP_HAS_CACHE swap_map entry whose page
+			 * has not been brought into the swapcache yet, while
+			 * the other end is scheduled away waiting on discard
+			 * I/O completion at scan_swap_map().
+			 *
+			 * In order to avoid turning this transitory state
+			 * into a permanent loop around this -EEXIST case
+			 * if !CONFIG_PREEMPT and the I/O completion happens
+			 * to be waiting on the CPU waitqueue where we are now
+			 * busy looping, we just conditionally invoke the
+			 * scheduler here, if there are some more important
+			 * tasks to run.
+			 */
+			cond_resched();
 			continue;
 		}
 		if (err) {		/* swp entry is obsolete ? */
diff -druNp linux-libre-3.2.46-gnu1/net/bluetooth/l2cap_core.c linux-libre-3.2.47-gnu1/net/bluetooth/l2cap_core.c
--- linux-libre-3.2.46-gnu1/net/bluetooth/l2cap_core.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/net/bluetooth/l2cap_core.c	2013-06-18 21:17:03.000000000 -0400
@@ -2297,10 +2297,15 @@ done:
 	}
 }
 
-static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_command_rej(struct l2cap_conn *conn,
+				    struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+				    u8 *data)
 {
 	struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
 
+	if (cmd_len < sizeof(*rej))
+		return -EPROTO;
+
 	if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
 		return 0;
 
@@ -2317,7 +2322,8 @@ static inline int l2cap_command_rej(stru
 	return 0;
 }
 
-static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static int l2cap_connect_req(struct l2cap_conn *conn,
+			     struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
 	struct l2cap_conn_rsp rsp;
@@ -2325,8 +2331,14 @@ static inline int l2cap_connect_req(stru
 	struct sock *parent, *sk = NULL;
 	int result, status = L2CAP_CS_NO_INFO;
 
-	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-	__le16 psm = req->psm;
+	u16 dcid = 0, scid;
+	__le16 psm;
+
+	if (cmd_len < sizeof(struct l2cap_conn_req))
+		return -EPROTO;
+
+	scid = __le16_to_cpu(req->scid);
+	psm = req->psm;
 
 	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
 
@@ -2451,7 +2463,9 @@ sendresp:
 	return 0;
 }
 
-static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static int l2cap_connect_rsp(struct l2cap_conn *conn,
+			      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+			      u8 *data)
 {
 	struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
 	u16 scid, dcid, result, status;
@@ -2459,6 +2473,9 @@ static inline int l2cap_connect_rsp(stru
 	struct sock *sk;
 	u8 req[128];
 
+	if (cmd_len < sizeof(*rsp))
+		return -EPROTO;
+
 	scid   = __le16_to_cpu(rsp->scid);
 	dcid   = __le16_to_cpu(rsp->dcid);
 	result = __le16_to_cpu(rsp->result);
@@ -2534,6 +2551,9 @@ static inline int l2cap_config_req(struc
 	struct sock *sk;
 	int len;
 
+	if (cmd_len < sizeof(*req))
+		return -EPROTO;
+
 	dcid  = __le16_to_cpu(req->dcid);
 	flags = __le16_to_cpu(req->flags);
 
@@ -2559,7 +2579,7 @@ static inline int l2cap_config_req(struc
 
 	/* Reject if config buffer is too small. */
 	len = cmd_len - sizeof(*req);
-	if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
+	if (chan->conf_len + len > sizeof(chan->conf_req)) {
 		l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
 				l2cap_build_conf_rsp(chan, rsp,
 					L2CAP_CONF_REJECT, flags), rsp);
@@ -2621,13 +2641,18 @@ unlock:
 	return 0;
 }
 
-static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_config_rsp(struct l2cap_conn *conn,
+				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+				   u8 *data)
 {
 	struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
 	u16 scid, flags, result;
 	struct l2cap_chan *chan;
 	struct sock *sk;
-	int len = cmd->len - sizeof(*rsp);
+	int len = cmd_len - sizeof(*rsp);
+
+	if (cmd_len < sizeof(*rsp))
+		return -EPROTO;
 
 	scid   = __le16_to_cpu(rsp->scid);
 	flags  = __le16_to_cpu(rsp->flags);
@@ -2703,7 +2728,9 @@ done:
 	return 0;
 }
 
-static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
+				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+				       u8 *data)
 {
 	struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
 	struct l2cap_disconn_rsp rsp;
@@ -2711,6 +2738,9 @@ static inline int l2cap_disconnect_req(s
 	struct l2cap_chan *chan;
 	struct sock *sk;
 
+	if (cmd_len != sizeof(*req))
+		return -EPROTO;
+
 	scid = __le16_to_cpu(req->scid);
 	dcid = __le16_to_cpu(req->dcid);
 
@@ -2744,13 +2774,18 @@ static inline int l2cap_disconnect_req(s
 	return 0;
 }
 
-static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
+				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+				       u8 *data)
 {
 	struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
 	u16 dcid, scid;
 	struct l2cap_chan *chan;
 	struct sock *sk;
 
+	if (cmd_len != sizeof(*rsp))
+		return -EPROTO;
+
 	scid = __le16_to_cpu(rsp->scid);
 	dcid = __le16_to_cpu(rsp->dcid);
 
@@ -2778,11 +2813,16 @@ static inline int l2cap_disconnect_rsp(s
 	return 0;
 }
 
-static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_information_req(struct l2cap_conn *conn,
+					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+					u8 *data)
 {
 	struct l2cap_info_req *req = (struct l2cap_info_req *) data;
 	u16 type;
 
+	if (cmd_len != sizeof(*req))
+		return -EPROTO;
+
 	type = __le16_to_cpu(req->type);
 
 	BT_DBG("type 0x%4.4x", type);
@@ -2818,11 +2858,16 @@ static inline int l2cap_information_req(
 	return 0;
 }
 
-static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_information_rsp(struct l2cap_conn *conn,
+					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+					u8 *data)
 {
 	struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
 	u16 type, result;
 
+	if (cmd_len != sizeof(*rsp))
+		return -EPROTO;
+
 	type   = __le16_to_cpu(rsp->type);
 	result = __le16_to_cpu(rsp->result);
 
@@ -2941,15 +2986,15 @@ static inline int l2cap_bredr_sig_cmd(st
 
 	switch (cmd->code) {
 	case L2CAP_COMMAND_REJ:
-		l2cap_command_rej(conn, cmd, data);
+		l2cap_command_rej(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_CONN_REQ:
-		err = l2cap_connect_req(conn, cmd, data);
+		err = l2cap_connect_req(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_CONN_RSP:
-		err = l2cap_connect_rsp(conn, cmd, data);
+		err = l2cap_connect_rsp(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_CONF_REQ:
@@ -2957,15 +3002,15 @@ static inline int l2cap_bredr_sig_cmd(st
 		break;
 
 	case L2CAP_CONF_RSP:
-		err = l2cap_config_rsp(conn, cmd, data);
+		err = l2cap_config_rsp(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_DISCONN_REQ:
-		err = l2cap_disconnect_req(conn, cmd, data);
+		err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_DISCONN_RSP:
-		err = l2cap_disconnect_rsp(conn, cmd, data);
+		err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_ECHO_REQ:
@@ -2976,11 +3021,11 @@ static inline int l2cap_bredr_sig_cmd(st
 		break;
 
 	case L2CAP_INFO_REQ:
-		err = l2cap_information_req(conn, cmd, data);
+		err = l2cap_information_req(conn, cmd, cmd_len, data);
 		break;
 
 	case L2CAP_INFO_RSP:
-		err = l2cap_information_rsp(conn, cmd, data);
+		err = l2cap_information_rsp(conn, cmd, cmd_len, data);
 		break;
 
 	default:
diff -druNp linux-libre-3.2.46-gnu1/net/mac80211/iface.c linux-libre-3.2.47-gnu1/net/mac80211/iface.c
--- linux-libre-3.2.46-gnu1/net/mac80211/iface.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/net/mac80211/iface.c	2013-06-18 21:17:03.000000000 -0400
@@ -1242,6 +1242,15 @@ void ieee80211_remove_interfaces(struct
 
 	ASSERT_RTNL();
 
+	/*
+	 * Close all AP_VLAN interfaces first, as otherwise they
+	 * might be closed while the AP interface they belong to
+	 * is closed, causing unregister_netdevice_many() to crash.
+	 */
+	list_for_each_entry(sdata, &local->interfaces, list)
+		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+			dev_close(sdata->dev);
+
 	mutex_lock(&local->iflist_mtx);
 	list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
 		list_del(&sdata->list);
diff -druNp linux-libre-3.2.46-gnu1/net/wireless/sme.c linux-libre-3.2.47-gnu1/net/wireless/sme.c
--- linux-libre-3.2.46-gnu1/net/wireless/sme.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/net/wireless/sme.c	2013-06-18 21:17:03.000000000 -0400
@@ -220,6 +220,9 @@ void cfg80211_conn_work(struct work_stru
 	mutex_lock(&rdev->devlist_mtx);
 
 	list_for_each_entry(wdev, &rdev->netdev_list, list) {
+		if (!wdev->netdev)
+			continue;
+
 		wdev_lock(wdev);
 		if (!netif_running(wdev->netdev)) {
 			wdev_unlock(wdev);
diff -druNp linux-libre-3.2.46-gnu1/sound/usb/card.h linux-libre-3.2.47-gnu1/sound/usb/card.h
--- linux-libre-3.2.46-gnu1/sound/usb/card.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/sound/usb/card.h	2013-06-18 21:17:03.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef __USBAUDIO_CARD_H
 #define __USBAUDIO_CARD_H
 
+#define MAX_NR_RATES	1024
 #define MAX_PACKS	20
 #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */
 #define MAX_URBS	8
diff -druNp linux-libre-3.2.46-gnu1/sound/usb/format.c linux-libre-3.2.47-gnu1/sound/usb/format.c
--- linux-libre-3.2.46-gnu1/sound/usb/format.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/sound/usb/format.c	2013-06-18 21:17:03.000000000 -0400
@@ -226,7 +226,7 @@ static int parse_uac2_sample_rate_range(
 		int min = combine_quad(&data[2 + 12 * i]);
 		int max = combine_quad(&data[6 + 12 * i]);
 		int res = combine_quad(&data[10 + 12 * i]);
-		int rate;
+		unsigned int rate;
 
 		if ((max < 0) || (min < 0) || (res < 0) || (max < min))
 			continue;
@@ -253,6 +253,10 @@ static int parse_uac2_sample_rate_range(
 			fp->rates |= snd_pcm_rate_to_rate_bit(rate);
 
 			nr_rates++;
+			if (nr_rates >= MAX_NR_RATES) {
+				snd_printk(KERN_ERR "invalid uac2 rates\n");
+				break;
+			}
 
 			/* avoid endless loop */
 			if (res == 0)
diff -druNp linux-libre-3.2.46-gnu1/sound/usb/mixer.c linux-libre-3.2.47-gnu1/sound/usb/mixer.c
--- linux-libre-3.2.46-gnu1/sound/usb/mixer.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/sound/usb/mixer.c	2013-06-18 21:17:03.000000000 -0400
@@ -822,6 +822,7 @@ static void volume_control_quirks(struct
 	case USB_ID(0x046d, 0x0808):
 	case USB_ID(0x046d, 0x0809):
 	case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
+	case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
 	case USB_ID(0x046d, 0x0991):
 	/* Most audio usb devices lie about volume resolution.
 	 * Most Logitech webcams have res = 384.
diff -druNp linux-libre-3.2.46-gnu1/sound/usb/quirks.c linux-libre-3.2.47-gnu1/sound/usb/quirks.c
--- linux-libre-3.2.46-gnu1/sound/usb/quirks.c	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/sound/usb/quirks.c	2013-06-18 21:17:03.000000000 -0400
@@ -132,10 +132,14 @@ static int create_fixed_stream_quirk(str
 	unsigned *rate_table = NULL;
 
 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
-	if (! fp) {
+	if (!fp) {
 		snd_printk(KERN_ERR "cannot memdup\n");
 		return -ENOMEM;
 	}
+	if (fp->nr_rates > MAX_NR_RATES) {
+		kfree(fp);
+		return -EINVAL;
+	}
 	if (fp->nr_rates > 0) {
 		rate_table = kmemdup(fp->rate_table,
 				     sizeof(int) * fp->nr_rates, GFP_KERNEL);
diff -druNp linux-libre-3.2.46-gnu1/sound/usb/quirks-table.h linux-libre-3.2.47-gnu1/sound/usb/quirks-table.h
--- linux-libre-3.2.46-gnu1/sound/usb/quirks-table.h	2013-05-30 09:35:16.000000000 -0400
+++ linux-libre-3.2.47-gnu1/sound/usb/quirks-table.h	2013-06-18 21:17:03.000000000 -0400
@@ -157,7 +157,13 @@
 	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
 },
 {
-	USB_DEVICE(0x046d, 0x0990),
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+		       USB_DEVICE_ID_MATCH_INT_CLASS |
+		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+	.idVendor = 0x046d,
+	.idProduct = 0x0990,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
 	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Logitech, Inc.",
 		.product_name = "QuickCam Pro 9000",
