diff -druN linux-2.6.39.3-libre/arch/alpha/kernel/osf_sys.c linux-2.6.39.4-libre/arch/alpha/kernel/osf_sys.c
--- linux-2.6.39.3-libre/arch/alpha/kernel/osf_sys.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/alpha/kernel/osf_sys.c	2011-08-03 15:43:28.000000000 -0400
@@ -409,7 +409,7 @@
 		return -EFAULT;
 
 	len = namelen;
-	if (namelen > 32)
+	if (len > 32)
 		len = 32;
 
 	down_read(&uts_sem);
@@ -594,7 +594,7 @@
 	down_read(&uts_sem);
 	res = sysinfo_table[offset];
 	len = strlen(res)+1;
-	if (len > count)
+	if ((unsigned long)len > (unsigned long)count)
 		len = count;
 	if (copy_to_user(buf, res, len))
 		err = -EFAULT;
@@ -649,7 +649,7 @@
 		return 1;
 
 	case GSI_GET_HWRPB:
-		if (nbytes < sizeof(*hwrpb))
+		if (nbytes > sizeof(*hwrpb))
 			return -EINVAL;
 		if (copy_to_user(buffer, hwrpb, nbytes) != 0)
 			return -EFAULT;
@@ -1008,6 +1008,7 @@
 {
 	struct rusage r;
 	long ret, err;
+	unsigned int status = 0;
 	mm_segment_t old_fs;
 
 	if (!ur)
@@ -1016,13 +1017,15 @@
 	old_fs = get_fs();
 		
 	set_fs (KERNEL_DS);
-	ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
+	ret = sys_wait4(pid, (unsigned int __user *) &status, options,
+			(struct rusage __user *) &r);
 	set_fs (old_fs);
 
 	if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
 		return -EFAULT;
 
 	err = 0;
+	err |= put_user(status, ustatus);
 	err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
 	err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
 	err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff -druN linux-2.6.39.3-libre/arch/arm/kernel/perf_event.c linux-2.6.39.4-libre/arch/arm/kernel/perf_event.c
--- linux-2.6.39.3-libre/arch/arm/kernel/perf_event.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/arm/kernel/perf_event.c	2011-08-03 15:43:28.000000000 -0400
@@ -588,7 +588,7 @@
 static void armpmu_enable(struct pmu *pmu)
 {
 	/* Enable all of the perf events on hardware. */
-	int idx;
+	int idx, enabled = 0;
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
 	if (!armpmu)
@@ -601,9 +601,11 @@
 			continue;
 
 		armpmu->enable(&event->hw, idx);
+		enabled = 1;
 	}
 
-	armpmu->start();
+	if (enabled)
+		armpmu->start();
 }
 
 static void armpmu_disable(struct pmu *pmu)
diff -druN linux-2.6.39.3-libre/arch/arm/mach-davinci/board-dm365-evm.c linux-2.6.39.4-libre/arch/arm/mach-davinci/board-dm365-evm.c
--- linux-2.6.39.3-libre/arch/arm/mach-davinci/board-dm365-evm.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/arm/mach-davinci/board-dm365-evm.c	2011-08-03 15:43:28.000000000 -0400
@@ -520,7 +520,7 @@
 	 */
 	if (have_imager()) {
 		label = "HD imager";
-		mux |= 1;
+		mux |= 2;
 
 		/* externally mux MMC1/ENET/AIC33 to imager */
 		mux |= BIT(6) | BIT(5) | BIT(3);
@@ -540,7 +540,7 @@
 		resets &= ~BIT(1);
 
 		if (have_tvp7002()) {
-			mux |= 2;
+			mux |= 1;
 			resets &= ~BIT(2);
 			label = "tvp7002 HD";
 		} else {
diff -druN linux-2.6.39.3-libre/arch/arm/mach-mmp/pxa168.c linux-2.6.39.4-libre/arch/arm/mach-mmp/pxa168.c
--- linux-2.6.39.3-libre/arch/arm/mach-mmp/pxa168.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/arm/mach-mmp/pxa168.c	2011-08-03 15:43:28.000000000 -0400
@@ -79,7 +79,7 @@
 static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
 static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
 
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(lcd, LCD, 0x7f, 312000000);
 
 /* device and clock bindings */
diff -druN linux-2.6.39.3-libre/arch/arm/mach-mmp/pxa910.c linux-2.6.39.4-libre/arch/arm/mach-mmp/pxa910.c
--- linux-2.6.39.3-libre/arch/arm/mach-mmp/pxa910.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/arm/mach-mmp/pxa910.c	2011-08-03 15:43:28.000000000 -0400
@@ -110,7 +110,7 @@
 static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
 
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(u2o, USB, 0x1b, 480000000);
 
 /* device and clock bindings */
diff -druN linux-2.6.39.3-libre/arch/arm/mach-pxa/mfp-pxa2xx.c linux-2.6.39.4-libre/arch/arm/mach-pxa/mfp-pxa2xx.c
--- linux-2.6.39.3-libre/arch/arm/mach-pxa/mfp-pxa2xx.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/arm/mach-pxa/mfp-pxa2xx.c	2011-08-03 15:43:28.000000000 -0400
@@ -347,9 +347,9 @@
 		if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
 		    (GPDR(i) & GPIO_bit(i))) {
 			if (GPLR(i) & GPIO_bit(i))
-				PGSR(i) |= GPIO_bit(i);
+				PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
 			else
-				PGSR(i) &= ~GPIO_bit(i);
+				PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
 		}
 	}
 
diff -druN linux-2.6.39.3-libre/arch/x86/kernel/reboot.c linux-2.6.39.4-libre/arch/x86/kernel/reboot.c
--- linux-2.6.39.3-libre/arch/x86/kernel/reboot.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/arch/x86/kernel/reboot.c	2011-08-03 15:43:28.000000000 -0400
@@ -411,6 +411,14 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
 		},
 	},
+	{	/* Handle problems with rebooting on the Latitude E5420. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E5420",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
+		},
+	},
 	{ }
 };
 
diff -druN linux-2.6.39.3-libre/drivers/ata/libata-eh.c linux-2.6.39.4-libre/drivers/ata/libata-eh.c
--- linux-2.6.39.3-libre/drivers/ata/libata-eh.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/ata/libata-eh.c	2011-08-03 15:43:28.000000000 -0400
@@ -2802,10 +2802,11 @@
 	}
 
 	/*
-	 * Some controllers can't be frozen very well and may set
-	 * spuruious error conditions during reset.  Clear accumulated
-	 * error information.  As reset is the final recovery action,
-	 * nothing is lost by doing this.
+	 * Some controllers can't be frozen very well and may set spurious
+	 * error conditions during reset.  Clear accumulated error
+	 * information and re-thaw the port if frozen.  As reset is the
+	 * final recovery action and we cross check link onlineness against
+	 * device classification later, no hotplug event is lost by this.
 	 */
 	spin_lock_irqsave(link->ap->lock, flags);
 	memset(&link->eh_info, 0, sizeof(link->eh_info));
@@ -2814,6 +2815,9 @@
 	ap->pflags &= ~ATA_PFLAG_EH_PENDING;
 	spin_unlock_irqrestore(link->ap->lock, flags);
 
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		ata_eh_thaw_port(ap);
+
 	/*
 	 * Make sure onlineness and classification result correspond.
 	 * Hotplug could have happened during reset and some
diff -druN linux-2.6.39.3-libre/drivers/firewire/ohci.c linux-2.6.39.4-libre/drivers/firewire/ohci.c
--- linux-2.6.39.3-libre/drivers/firewire/ohci.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/firewire/ohci.c	2011-08-03 15:43:28.000000000 -0400
@@ -264,6 +264,7 @@
 #define PCI_DEVICE_ID_AGERE_FW643	0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW	0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22	0x8009
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS	0x11bd
 
 #define QUIRK_CYCLE_TIMER		1
 #define QUIRK_RESET_PACKET		2
@@ -3170,6 +3171,11 @@
 	int i, err;
 	size_t size;
 
+	if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
+		dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
+		return -ENOSYS;
+	}
+
 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
 	if (ohci == NULL) {
 		err = -ENOMEM;
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/evergreen.c linux-2.6.39.4-libre/drivers/gpu/drm/radeon/evergreen.c
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/evergreen.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/evergreen.c	2011-08-03 15:43:28.000000000 -0400
@@ -960,17 +960,19 @@
 {
 	save->vga_control[0] = RREG32(D1VGA_CONTROL);
 	save->vga_control[1] = RREG32(D2VGA_CONTROL);
-	save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
-	save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
-	save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
-	save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
 	save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
 	save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
 	save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
 	save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
+		save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
+		save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
 		save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
 		save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+	}
+	if (rdev->num_crtc >= 6) {
+		save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
+		save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
 		save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
 		save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
 	}
@@ -979,35 +981,45 @@
 	WREG32(VGA_RENDER_CONTROL, 0);
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
 	}
 	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
 
 	WREG32(D1VGA_CONTROL, 0);
 	WREG32(D2VGA_CONTROL, 0);
-	WREG32(EVERGREEN_D3VGA_CONTROL, 0);
-	WREG32(EVERGREEN_D4VGA_CONTROL, 0);
-	WREG32(EVERGREEN_D5VGA_CONTROL, 0);
-	WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+	if (rdev->num_crtc >= 4) {
+		WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+		WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+		WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+	}
 }
 
 void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1030,7 +1042,7 @@
 	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
 	       (u32)rdev->mc.vram_start);
 
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
 		       upper_32_bits(rdev->mc.vram_start));
 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
@@ -1048,7 +1060,8 @@
 		       (u32)rdev->mc.vram_start);
 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
 		       (u32)rdev->mc.vram_start);
-
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
 		       upper_32_bits(rdev->mc.vram_start));
 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
@@ -1076,31 +1089,41 @@
 	/* Restore video state */
 	WREG32(D1VGA_CONTROL, save->vga_control[0]);
 	WREG32(D2VGA_CONTROL, save->vga_control[1]);
-	WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
-	WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
-	WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
-	WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+	if (rdev->num_crtc >= 4) {
+		WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
+		WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
+		WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+	}
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
 	}
 	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
 	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
 	}
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
@@ -1900,7 +1923,7 @@
 			gb_backend_map = 0x66442200;
 			break;
 		case CHIP_JUNIPER:
-			gb_backend_map = 0x00006420;
+			gb_backend_map = 0x00002200;
 			break;
 		default:
 			gb_backend_map =
@@ -2327,18 +2350,22 @@
 	WREG32(GRBM_INT_CNTL, 0);
 	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
 
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
@@ -2457,19 +2484,25 @@
 
 	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
 	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
 		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
 		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
 	}
 
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+	if (rdev->num_crtc >= 4) {
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+	}
 
 	WREG32(DC_HPD1_INT_CONTROL, hpd1);
 	WREG32(DC_HPD2_INT_CONTROL, hpd2);
@@ -2493,53 +2526,57 @@
 	rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
 	rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
 	rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+	if (rdev->num_crtc >= 4) {
+		rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+		rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+	}
+	if (rdev->num_crtc >= 6) {
+		rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+		rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+	}
 
 	if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
 	if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-
 	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
 		WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
 	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
 		WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
-
 	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
 		WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
 	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)
 		WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
 
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
-
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
-
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+	if (rdev->num_crtc >= 4) {
+		if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
+	}
 
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+	if (rdev->num_crtc >= 6) {
+		if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+	}
 
 	if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
 		tmp = RREG32(DC_HPD1_INT_CONTROL);
@@ -3150,6 +3187,7 @@
 	r700_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	evergreen_pcie_gart_fini(rdev);
 	radeon_gem_fini(rdev);
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/evergreend.h linux-2.6.39.4-libre/drivers/gpu/drm/radeon/evergreend.h
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/evergreend.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/evergreend.h	2011-08-03 15:43:28.000000000 -0400
@@ -460,7 +460,7 @@
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
@@ -541,7 +541,7 @@
 #       define LB_D5_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD5_INTERRUPT                        (1 << 17)
 #       define DC_HPD5_RX_INTERRUPT                     (1 << 18)
-#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6050
+#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6150
 #       define LB_D6_VLINE_INTERRUPT                    (1 << 2)
 #       define LB_D6_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD6_INTERRUPT                        (1 << 17)
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/ni.c linux-2.6.39.4-libre/drivers/gpu/drm/radeon/ni.c
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/ni.c	2011-07-09 23:27:52.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/ni.c	2011-08-04 00:19:20.000000000 -0400
@@ -1543,6 +1543,7 @@
 	cayman_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	cayman_pcie_gart_fini(rdev);
 	radeon_gem_fini(rdev);
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/r600.c linux-2.6.39.4-libre/drivers/gpu/drm/radeon/r600.c
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/r600.c	2011-07-09 23:27:46.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/r600.c	2011-08-04 00:19:15.000000000 -0400
@@ -2577,6 +2577,7 @@
 	r600_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	r600_pcie_gart_fini(rdev);
 	radeon_agp_fini(rdev);
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/r600d.h linux-2.6.39.4-libre/drivers/gpu/drm/radeon/r600d.h
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/r600d.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/r600d.h	2011-08-03 15:43:28.000000000 -0400
@@ -536,7 +536,7 @@
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/radeon_display.c linux-2.6.39.4-libre/drivers/gpu/drm/radeon/radeon_display.c
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/radeon_display.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/radeon_display.c	2011-08-03 15:43:28.000000000 -0400
@@ -264,6 +264,8 @@
 		radeon_bo_unreserve(work->old_rbo);
 	} else
 		DRM_ERROR("failed to reserve buffer after flip\n");
+
+	drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
 	kfree(work);
 }
 
@@ -371,6 +373,8 @@
 	new_radeon_fb = to_radeon_framebuffer(fb);
 	/* schedule unpin of the old buffer */
 	obj = old_radeon_fb->obj;
+	/* take a reference to the old object */
+	drm_gem_object_reference(obj);
 	rbo = gem_to_radeon_bo(obj);
 	work->old_rbo = rbo;
 	INIT_WORK(&work->work, radeon_unpin_work_func);
@@ -378,12 +382,9 @@
 	/* We borrow the event spin lock for protecting unpin_work */
 	spin_lock_irqsave(&dev->event_lock, flags);
 	if (radeon_crtc->unpin_work) {
-		spin_unlock_irqrestore(&dev->event_lock, flags);
-		kfree(work);
-		radeon_fence_unref(&fence);
-
 		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
-		return -EBUSY;
+		r = -EBUSY;
+		goto unlock_free;
 	}
 	radeon_crtc->unpin_work = work;
 	radeon_crtc->deferred_flip_completion = 0;
@@ -497,6 +498,8 @@
 pflip_cleanup:
 	spin_lock_irqsave(&dev->event_lock, flags);
 	radeon_crtc->unpin_work = NULL;
+unlock_free:
+	drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 	radeon_fence_unref(&fence);
 	kfree(work);
diff -druN linux-2.6.39.3-libre/drivers/gpu/drm/radeon/rv770.c linux-2.6.39.4-libre/drivers/gpu/drm/radeon/rv770.c
--- linux-2.6.39.3-libre/drivers/gpu/drm/radeon/rv770.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/gpu/drm/radeon/rv770.c	2011-08-03 15:43:28.000000000 -0400
@@ -1365,6 +1365,7 @@
 	r700_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
 	rv770_vram_scratch_fini(rdev);
diff -druN linux-2.6.39.3-libre/drivers/hwmon/asus_atk0110.c linux-2.6.39.4-libre/drivers/hwmon/asus_atk0110.c
--- linux-2.6.39.3-libre/drivers/hwmon/asus_atk0110.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/asus_atk0110.c	2011-08-03 15:43:28.000000000 -0400
@@ -673,6 +673,7 @@
 	else
 		err = -EIO;
 
+	ACPI_FREE(ret);
 	return err;
 }
 
diff -druN linux-2.6.39.3-libre/drivers/hwmon/it87.c linux-2.6.39.4-libre/drivers/hwmon/it87.c
--- linux-2.6.39.3-libre/drivers/hwmon/it87.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/it87.c	2011-08-03 15:43:28.000000000 -0400
@@ -1535,7 +1535,7 @@
 };
 
 static const struct attribute_group it87_group_label = {
-	.attrs = it87_attributes_vid,
+	.attrs = it87_attributes_label,
 };
 
 /* SuperIO detection - will change isa_address if a chip is found */
diff -druN linux-2.6.39.3-libre/drivers/hwmon/lm95241.c linux-2.6.39.4-libre/drivers/hwmon/lm95241.c
--- linux-2.6.39.3-libre/drivers/hwmon/lm95241.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/lm95241.c	2011-08-03 15:43:28.000000000 -0400
@@ -98,11 +98,16 @@
 };
 
 /* Conversions */
-static int TempFromReg(u8 val_h, u8 val_l)
+static int temp_from_reg_signed(u8 val_h, u8 val_l)
 {
-	if (val_h & 0x80)
-		return val_h - 0x100;
-	return val_h * 1000 + val_l * 1000 / 256;
+	s16 val_hl = (val_h << 8) | val_l;
+	return val_hl * 1000 / 256;
+}
+
+static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
+{
+	u16 val_hl = (val_h << 8) | val_l;
+	return val_hl * 1000 / 256;
 }
 
 static struct lm95241_data *lm95241_update_device(struct device *dev)
@@ -135,10 +140,13 @@
 			  char *buf)
 {
 	struct lm95241_data *data = lm95241_update_device(dev);
+	int index = to_sensor_dev_attr(attr)->index;
 
 	return snprintf(buf, PAGE_SIZE - 1, "%d\n",
-		TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
-			    data->temp[to_sensor_dev_attr(attr)->index + 1]));
+			index == 0 || (data->config & (1 << (index / 2))) ?
+		temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
+		temp_from_reg_unsigned(data->temp[index],
+				       data->temp[index + 1]));
 }
 
 static ssize_t show_type(struct device *dev, struct device_attribute *attr,
@@ -339,7 +347,7 @@
 	if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
 	     == MANUFACTURER_ID)
 	    && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		>= DEFAULT_REVISION)) {
+		== DEFAULT_REVISION)) {
 		name = DEVNAME;
 	} else {
 		dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
diff -druN linux-2.6.39.3-libre/drivers/hwmon/max1111.c linux-2.6.39.4-libre/drivers/hwmon/max1111.c
--- linux-2.6.39.3-libre/drivers/hwmon/max1111.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/max1111.c	2011-08-03 15:43:28.000000000 -0400
@@ -40,6 +40,8 @@
 	struct spi_transfer	xfer[2];
 	uint8_t *tx_buf;
 	uint8_t *rx_buf;
+	struct mutex		drvdata_lock;
+	/* protect msg, xfer and buffers from multiple access */
 };
 
 static int max1111_read(struct device *dev, int channel)
@@ -48,6 +50,9 @@
 	uint8_t v1, v2;
 	int err;
 
+	/* writing to drvdata struct is not thread safe, wait on mutex */
+	mutex_lock(&data->drvdata_lock);
+
 	data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
 		MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
 		MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
@@ -55,12 +60,15 @@
 	err = spi_sync(data->spi, &data->msg);
 	if (err < 0) {
 		dev_err(dev, "spi_sync failed with %d\n", err);
+		mutex_unlock(&data->drvdata_lock);
 		return err;
 	}
 
 	v1 = data->rx_buf[0];
 	v2 = data->rx_buf[1];
 
+	mutex_unlock(&data->drvdata_lock);
+
 	if ((v1 & 0xc0) || (v2 & 0x3f))
 		return -EINVAL;
 
@@ -176,6 +184,8 @@
 	if (err)
 		goto err_free_data;
 
+	mutex_init(&data->drvdata_lock);
+
 	data->spi = spi;
 	spi_set_drvdata(spi, data);
 
@@ -213,6 +223,7 @@
 
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
+	mutex_destroy(&data->drvdata_lock);
 	kfree(data->rx_buf);
 	kfree(data->tx_buf);
 	kfree(data);
diff -druN linux-2.6.39.3-libre/drivers/hwmon/pmbus.c linux-2.6.39.4-libre/drivers/hwmon/pmbus.c
--- linux-2.6.39.3-libre/drivers/hwmon/pmbus.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/pmbus.c	2011-08-03 15:43:28.000000000 -0400
@@ -47,22 +47,29 @@
 	if (info->func[0]
 	    && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
 		info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
 		info->func[0] |= PMBUS_HAVE_FAN12;
 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
 			info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
 	}
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
 		info->func[0] |= PMBUS_HAVE_FAN34;
 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
 			info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
 	}
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
 		info->func[0] |= PMBUS_HAVE_TEMP;
-		if (pmbus_check_byte_register(client, 0,
-					      PMBUS_STATUS_TEMPERATURE))
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+		info->func[0] |= PMBUS_HAVE_TEMP2;
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+		info->func[0] |= PMBUS_HAVE_TEMP3;
+	if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
+			     | PMBUS_HAVE_TEMP3)
+	    && pmbus_check_byte_register(client, 0,
+					 PMBUS_STATUS_TEMPERATURE))
 			info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
-	}
 
 	/* Sensors detected on all pages */
 	for (page = 0; page < info->pages; page++) {
diff -druN linux-2.6.39.3-libre/drivers/hwmon/pmbus_core.c linux-2.6.39.4-libre/drivers/hwmon/pmbus_core.c
--- linux-2.6.39.3-libre/drivers/hwmon/pmbus_core.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/hwmon/pmbus_core.c	2011-08-03 15:43:28.000000000 -0400
@@ -355,8 +355,8 @@
  * Convert linear sensor values to milli- or micro-units
  * depending on sensor type.
  */
-static int pmbus_reg2data_linear(struct pmbus_data *data,
-				 struct pmbus_sensor *sensor)
+static long pmbus_reg2data_linear(struct pmbus_data *data,
+				  struct pmbus_sensor *sensor)
 {
 	s16 exponent;
 	s32 mantissa;
@@ -390,15 +390,15 @@
 	else
 		val >>= -exponent;
 
-	return (int)val;
+	return val;
 }
 
 /*
  * Convert direct sensor values to milli- or micro-units
  * depending on sensor type.
  */
-static int pmbus_reg2data_direct(struct pmbus_data *data,
-				 struct pmbus_sensor *sensor)
+static long pmbus_reg2data_direct(struct pmbus_data *data,
+				  struct pmbus_sensor *sensor)
 {
 	long val = (s16) sensor->data;
 	long m, b, R;
@@ -433,12 +433,12 @@
 		R++;
 	}
 
-	return (int)((val - b) / m);
+	return (val - b) / m;
 }
 
-static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
+static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
 {
-	int val;
+	long val;
 
 	if (data->info->direct[sensor->class])
 		val = pmbus_reg2data_direct(data, sensor);
@@ -612,7 +612,7 @@
 	if (!s1 && !s2)
 		*val = !!regval;
 	else {
-		int v1, v2;
+		long v1, v2;
 		struct pmbus_sensor *sensor1, *sensor2;
 
 		sensor1 = &data->sensors[s1];
@@ -654,7 +654,7 @@
 	if (sensor->data < 0)
 		return sensor->data;
 
-	return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor));
+	return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
 }
 
 static ssize_t pmbus_set_sensor(struct device *dev,
@@ -1518,14 +1518,9 @@
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
 
-	/*
-	 * Bail out if status register or PMBus revision register
-	 * does not exist.
-	 */
-	if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
-	    || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
-		dev_err(&client->dev,
-			"Status or revision register not found\n");
+	/* Bail out if PMBus status register does not exist. */
+	if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+		dev_err(&client->dev, "PMBus status register not found\n");
 		ret = -ENODEV;
 		goto out_data;
 	}
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib0070.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib0070.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib0070.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib0070.c	2011-08-03 15:43:28.000000000 -0400
@@ -73,47 +73,27 @@
 
     u8  wbd_gain_current;
 	u16 wbd_offset_3_3[2];
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[3];
-	u8 i2c_read_buffer[2];
 };
 
 static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 {
-	state->i2c_write_buffer[0] = reg;
-
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->cfg->i2c_address;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 1;
-	state->msg[1].addr = state->cfg->i2c_address;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = state->i2c_read_buffer;
-	state->msg[1].len = 2;
-
-	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+	u8 b[2];
+	struct i2c_msg msg[2] = {
+		{ .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+		{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
+	};
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0070 I2C read failed\n");
 		return 0;
 	}
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (b[0] << 8) | b[1];
 }
 
 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = reg;
-	state->i2c_write_buffer[1] = val >> 8;
-	state->i2c_write_buffer[2] = val & 0xff;
-
-	memset(state->msg, 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->cfg->i2c_address;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 3;
-
-	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+	u8 b[3] = { reg, val >> 8, val & 0xff };
+	struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0070 I2C write failed\n");
 		return -EREMOTEIO;
 	}
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib0090.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib0090.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib0090.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib0090.c	2011-08-03 15:43:28.000000000 -0400
@@ -191,11 +191,6 @@
 	u8 wbd_calibration_gain;
 	const struct dib0090_wbd_slope *current_wbd_table;
 	u16 wbdmux;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[3];
-	u8 i2c_read_buffer[2];
 };
 
 struct dib0090_fw_state {
@@ -203,48 +198,27 @@
 	struct dvb_frontend *fe;
 	struct dib0090_identity identity;
 	const struct dib0090_config *config;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg;
-	u8 i2c_write_buffer[2];
-	u8 i2c_read_buffer[2];
 };
 
 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
 {
-	state->i2c_write_buffer[0] = reg;
-
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->config->i2c_address;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 1;
-	state->msg[1].addr = state->config->i2c_address;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = state->i2c_read_buffer;
-	state->msg[1].len = 2;
-
-	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+	u8 b[2];
+	struct i2c_msg msg[2] = {
+		{.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1},
+		{.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
+	};
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 		return 0;
 	}
-
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (b[0] << 8) | b[1];
 }
 
 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = reg & 0xff;
-	state->i2c_write_buffer[1] = val >> 8;
-	state->i2c_write_buffer[2] = val & 0xff;
-
-	memset(state->msg, 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->config->i2c_address;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 3;
-
-	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+	u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
+	struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 		return -EREMOTEIO;
 	}
@@ -253,31 +227,20 @@
 
 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
 {
-	state->i2c_write_buffer[0] = reg;
-
-	memset(&state->msg, 0, sizeof(struct i2c_msg));
-	state->msg.addr = reg;
-	state->msg.flags = I2C_M_RD;
-	state->msg.buf = state->i2c_read_buffer;
-	state->msg.len = 2;
-	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+	u8 b[2];
+	struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 		return 0;
 	}
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (b[0] << 8) | b[1];
 }
 
 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = val >> 8;
-	state->i2c_write_buffer[1] = val & 0xff;
-
-	memset(&state->msg, 0, sizeof(struct i2c_msg));
-	state->msg.addr = reg;
-	state->msg.flags = 0;
-	state->msg.buf = state->i2c_write_buffer;
-	state->msg.len = 2;
-	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+	u8 b[2] = { val >> 8, val & 0xff };
+	struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 };
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 		return -EREMOTEIO;
 	}
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib7000m.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib7000m.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib7000m.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib7000m.c	2011-08-03 15:43:28.000000000 -0400
@@ -50,11 +50,6 @@
 	u16 revision;
 
 	u8 agc_state;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[4];
-	u8 i2c_read_buffer[2];
 };
 
 enum dib7000m_power_mode {
@@ -69,39 +64,29 @@
 
 static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
 {
-	state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
-	state->i2c_write_buffer[1] = reg & 0xff;
-
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 2;
-	state->msg[1].addr = state->i2c_addr >> 1;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = state->i2c_read_buffer;
-	state->msg[1].len = 2;
+	u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
+	u8 rb[2];
+	struct i2c_msg msg[2] = {
+		{ .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
+		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+	};
 
-	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
 		dprintk("i2c read error on %d",reg);
 
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (rb[0] << 8) | rb[1];
 }
 
 static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	state->i2c_write_buffer[1] = reg & 0xff;
-	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-	state->i2c_write_buffer[3] = val & 0xff;
-
-	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 4;
-
-	return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+	u8 b[4] = {
+		(reg >> 8) & 0xff, reg & 0xff,
+		(val >> 8) & 0xff, val & 0xff,
+	};
+	struct i2c_msg msg = {
+		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+	};
+	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
 {
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib7000p.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib7000p.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib7000p.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib7000p.c	2011-08-03 15:43:28.000000000 -0400
@@ -63,11 +63,6 @@
 
 	u16 tuner_enable;
 	struct i2c_adapter dib7090_tuner_adap;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[4];
-	u8 i2c_read_buffer[2];
 };
 
 enum dib7000p_power_mode {
@@ -81,39 +76,29 @@
 
 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
 {
-	state->i2c_write_buffer[0] = reg >> 8;
-	state->i2c_write_buffer[1] = reg & 0xff;
-
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 2;
-	state->msg[1].addr = state->i2c_addr >> 1;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = state->i2c_read_buffer;
-	state->msg[1].len = 2;
+	u8 wb[2] = { reg >> 8, reg & 0xff };
+	u8 rb[2];
+	struct i2c_msg msg[2] = {
+		{.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+		{.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
+	};
 
-	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (rb[0] << 8) | rb[1];
 }
 
 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	state->i2c_write_buffer[1] = reg & 0xff;
-	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-	state->i2c_write_buffer[3] = val & 0xff;
-
-	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 4;
-
-	return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+	u8 b[4] = {
+		(reg >> 8) & 0xff, reg & 0xff,
+		(val >> 8) & 0xff, val & 0xff,
+	};
+	struct i2c_msg msg = {
+		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+	};
+	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
@@ -1565,24 +1550,11 @@
 
 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
 {
-	u8 *tx, *rx;
+	u8 tx[2], rx[2];
 	struct i2c_msg msg[2] = {
-		{.addr = 18 >> 1, .flags = 0, .len = 2},
-		{.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
+		{.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2},
+		{.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2},
 	};
-	int ret = 0;
-
-	tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
-	if (!tx)
-		return -ENOMEM;
-	rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
-	if (!rx) {
-		goto rx_memory_error;
-		ret = -ENOMEM;
-	}
-
-	msg[0].buf = tx;
-	msg[1].buf = rx;
 
 	tx[0] = 0x03;
 	tx[1] = 0x00;
@@ -1602,11 +1574,7 @@
 		}
 
 	dprintk("-D-  DiB7000PC not detected");
-
-	kfree(rx);
-rx_memory_error:
-	kfree(tx);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(dib7000pc_detection);
 
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib8000.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib8000.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib8000.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib8000.c	2011-08-03 15:43:28.000000000 -0400
@@ -35,8 +35,6 @@
 struct i2c_device {
 	struct i2c_adapter *adap;
 	u8 addr;
-	u8 *i2c_write_buffer;
-	u8 *i2c_read_buffer;
 };
 
 struct dib8000_state {
@@ -72,11 +70,6 @@
 	u32 status;
 
 	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[4];
-	u8 i2c_read_buffer[2];
 };
 
 enum dib8000_power_mode {
@@ -86,41 +79,22 @@
 
 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
 {
+	u8 wb[2] = { reg >> 8, reg & 0xff };
+	u8 rb[2];
 	struct i2c_msg msg[2] = {
-		{.addr = i2c->addr >> 1, .flags = 0,
-			.buf = i2c->i2c_write_buffer, .len = 2},
-		{.addr = i2c->addr >> 1, .flags = I2C_M_RD,
-			.buf = i2c->i2c_read_buffer, .len = 2},
+		{.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
+		{.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
 	};
 
-	msg[0].buf[0] = reg >> 8;
-	msg[0].buf[1] = reg & 0xff;
-
 	if (i2c_transfer(i2c->adap, msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (msg[1].buf[0] << 8) | msg[1].buf[1];
+	return (rb[0] << 8) | rb[1];
 }
 
 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
 {
-	state->i2c_write_buffer[0] = reg >> 8;
-	state->i2c_write_buffer[1] = reg & 0xff;
-
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c.addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 2;
-	state->msg[1].addr = state->i2c.addr >> 1;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = state->i2c_read_buffer;
-	state->msg[1].len = 2;
-
-	if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
-		dprintk("i2c read error on %d", reg);
-
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return dib8000_i2c_read16(&state->i2c, reg);
 }
 
 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
@@ -135,34 +109,19 @@
 
 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 {
-	struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
-		.buf = i2c->i2c_write_buffer, .len = 4};
-	int ret = 0;
-
-	msg.buf[0] = (reg >> 8) & 0xff;
-	msg.buf[1] = reg & 0xff;
-	msg.buf[2] = (val >> 8) & 0xff;
-	msg.buf[3] = val & 0xff;
-
-	ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
-
-	return ret;
+	u8 b[4] = {
+		(reg >> 8) & 0xff, reg & 0xff,
+		(val >> 8) & 0xff, val & 0xff,
+	};
+	struct i2c_msg msg = {
+		.addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
+	};
+	return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
 {
-	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	state->i2c_write_buffer[1] = reg & 0xff;
-	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-	state->i2c_write_buffer[3] = val & 0xff;
-
-	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c.addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 4;
-
-	return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+	return dib8000_i2c_write16(&state->i2c, reg, val);
 }
 
 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
@@ -1021,31 +980,30 @@
 	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
 }
 
-static const u16 adc_target_16dB[11] = {
-	(1 << 13) - 825 - 117,
-	(1 << 13) - 837 - 117,
-	(1 << 13) - 811 - 117,
-	(1 << 13) - 766 - 117,
-	(1 << 13) - 737 - 117,
-	(1 << 13) - 693 - 117,
-	(1 << 13) - 648 - 117,
-	(1 << 13) - 619 - 117,
-	(1 << 13) - 575 - 117,
-	(1 << 13) - 531 - 117,
-	(1 << 13) - 501 - 117
-};
-static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
-
 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
 {
 	u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
 	u8 guard, crate, constellation, timeI;
+	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
 	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
 	const s16 *ncoeff = NULL, *ana_fe;
 	u16 tmcc_pow = 0;
 	u16 coff_pow = 0x2800;
 	u16 init_prbs = 0xfff;
 	u16 ana_gain = 0;
+	u16 adc_target_16dB[11] = {
+		(1 << 13) - 825 - 117,
+		(1 << 13) - 837 - 117,
+		(1 << 13) - 811 - 117,
+		(1 << 13) - 766 - 117,
+		(1 << 13) - 737 - 117,
+		(1 << 13) - 693 - 117,
+		(1 << 13) - 648 - 117,
+		(1 << 13) - 619 - 117,
+		(1 << 13) - 575 - 117,
+		(1 << 13) - 531 - 117,
+		(1 << 13) - 501 - 117
+	};
 
 	if (state->ber_monitored_layer != LAYER_ALL)
 		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
@@ -2421,22 +2379,10 @@
 
 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
 {
-	int k = 0, ret = 0;
+	int k = 0;
 	u8 new_addr = 0;
 	struct i2c_device client = {.adap = host };
 
-	client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-	if (!client.i2c_write_buffer) {
-		dprintk("%s: not enough memory", __func__);
-		return -ENOMEM;
-	}
-	client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-	if (!client.i2c_read_buffer) {
-		dprintk("%s: not enough memory", __func__);
-		ret = -ENOMEM;
-		goto error_memory;
-	}
-
 	for (k = no_of_demods - 1; k >= 0; k--) {
 		/* designated i2c address */
 		new_addr = first_addr + (k << 1);
@@ -2448,8 +2394,7 @@
 			client.addr = default_addr;
 			if (dib8000_identify(&client) == 0) {
 				dprintk("#%d: not identified", k);
-				ret  = -EINVAL;
-				goto error;
+				return -EINVAL;
 			}
 		}
 
@@ -2475,12 +2420,7 @@
 		dib8000_i2c_write16(&client, 1286, 0);
 	}
 
-error:
-	kfree(client.i2c_read_buffer);
-error_memory:
-	kfree(client.i2c_write_buffer);
-
-	return ret;
+	return 0;
 }
 
 EXPORT_SYMBOL(dib8000_i2c_enumeration);
@@ -2579,8 +2519,6 @@
 	memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
 	state->i2c.adap = i2c_adap;
 	state->i2c.addr = i2c_addr;
-	state->i2c.i2c_write_buffer = state->i2c_write_buffer;
-	state->i2c.i2c_read_buffer = state->i2c_read_buffer;
 	state->gpio_val = cfg->gpio_val;
 	state->gpio_dir = cfg->gpio_dir;
 
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib9000.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib9000.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dib9000.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dib9000.c	2011-08-03 15:43:28.000000000 -0400
@@ -27,8 +27,6 @@
 struct i2c_device {
 	struct i2c_adapter *i2c_adap;
 	u8 i2c_addr;
-	u8 *i2c_read_buffer;
-	u8 *i2c_write_buffer;
 };
 
 /* lock */
@@ -94,16 +92,11 @@
 
 	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
 	u16 component_bus_speed;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[2];
-	u8 i2c_write_buffer[255];
-	u8 i2c_read_buffer[255];
 };
 
-static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0
+	0, 0, 0
 };
 
 enum dib9000_power_mode {
@@ -224,33 +217,25 @@
 	u32 chunk_size = 126;
 	u32 l;
 	int ret;
+	u8 wb[2] = { reg >> 8, reg & 0xff };
+	struct i2c_msg msg[2] = {
+		{.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+		{.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
+	};
 
 	if (state->platform.risc.fw_is_running && (reg < 1024))
 		return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
 
-	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c.i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = 2;
-	state->msg[1].addr = state->i2c.i2c_addr >> 1;
-	state->msg[1].flags = I2C_M_RD;
-	state->msg[1].buf = b;
-	state->msg[1].len = len;
-
-	state->i2c_write_buffer[0] = reg >> 8;
-	state->i2c_write_buffer[1] = reg & 0xff;
-
 	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-		state->i2c_write_buffer[0] |= (1 << 5);
+		wb[0] |= (1 << 5);
 	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-		state->i2c_write_buffer[0] |= (1 << 4);
+		wb[0] |= (1 << 4);
 
 	do {
 		l = len < chunk_size ? len : chunk_size;
-		state->msg[1].len = l;
-		state->msg[1].buf = b;
-		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
+		msg[1].len = l;
+		msg[1].buf = b;
+		ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0;
 		if (ret != 0) {
 			dprintk("i2c read error on %d", reg);
 			return -EREMOTEIO;
@@ -268,47 +253,50 @@
 
 static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
 {
+	u8 b[2];
+	u8 wb[2] = { reg >> 8, reg & 0xff };
 	struct i2c_msg msg[2] = {
-		{.addr = i2c->i2c_addr >> 1, .flags = 0,
-			.buf = i2c->i2c_write_buffer, .len = 2},
-		{.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
-			.buf = i2c->i2c_read_buffer, .len = 2},
+		{.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+		{.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2},
 	};
 
-	i2c->i2c_write_buffer[0] = reg >> 8;
-	i2c->i2c_write_buffer[1] = reg & 0xff;
-
 	if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
 		dprintk("read register %x error", reg);
 		return 0;
 	}
 
-	return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
+	return (b[0] << 8) | b[1];
 }
 
 static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
 {
-	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
+	u8 b[2];
+	if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
 		return 0;
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (b[0] << 8 | b[1]);
 }
 
 static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
 {
-	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
-				attribute) != 0)
+	u8 b[2];
+	if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0)
 		return 0;
-	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+	return (b[0] << 8 | b[1]);
 }
 
 #define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
 
 static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
 {
+	u8 b[255];
 	u32 chunk_size = 126;
 	u32 l;
 	int ret;
 
+	struct i2c_msg msg = {
+		.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
+	};
+
 	if (state->platform.risc.fw_is_running && (reg < 1024)) {
 		if (dib9000_risc_apb_access_write
 		    (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
@@ -316,26 +304,20 @@
 		return 0;
 	}
 
-	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-	state->msg[0].addr = state->i2c.i2c_addr >> 1;
-	state->msg[0].flags = 0;
-	state->msg[0].buf = state->i2c_write_buffer;
-	state->msg[0].len = len + 2;
-
-	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	state->i2c_write_buffer[1] = (reg) & 0xff;
+	b[0] = (reg >> 8) & 0xff;
+	b[1] = (reg) & 0xff;
 
 	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-		state->i2c_write_buffer[0] |= (1 << 5);
+		b[0] |= (1 << 5);
 	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-		state->i2c_write_buffer[0] |= (1 << 4);
+		b[0] |= (1 << 4);
 
 	do {
 		l = len < chunk_size ? len : chunk_size;
-		state->msg[0].len = l + 2;
-		memcpy(&state->i2c_write_buffer[2], buf, l);
+		msg.len = l + 2;
+		memcpy(&b[2], buf, l);
 
-		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+		ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 
 		buf += l;
 		len -= l;
@@ -349,16 +331,11 @@
 
 static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 {
+	u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
 	struct i2c_msg msg = {
-		.addr = i2c->i2c_addr >> 1, .flags = 0,
-		.buf = i2c->i2c_write_buffer, .len = 4
+		.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
 	};
 
-	i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	i2c->i2c_write_buffer[1] = reg & 0xff;
-	i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
-	i2c->i2c_write_buffer[3] = val & 0xff;
-
 	return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
@@ -1038,8 +1015,8 @@
 		return 0;
 	dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
 	do {
-		dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
-	} while (state->i2c_read_buffer[0] && index_loop--);
+		dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1);
+	} while (i && index_loop--);
 
 	if (index_loop > 0)
 		return 0;
@@ -1162,7 +1139,7 @@
 
 		s8 intlv_native;
 	};
-	struct dibDVBTChannel *ch;
+	struct dibDVBTChannel ch;
 	int ret = 0;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
@@ -1171,12 +1148,9 @@
 		ret = -EIO;
 	}
 
-	dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
-			state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
-	ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
-
+	dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel));
 
-	switch (ch->spectrum_inversion & 0x7) {
+	switch (ch.spectrum_inversion & 0x7) {
 	case 1:
 		state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
 		break;
@@ -1188,7 +1162,7 @@
 		state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
 		break;
 	}
-	switch (ch->nfft) {
+	switch (ch.nfft) {
 	case 0:
 		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
 		break;
@@ -1203,7 +1177,7 @@
 		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
 		break;
 	}
-	switch (ch->guard) {
+	switch (ch.guard) {
 	case 0:
 		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
 		break;
@@ -1221,7 +1195,7 @@
 		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
 		break;
 	}
-	switch (ch->constellation) {
+	switch (ch.constellation) {
 	case 2:
 		state->fe[0]->dtv_property_cache.modulation = QAM_64;
 		break;
@@ -1236,7 +1210,7 @@
 		state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
 		break;
 	}
-	switch (ch->hrch) {
+	switch (ch.hrch) {
 	case 0:
 		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
 		break;
@@ -1248,7 +1222,7 @@
 		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
 		break;
 	}
-	switch (ch->code_rate_hp) {
+	switch (ch.code_rate_hp) {
 	case 1:
 		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
 		break;
@@ -1269,7 +1243,7 @@
 		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
 		break;
 	}
-	switch (ch->code_rate_lp) {
+	switch (ch.code_rate_lp) {
 	case 1:
 		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
 		break;
@@ -1465,10 +1439,9 @@
 		break;
 	case CT_DEMOD_STEP_1:
 		if (search)
-			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
+			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1);
 		else
-			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
-		i = (s8)state->i2c_read_buffer[0];
+			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1);
 		switch (i) {	/* something happened */
 		case 0:
 			break;
@@ -2065,17 +2038,14 @@
 static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 *c;
+	u16 c[16];
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
-			state->i2c_read_buffer, 16 * 2);
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
-	c = (u16 *)state->i2c_read_buffer;
-
 	*ber = c[10] << 16 | c[11];
 	return 0;
 }
@@ -2084,7 +2054,7 @@
 {
 	struct dib9000_state *state = fe->demodulator_priv;
 	u8 index_frontend;
-	u16 *c = (u16 *)state->i2c_read_buffer;
+	u16 c[16];
 	u16 val;
 
 	*strength = 0;
@@ -2099,7 +2069,7 @@
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	val = 65535 - c[4];
@@ -2113,14 +2083,14 @@
 static u32 dib9000_get_snr(struct dvb_frontend *fe)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 *c = (u16 *)state->i2c_read_buffer;
+	u16 c[16];
 	u32 n, s, exp;
 	u16 val;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	val = c[7];
@@ -2167,12 +2137,12 @@
 static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 *c = (u16 *)state->i2c_read_buffer;
+	u16 c[16];
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	*unc = c[12];
@@ -2181,22 +2151,10 @@
 
 int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
 {
-	int k = 0, ret = 0;
+	int k = 0;
 	u8 new_addr = 0;
 	struct i2c_device client = {.i2c_adap = i2c };
 
-	client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-	if (!client.i2c_write_buffer) {
-		dprintk("%s: not enough memory", __func__);
-		return -ENOMEM;
-	}
-	client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-	if (!client.i2c_read_buffer) {
-		dprintk("%s: not enough memory", __func__);
-		ret = -ENOMEM;
-		goto error_memory;
-	}
-
 	client.i2c_addr = default_addr + 16;
 	dib9000_i2c_write16(&client, 1796, 0x0);
 
@@ -2220,8 +2178,7 @@
 			client.i2c_addr = default_addr;
 			if (dib9000_identify(&client) == 0) {
 				dprintk("DiB9000 #%d: not identified", k);
-				ret = -EIO;
-				goto error;
+				return -EIO;
 			}
 		}
 
@@ -2239,12 +2196,7 @@
 		dib9000_i2c_write16(&client, 1795, 0);
 	}
 
-error:
-	kfree(client.i2c_read_buffer);
-error_memory:
-	kfree(client.i2c_write_buffer);
-
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(dib9000_i2c_enumeration);
 
@@ -2309,8 +2261,6 @@
 	memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
 	st->i2c.i2c_adap = i2c_adap;
 	st->i2c.i2c_addr = i2c_addr;
-	st->i2c.i2c_write_buffer = st->i2c_write_buffer;
-	st->i2c.i2c_read_buffer = st->i2c_read_buffer;
 
 	st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
 	st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dibx000_common.c linux-2.6.39.4-libre/drivers/media/dvb/frontends/dibx000_common.c
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dibx000_common.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dibx000_common.c	2011-08-03 15:43:28.000000000 -0400
@@ -10,39 +10,30 @@
 
 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
 {
-	mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-	mst->i2c_write_buffer[1] = reg & 0xff;
-	mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
-	mst->i2c_write_buffer[3] = val & 0xff;
-
-	memset(mst->msg, 0, sizeof(struct i2c_msg));
-	mst->msg[0].addr = mst->i2c_addr;
-	mst->msg[0].flags = 0;
-	mst->msg[0].buf = mst->i2c_write_buffer;
-	mst->msg[0].len = 4;
+	u8 b[4] = {
+		(reg >> 8) & 0xff, reg & 0xff,
+		(val >> 8) & 0xff, val & 0xff,
+	};
+	struct i2c_msg msg = {
+		.addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
+	};
 
-	return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
+	return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
 {
-	mst->i2c_write_buffer[0] = reg >> 8;
-	mst->i2c_write_buffer[1] = reg & 0xff;
-
-	memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
-	mst->msg[0].addr = mst->i2c_addr;
-	mst->msg[0].flags = 0;
-	mst->msg[0].buf = mst->i2c_write_buffer;
-	mst->msg[0].len = 2;
-	mst->msg[1].addr = mst->i2c_addr;
-	mst->msg[1].flags = I2C_M_RD;
-	mst->msg[1].buf = mst->i2c_read_buffer;
-	mst->msg[1].len = 2;
+	u8 wb[2] = { reg >> 8, reg & 0xff };
+	u8 rb[2];
+	struct i2c_msg msg[2] = {
+		{.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
+		{.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
+	};
 
-	if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
+	if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
+	return (rb[0] << 8) | rb[1];
 }
 
 static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
@@ -257,32 +248,26 @@
 					struct i2c_msg msg[], int num)
 {
 	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+	struct i2c_msg m[2 + num];
+	u8 tx_open[4], tx_close[4];
 
-	if (num > 32) {
-		dprintk("%s: too much I2C message to be transmitted (%i).\
-				Maximum is 32", __func__, num);
-		return -ENOMEM;
-	}
-
-	memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
 
 	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
 
-	/* open the gate */
-	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
-	mst->msg[0].addr = mst->i2c_addr;
-	mst->msg[0].buf = &mst->i2c_write_buffer[0];
-	mst->msg[0].len = 4;
+	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+	m[0].addr = mst->i2c_addr;
+	m[0].buf = tx_open;
+	m[0].len = 4;
 
-	memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
 
-	/* close the gate */
-	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
-	mst->msg[num + 1].addr = mst->i2c_addr;
-	mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
-	mst->msg[num + 1].len = 4;
+	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
+	m[num + 1].addr = mst->i2c_addr;
+	m[num + 1].buf = tx_close;
+	m[num + 1].len = 4;
 
-	return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
+	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
 }
 
 static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
@@ -294,32 +279,26 @@
 					struct i2c_msg msg[], int num)
 {
 	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+	struct i2c_msg m[2 + num];
+	u8 tx_open[4], tx_close[4];
 
-	if (num > 32) {
-		dprintk("%s: too much I2C message to be transmitted (%i).\
-				Maximum is 32", __func__, num);
-		return -ENOMEM;
-	}
-
-	memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
 
 	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
 
-	/* open the gate */
-	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
-	mst->msg[0].addr = mst->i2c_addr;
-	mst->msg[0].buf = &mst->i2c_write_buffer[0];
-	mst->msg[0].len = 4;
+	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+	m[0].addr = mst->i2c_addr;
+	m[0].buf = tx_open;
+	m[0].len = 4;
 
-	memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
 
-	/* close the gate */
-	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
-	mst->msg[num + 1].addr = mst->i2c_addr;
-	mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
-	mst->msg[num + 1].len = 4;
+	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
+	m[num + 1].addr = mst->i2c_addr;
+	m[num + 1].buf = tx_close;
+	m[num + 1].len = 4;
 
-	return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
+	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
 }
 
 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
diff -druN linux-2.6.39.3-libre/drivers/media/dvb/frontends/dibx000_common.h linux-2.6.39.4-libre/drivers/media/dvb/frontends/dibx000_common.h
--- linux-2.6.39.3-libre/drivers/media/dvb/frontends/dibx000_common.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/dvb/frontends/dibx000_common.h	2011-08-03 15:43:28.000000000 -0400
@@ -28,11 +28,6 @@
 	u8 i2c_addr;
 
 	u16 base_reg;
-
-	/* for the I2C transfer */
-	struct i2c_msg msg[34];
-	u8 i2c_write_buffer[8];
-	u8 i2c_read_buffer[2];
 };
 
 extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
diff -druN linux-2.6.39.3-libre/drivers/media/radio/si4713-i2c.c linux-2.6.39.4-libre/drivers/media/radio/si4713-i2c.c
--- linux-2.6.39.3-libre/drivers/media/radio/si4713-i2c.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/radio/si4713-i2c.c	2011-08-03 15:43:28.000000000 -0400
@@ -1033,7 +1033,7 @@
 		char ps_name[MAX_RDS_PS_NAME + 1];
 
 		len = control->size - 1;
-		if (len > MAX_RDS_PS_NAME) {
+		if (len < 0 || len > MAX_RDS_PS_NAME) {
 			rval = -ERANGE;
 			goto exit;
 		}
@@ -1057,7 +1057,7 @@
 		char radio_text[MAX_RDS_RADIO_TEXT + 1];
 
 		len = control->size - 1;
-		if (len > MAX_RDS_RADIO_TEXT) {
+		if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
 			rval = -ERANGE;
 			goto exit;
 		}
diff -druN linux-2.6.39.3-libre/drivers/media/video/bt8xx/bttv-driver.c linux-2.6.39.4-libre/drivers/media/video/bt8xx/bttv-driver.c
--- linux-2.6.39.3-libre/drivers/media/video/bt8xx/bttv-driver.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/video/bt8xx/bttv-driver.c	2011-08-03 15:43:28.000000000 -0400
@@ -3474,7 +3474,7 @@
 	if (0 != t->index)
 		return -EINVAL;
 
-	bttv_call_all(btv, tuner, g_tuner, t);
+	bttv_call_all(btv, tuner, s_tuner, t);
 	return 0;
 }
 
diff -druN linux-2.6.39.3-libre/drivers/media/video/cx23885/cx23885-core.c linux-2.6.39.4-libre/drivers/media/video/cx23885/cx23885-core.c
--- linux-2.6.39.3-libre/drivers/media/video/cx23885/cx23885-core.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/video/cx23885/cx23885-core.c	2011-08-03 15:43:28.000000000 -0400
@@ -2060,12 +2060,8 @@
 		goto fail_irq;
 	}
 
-	if (!pci_enable_msi(pci_dev))
-		err = request_irq(pci_dev->irq, cx23885_irq,
-				  IRQF_DISABLED, dev->name, dev);
-	else
-		err = request_irq(pci_dev->irq, cx23885_irq,
-				  IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+	err = request_irq(pci_dev->irq, cx23885_irq,
+			  IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
 	if (err < 0) {
 		printk(KERN_ERR "%s: can't get IRQ %d\n",
 		       dev->name, pci_dev->irq);
@@ -2114,7 +2110,6 @@
 
 	/* unregister stuff */
 	free_irq(pci_dev->irq, dev);
-	pci_disable_msi(pci_dev);
 
 	cx23885_dev_unregister(dev);
 	v4l2_device_unregister(v4l2_dev);
diff -druN linux-2.6.39.3-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-2.6.39.4-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-2.6.39.3-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2011-07-09 23:29:42.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2011-08-04 00:21:17.000000000 -0400
@@ -3046,6 +3046,8 @@
 	if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
 		struct v4l2_tuner vt;
 		memset(&vt, 0, sizeof(vt));
+		vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		vt.audmode = hdw->audiomode_val;
 		v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
 	}
@@ -5171,6 +5173,8 @@
 {
 	struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
 	memset(vtp, 0, sizeof(*vtp));
+	vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	hdw->tuner_signal_stale = 0;
 	/* Note: There apparently is no replacement for VIDIOC_CROPCAP
 	   using v4l2-subdev - therefore we can't support that AT ALL right
diff -druN linux-2.6.39.3-libre/drivers/media/video/tuner-core.c linux-2.6.39.4-libre/drivers/media/video/tuner-core.c
--- linux-2.6.39.3-libre/drivers/media/video/tuner-core.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/video/tuner-core.c	2011-08-03 15:43:28.000000000 -0400
@@ -724,19 +724,15 @@
 }
 
 /**
- * set_mode_freq - Switch tuner to other mode.
- * @client:	struct i2c_client pointer
+ * set_mode - Switch tuner to other mode.
  * @t:		a pointer to the module's internal struct_tuner
  * @mode:	enum v4l2_type (radio or TV)
- * @freq:	frequency to set (0 means to use the previous one)
  *
  * If tuner doesn't support the needed mode (radio or TV), prints a
  * debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the state and sets frequency to the last value, if
- * the tuner can sleep or if it supports both Radio and TV.
+ * Otherwise, changes the mode and returns 0.
  */
-static int set_mode_freq(struct i2c_client *client, struct tuner *t,
-			 enum v4l2_tuner_type mode, unsigned int freq)
+static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
 {
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
@@ -752,17 +748,27 @@
 		t->mode = mode;
 		tuner_dbg("Changing to mode %d\n", mode);
 	}
+	return 0;
+}
+
+/**
+ * set_freq - Set the tuner to the desired frequency.
+ * @t:		a pointer to the module's internal struct_tuner
+ * @freq:	frequency to set (0 means to use the current frequency)
+ */
+static void set_freq(struct tuner *t, unsigned int freq)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
 	if (t->mode == V4L2_TUNER_RADIO) {
-		if (freq)
-			t->radio_freq = freq;
-		set_radio_freq(client, t->radio_freq);
+		if (!freq)
+			freq = t->radio_freq;
+		set_radio_freq(client, freq);
 	} else {
-		if (freq)
-			t->tv_freq = freq;
-		set_tv_freq(client, t->tv_freq);
+		if (!freq)
+			freq = t->tv_freq;
+		set_tv_freq(client, freq);
 	}
-
-	return 0;
 }
 
 /*
@@ -1058,10 +1064,9 @@
 static int tuner_s_radio(struct v4l2_subdev *sd)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
-		return 0;
+	if (set_mode(t, V4L2_TUNER_RADIO) == 0)
+		set_freq(t, 0);
 	return 0;
 }
 
@@ -1093,25 +1098,22 @@
 static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
+	if (set_mode(t, V4L2_TUNER_ANALOG_TV))
 		return 0;
 
 	t->std = std;
 	tuner_fixup_std(t);
-
+	set_freq(t, 0);
 	return 0;
 }
 
 static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
-		return 0;
 
+	if (set_mode(t, f->type) == 0)
+		set_freq(t, f->frequency);
 	return 0;
 }
 
@@ -1180,13 +1182,13 @@
 static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
+	if (set_mode(t, vt->type))
 		return 0;
 
 	if (t->mode == V4L2_TUNER_RADIO)
 		t->audmode = vt->audmode;
+	set_freq(t, 0);
 
 	return 0;
 }
@@ -1221,7 +1223,8 @@
 	tuner_dbg("resume\n");
 
 	if (!t->standby)
-		set_mode_freq(c, t, t->type, 0);
+		if (set_mode(t, t->mode) == 0)
+			set_freq(t, 0);
 
 	return 0;
 }
diff -druN linux-2.6.39.3-libre/drivers/media/video/v4l2-ioctl.c linux-2.6.39.4-libre/drivers/media/video/v4l2-ioctl.c
--- linux-2.6.39.3-libre/drivers/media/video/v4l2-ioctl.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/media/video/v4l2-ioctl.c	2011-08-03 15:43:28.000000000 -0400
@@ -1822,6 +1822,8 @@
 		if (!ops->vidioc_g_tuner)
 			break;
 
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		ret = ops->vidioc_g_tuner(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1840,6 +1842,8 @@
 
 		if (!ops->vidioc_s_tuner)
 			break;
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		dbgarg(cmd, "index=%d, name=%s, type=%d, "
 				"capability=0x%x, rangelow=%d, "
 				"rangehigh=%d, signal=%d, afc=%d, "
@@ -1858,6 +1862,8 @@
 		if (!ops->vidioc_g_frequency)
 			break;
 
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		ret = ops->vidioc_g_frequency(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
diff -druN linux-2.6.39.3-libre/drivers/mmc/host/sdhci-esdhc-imx.c linux-2.6.39.4-libre/drivers/mmc/host/sdhci-esdhc-imx.c
--- linux-2.6.39.3-libre/drivers/mmc/host/sdhci-esdhc-imx.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/mmc/host/sdhci-esdhc-imx.c	2011-08-03 15:43:28.000000000 -0400
@@ -74,7 +74,7 @@
 		if (boarddata && gpio_is_valid(boarddata->cd_gpio)
 				&& gpio_get_value(boarddata->cd_gpio))
 			/* no card, if a valid gpio says so... */
-			val &= SDHCI_CARD_PRESENT;
+			val &= ~SDHCI_CARD_PRESENT;
 		else
 			/* ... in all other cases assume card is present */
 			val |= SDHCI_CARD_PRESENT;
diff -druN linux-2.6.39.3-libre/drivers/net/wireless/ath/ath5k/pci.c linux-2.6.39.4-libre/drivers/net/wireless/ath/ath5k/pci.c
--- linux-2.6.39.3-libre/drivers/net/wireless/ath/ath5k/pci.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/net/wireless/ath/ath5k/pci.c	2011-08-03 15:43:28.000000000 -0400
@@ -265,7 +265,9 @@
 #ifdef CONFIG_PM_SLEEP
 static int ath5k_pci_suspend(struct device *dev)
 {
-	struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ath5k_softc *sc = hw->priv;
 
 	ath5k_led_off(sc);
 	return 0;
@@ -274,7 +276,8 @@
 static int ath5k_pci_resume(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct ath5k_softc *sc = pci_get_drvdata(pdev);
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ath5k_softc *sc = hw->priv;
 
 	/*
 	 * Suspend/Resume resets the PCI configuration space, so we have to
diff -druN linux-2.6.39.3-libre/drivers/net/wireless/ath/ath5k/sysfs.c linux-2.6.39.4-libre/drivers/net/wireless/ath/ath5k/sysfs.c
--- linux-2.6.39.3-libre/drivers/net/wireless/ath/ath5k/sysfs.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/net/wireless/ath/ath5k/sysfs.c	2011-08-03 15:43:28.000000000 -0400
@@ -10,7 +10,8 @@
 			struct device_attribute *attr,			\
 			char *buf)					\
 {									\
-	struct ath5k_softc *sc = dev_get_drvdata(dev);			\
+	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
+	struct ath5k_softc *sc = hw->priv;				\
 	return snprintf(buf, PAGE_SIZE, "%d\n", get); 			\
 }									\
 									\
@@ -18,7 +19,8 @@
 			struct device_attribute *attr,			\
 			const char *buf, size_t count)			\
 {									\
-	struct ath5k_softc *sc = dev_get_drvdata(dev);			\
+	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
+	struct ath5k_softc *sc = hw->priv;				\
 	int val;							\
 									\
 	val = (int)simple_strtoul(buf, NULL, 10);			\
@@ -33,7 +35,8 @@
 			struct device_attribute *attr,			\
 			char *buf)					\
 {									\
-	struct ath5k_softc *sc = dev_get_drvdata(dev);			\
+	struct ieee80211_hw *hw = dev_get_drvdata(dev);			\
+	struct ath5k_softc *sc = hw->priv;				\
 	return snprintf(buf, PAGE_SIZE, "%d\n", get); 			\
 }									\
 static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
diff -druN linux-2.6.39.3-libre/drivers/net/wireless/ath/ath9k/xmit.c linux-2.6.39.4-libre/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-2.6.39.3-libre/drivers/net/wireless/ath/ath9k/xmit.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/net/wireless/ath/ath9k/xmit.c	2011-08-03 15:43:28.000000000 -0400
@@ -662,7 +662,8 @@
 	 * TODO - this could be improved to be dependent on the rate.
 	 *      The hardware can keep up at lower rates, but not higher rates
 	 */
-	if (fi->keyix != ATH9K_TXKEYIX_INVALID)
+	if ((fi->keyix != ATH9K_TXKEYIX_INVALID) &&
+	    !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))
 		ndelim += ATH_AGGR_ENCRYPTDELIM;
 
 	/*
diff -druN linux-2.6.39.3-libre/drivers/net/wireless/ath/carl9170/usb.c linux-2.6.39.4-libre/drivers/net/wireless/ath/carl9170/usb.c
--- linux-2.6.39.3-libre/drivers/net/wireless/ath/carl9170/usb.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/net/wireless/ath/carl9170/usb.c	2011-08-03 15:43:28.000000000 -0400
@@ -112,6 +112,8 @@
 	{ USB_DEVICE(0x04bb, 0x093f) },
 	/* NEC WL300NU-G */
 	{ USB_DEVICE(0x0409, 0x0249) },
+	/* NEC WL300NU-AG */
+	{ USB_DEVICE(0x0409, 0x02b4) },
 	/* AVM FRITZ!WLAN USB Stick N */
 	{ USB_DEVICE(0x057c, 0x8401) },
 	/* AVM FRITZ!WLAN USB Stick N 2.4 */
diff -druN linux-2.6.39.3-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c linux-2.6.39.4-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
--- linux-2.6.39.3-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2011-07-09 23:34:37.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2011-08-04 00:26:07.000000000 -0400
@@ -278,6 +278,7 @@
 	{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
 	{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
 	{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
+	{RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
 	{RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
 	{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
 	/* HP - Lite-On ,8188CUS Slim Combo */
diff -druN linux-2.6.39.3-libre/drivers/pci/quirks.c linux-2.6.39.4-libre/drivers/pci/quirks.c
--- linux-2.6.39.3-libre/drivers/pci/quirks.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/pci/quirks.c	2011-08-03 15:43:28.000000000 -0400
@@ -2755,6 +2755,29 @@
 
 	dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
 	dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+
+	/*
+	 * RICOH 0xe823 SD/MMC card reader fails to recognize
+	 * certain types of SD/MMC cards. Lowering the SD base
+	 * clock frequency from 200Mhz to 50Mhz fixes this issue.
+	 *
+	 * 0x150 - SD2.0 mode enable for changing base clock
+	 *	   frequency to 50Mhz
+	 * 0xe1  - Base clock frequency
+	 * 0x32  - 50Mhz new clock frequency
+	 * 0xf9  - Key register for 0x150
+	 * 0xfc  - key register for 0xe1
+	 */
+	if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) {
+		pci_write_config_byte(dev, 0xf9, 0xfc);
+		pci_write_config_byte(dev, 0x150, 0x10);
+		pci_write_config_byte(dev, 0xf9, 0x00);
+		pci_write_config_byte(dev, 0xfc, 0x01);
+		pci_write_config_byte(dev, 0xe1, 0x32);
+		pci_write_config_byte(dev, 0xfc, 0x00);
+
+		dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
+	}
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
diff -druN linux-2.6.39.3-libre/drivers/platform/x86/dell-laptop.c linux-2.6.39.4-libre/drivers/platform/x86/dell-laptop.c
--- linux-2.6.39.3-libre/drivers/platform/x86/dell-laptop.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/platform/x86/dell-laptop.c	2011-08-03 15:43:28.000000000 -0400
@@ -290,12 +290,9 @@
 	dell_send_request(buffer, 17, 11);
 
 	/* If the hardware switch controls this radio, and the hardware
-	   switch is disabled, don't allow changing the software state.
-	   If the hardware switch is reported as not supported, always
-	   fire the SMI to toggle the killswitch. */
+	   switch is disabled, don't allow changing the software state */
 	if ((hwswitch_state & BIT(hwswitch_bit)) &&
-	    !(buffer->output[1] & BIT(16)) &&
-	    (buffer->output[1] & BIT(0))) {
+	    !(buffer->output[1] & BIT(16))) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -401,23 +398,6 @@
 
 static void dell_update_rfkill(struct work_struct *ignored)
 {
-	int status;
-
-	get_buffer();
-	dell_send_request(buffer, 17, 11);
-	status = buffer->output[1];
-	release_buffer();
-
-	/* if hardware rfkill is not supported, set it explicitly */
-	if (!(status & BIT(0))) {
-		if (wifi_rfkill)
-			dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
-		if (bluetooth_rfkill)
-			dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
-		if (wwan_rfkill)
-			dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
-	}
-
 	if (wifi_rfkill)
 		dell_rfkill_query(wifi_rfkill, (void *)1);
 	if (bluetooth_rfkill)
diff -druN linux-2.6.39.3-libre/drivers/usb/serial/pl2303.c linux-2.6.39.4-libre/drivers/usb/serial/pl2303.c
--- linux-2.6.39.3-libre/drivers/usb/serial/pl2303.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/usb/serial/pl2303.c	2011-08-03 15:43:28.000000000 -0400
@@ -91,6 +91,7 @@
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
 	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
 	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
+	{ USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff -druN linux-2.6.39.3-libre/drivers/usb/serial/pl2303.h linux-2.6.39.4-libre/drivers/usb/serial/pl2303.h
--- linux-2.6.39.3-libre/drivers/usb/serial/pl2303.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/drivers/usb/serial/pl2303.h	2011-08-03 15:43:28.000000000 -0400
@@ -144,3 +144,7 @@
 /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
 #define ADLINK_VENDOR_ID		0x0b63
 #define ADLINK_ND6530_PRODUCT_ID	0x6530
+
+/* WinChipHead USB->RS 232 adapter */
+#define WINCHIPHEAD_VENDOR_ID		0x4348
+#define WINCHIPHEAD_USBSER_PRODUCT_ID	0x5523
diff -druN linux-2.6.39.3-libre/fs/cifs/connect.c linux-2.6.39.4-libre/fs/cifs/connect.c
--- linux-2.6.39.3-libre/fs/cifs/connect.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/cifs/connect.c	2011-08-03 15:43:28.000000000 -0400
@@ -2571,23 +2571,6 @@
 	else /* default */
 		cifs_sb->rsize = CIFSMaxBufSize;
 
-	if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
-		cERROR(1, "wsize %d too large, using 4096 instead",
-			  pvolume_info->wsize);
-		cifs_sb->wsize = 4096;
-	} else if (pvolume_info->wsize)
-		cifs_sb->wsize = pvolume_info->wsize;
-	else
-		cifs_sb->wsize = min_t(const int,
-					PAGEVEC_SIZE * PAGE_CACHE_SIZE,
-					127*1024);
-		/* old default of CIFSMaxBufSize was too small now
-		   that SMB Write2 can send multiple pages in kvec.
-		   RFC1001 does not describe what happens when frame
-		   bigger than 128K is sent so use that as max in
-		   conjunction with 52K kvec constraint on arch with 4K
-		   page size  */
-
 	if (cifs_sb->rsize < 2048) {
 		cifs_sb->rsize = 2048;
 		/* Windows ME may prefer this */
@@ -2665,6 +2648,48 @@
 			   "mount option supported");
 }
 
+/* Prior to 3.0, cifs couldn't handle writes larger than this */
+#define CIFS_MAX_WSIZE (PAGEVEC_SIZE * PAGE_CACHE_SIZE)
+
+/*
+ * When the server doesn't allow large posix writes, only allow a wsize of
+ * 128k minus the size of the WRITE_AND_X header. That allows for a write up
+ * to the maximum size described by RFC1002.
+ */
+#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4)
+
+/* Make the default the same as the max */
+#define CIFS_DEFAULT_WSIZE CIFS_MAX_WSIZE
+
+static unsigned int
+cifs_negotiate_wsize(struct cifsTconInfo *tcon, struct smb_vol *pvolume_info)
+{
+	__u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+	struct TCP_Server_Info *server = tcon->ses->server;
+	unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
+				CIFS_DEFAULT_WSIZE;
+
+	/* can server support 24-bit write sizes? (via UNIX extensions) */
+	if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
+		wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE);
+
+	/*
+	 * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set?
+	 * Limit it to max buffer offered by the server, minus the size of the
+	 * WRITEX header, not including the 4 byte RFC1001 length.
+	 */
+	if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
+	    (!(server->capabilities & CAP_UNIX) &&
+	     (server->secMode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED))))
+		wsize = min_t(unsigned int, wsize,
+				server->maxBuf - sizeof(WRITE_REQ) + 4);
+
+	/* hard limit of CIFS_MAX_WSIZE */
+	wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
+
+	return wsize;
+}
+
 static int
 is_path_accessible(int xid, struct cifsTconInfo *tcon,
 		   struct cifs_sb_info *cifs_sb, const char *full_path)
@@ -2866,13 +2891,12 @@
 		cifs_sb->rsize = 1024 * 127;
 		cFYI(DBG2, "no very large read support, rsize now 127K");
 	}
-	if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
-		cifs_sb->wsize = min(cifs_sb->wsize,
-			       (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
 	if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
 		cifs_sb->rsize = min(cifs_sb->rsize,
 			       (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
 
+	cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
+
 remote_path_check:
 	/* check if a whole path (including prepath) is not remote */
 	if (!rc && tcon) {
diff -druN linux-2.6.39.3-libre/fs/ext4/super.c linux-2.6.39.4-libre/fs/ext4/super.c
--- linux-2.6.39.3-libre/fs/ext4/super.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/ext4/super.c	2011-08-03 15:43:28.000000000 -0400
@@ -4635,6 +4635,9 @@
 	if (test_opt(sb, DELALLOC))
 		sync_filesystem(sb);
 
+	if (!inode)
+		goto out;
+
 	/* Update modification times of quota files when userspace can
 	 * start looking at them */
 	handle = ext4_journal_start(inode, 1);
diff -druN linux-2.6.39.3-libre/fs/fscache/page.c linux-2.6.39.4-libre/fs/fscache/page.c
--- linux-2.6.39.3-libre/fs/fscache/page.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/fscache/page.c	2011-08-03 15:43:28.000000000 -0400
@@ -989,16 +989,12 @@
 
 	pagevec_init(&pvec, 0);
 	next = 0;
-	while (next <= (loff_t)-1 &&
-	       pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)
-	       ) {
+	do {
+		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
+			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
-			pgoff_t page_index = page->index;
-
-			ASSERTCMP(page_index, >=, next);
-			next = page_index + 1;
-
+			next = page->index;
 			if (PageFsCache(page)) {
 				__fscache_wait_on_page_write(cookie, page);
 				__fscache_uncache_page(cookie, page);
@@ -1006,7 +1002,7 @@
 		}
 		pagevec_release(&pvec);
 		cond_resched();
-	}
+	} while (++next);
 
 	_leave("");
 }
diff -druN linux-2.6.39.3-libre/fs/gfs2/file.c linux-2.6.39.4-libre/fs/gfs2/file.c
--- linux-2.6.39.3-libre/fs/gfs2/file.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/gfs2/file.c	2011-08-03 15:43:28.000000000 -0400
@@ -826,6 +826,7 @@
 	loff_t bytes, max_bytes;
 	struct gfs2_alloc *al;
 	int error;
+	loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1);
 	loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift;
 	next = (next + 1) << sdp->sd_sb.sb_bsize_shift;
 
@@ -833,13 +834,15 @@
 	if (mode & ~FALLOC_FL_KEEP_SIZE)
 		return -EOPNOTSUPP;
 
-	offset = (offset >> sdp->sd_sb.sb_bsize_shift) <<
-		 sdp->sd_sb.sb_bsize_shift;
+	offset &= bsize_mask;
 
 	len = next - offset;
 	bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2;
 	if (!bytes)
 		bytes = UINT_MAX;
+	bytes &= bsize_mask;
+	if (bytes == 0)
+		bytes = sdp->sd_sb.sb_bsize;
 
 	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
 	error = gfs2_glock_nq(&ip->i_gh);
@@ -870,6 +873,9 @@
 		if (error) {
 			if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
 				bytes >>= 1;
+				bytes &= bsize_mask;
+				if (bytes == 0)
+					bytes = sdp->sd_sb.sb_bsize;
 				goto retry;
 			}
 			goto out_qunlock;
diff -druN linux-2.6.39.3-libre/fs/namei.c linux-2.6.39.4-libre/fs/namei.c
--- linux-2.6.39.3-libre/fs/namei.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/namei.c	2011-08-03 15:43:28.000000000 -0400
@@ -1013,7 +1013,6 @@
 		 * Don't forget we might have a non-mountpoint managed dentry
 		 * that wants to block transit.
 		 */
-		*inode = path->dentry->d_inode;
 		if (!reverse_transit &&
 		     unlikely(managed_dentry_might_block(path->dentry)))
 			return false;
@@ -1027,6 +1026,12 @@
 		path->mnt = mounted;
 		path->dentry = mounted->mnt_root;
 		nd->seq = read_seqcount_begin(&path->dentry->d_seq);
+		/*
+		 * Update the inode too. We don't need to re-check the
+		 * dentry sequence number here after this d_inode read,
+		 * because a mount-point is always pinned.
+		 */
+		*inode = path->dentry->d_inode;
 	}
 
 	if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
diff -druN linux-2.6.39.3-libre/fs/nfs/nfs4xdr.c linux-2.6.39.4-libre/fs/nfs/nfs4xdr.c
--- linux-2.6.39.3-libre/fs/nfs/nfs4xdr.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/nfs/nfs4xdr.c	2011-08-03 15:43:28.000000000 -0400
@@ -91,7 +91,7 @@
 #define encode_getfh_maxsz      (op_encode_hdr_maxsz)
 #define decode_getfh_maxsz      (op_decode_hdr_maxsz + 1 + \
 				((3+NFS4_FHSIZE) >> 2))
-#define nfs4_fattr_bitmap_maxsz 3
+#define nfs4_fattr_bitmap_maxsz 4
 #define encode_getattr_maxsz    (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
 #define nfs4_name_maxsz		(1 + ((3 + NFS4_MAXNAMLEN) >> 2))
 #define nfs4_path_maxsz		(1 + ((3 + NFS4_MAXPATHLEN) >> 2))
diff -druN linux-2.6.39.3-libre/fs/partitions/efi.c linux-2.6.39.4-libre/fs/partitions/efi.c
--- linux-2.6.39.3-libre/fs/partitions/efi.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/partitions/efi.c	2011-08-03 15:43:28.000000000 -0400
@@ -310,6 +310,15 @@
 		goto fail;
 	}
 
+	/* Check the GUID Partition Table header size */
+	if (le32_to_cpu((*gpt)->header_size) >
+			bdev_logical_block_size(state->bdev)) {
+		pr_debug("GUID Partition Table Header size is wrong: %u > %u\n",
+			le32_to_cpu((*gpt)->header_size),
+			bdev_logical_block_size(state->bdev));
+		goto fail;
+	}
+
 	/* Check the GUID Partition Table CRC */
 	origcrc = le32_to_cpu((*gpt)->header_crc32);
 	(*gpt)->header_crc32 = 0;
diff -druN linux-2.6.39.3-libre/fs/proc/base.c linux-2.6.39.4-libre/fs/proc/base.c
--- linux-2.6.39.3-libre/fs/proc/base.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/proc/base.c	2011-08-03 15:43:28.000000000 -0400
@@ -2762,6 +2762,9 @@
 	struct task_io_accounting acct = task->ioac;
 	unsigned long flags;
 
+	if (!ptrace_may_access(task, PTRACE_MODE_READ))
+		return -EACCES;
+
 	if (whole && lock_task_sighand(task, &flags)) {
 		struct task_struct *t = task;
 
@@ -2892,7 +2895,7 @@
 	REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
 #endif
 #ifdef CONFIG_TASK_IO_ACCOUNTING
-	INF("io",	S_IRUGO, proc_tgid_io_accounting),
+	INF("io",	S_IRUSR, proc_tgid_io_accounting),
 #endif
 };
 
@@ -3230,7 +3233,7 @@
 	REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
 #endif
 #ifdef CONFIG_TASK_IO_ACCOUNTING
-	INF("io",	S_IRUGO, proc_tid_io_accounting),
+	INF("io",	S_IRUSR, proc_tid_io_accounting),
 #endif
 };
 
diff -druN linux-2.6.39.3-libre/fs/xfs/xfs_alloc.c linux-2.6.39.4-libre/fs/xfs/xfs_alloc.c
--- linux-2.6.39.3-libre/fs/xfs/xfs_alloc.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/fs/xfs/xfs_alloc.c	2011-08-03 15:43:28.000000000 -0400
@@ -2610,6 +2610,12 @@
 					new->bno + new->length) -
 				min(busyp->bno, new->bno);
 		new->bno = min(busyp->bno, new->bno);
+		/*
+		 * Start the search over from the tree root, because
+		 * erasing the node can rearrange the tree topology.
+		 */
+		spin_unlock(&pag->pagb_lock);
+		goto restart;
 	} else
 		busyp = NULL;
 
diff -druN linux-2.6.39.3-libre/include/drm/drm_pciids.h linux-2.6.39.4-libre/include/drm/drm_pciids.h
--- linux-2.6.39.3-libre/include/drm/drm_pciids.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/include/drm/drm_pciids.h	2011-08-03 15:43:28.000000000 -0400
@@ -182,6 +182,7 @@
 	{0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
@@ -192,6 +193,7 @@
 	{0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
diff -druN linux-2.6.39.3-libre/include/linux/netdevice.h linux-2.6.39.4-libre/include/linux/netdevice.h
--- linux-2.6.39.3-libre/include/linux/netdevice.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/include/linux/netdevice.h	2011-08-03 15:43:28.000000000 -0400
@@ -1680,9 +1680,12 @@
 static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
 					unsigned int offset)
 {
+	if (!pskb_may_pull(skb, hlen))
+		return NULL;
+
 	NAPI_GRO_CB(skb)->frag0 = NULL;
 	NAPI_GRO_CB(skb)->frag0_len = 0;
-	return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
+	return skb->data + offset;
 }
 
 static inline void *skb_gro_mac_header(struct sk_buff *skb)
diff -druN linux-2.6.39.3-libre/Makefile linux-2.6.39.4-libre/Makefile
--- linux-2.6.39.3-libre/Makefile	2011-07-09 23:26:40.000000000 -0400
+++ linux-2.6.39.4-libre/Makefile	2011-08-04 00:18:11.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 39
-EXTRAVERSION = .3-libre
+EXTRAVERSION = .4-libre
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
diff -druN linux-2.6.39.3-libre/mm/compaction.c linux-2.6.39.4-libre/mm/compaction.c
--- linux-2.6.39.3-libre/mm/compaction.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/mm/compaction.c	2011-08-03 15:43:28.000000000 -0400
@@ -144,9 +144,20 @@
 	int nr_freepages = cc->nr_freepages;
 	struct list_head *freelist = &cc->freepages;
 
+	/*
+	 * Initialise the free scanner. The starting point is where we last
+	 * scanned from (or the end of the zone if starting). The low point
+	 * is the end of the pageblock the migration scanner is using.
+	 */
 	pfn = cc->free_pfn;
 	low_pfn = cc->migrate_pfn + pageblock_nr_pages;
-	high_pfn = low_pfn;
+
+	/*
+	 * Take care that if the migration scanner is at the end of the zone
+	 * that the free scanner does not accidentally move to the next zone
+	 * in the next isolation cycle.
+	 */
+	high_pfn = min(low_pfn, pfn);
 
 	/*
 	 * Isolate free pages until enough are available to migrate the
@@ -240,11 +251,18 @@
 	return isolated > (inactive + active) / 2;
 }
 
+/* possible outcome of isolate_migratepages */
+typedef enum {
+	ISOLATE_ABORT,		/* Abort compaction now */
+	ISOLATE_NONE,		/* No pages isolated, continue scanning */
+	ISOLATE_SUCCESS,	/* Pages isolated, migrate */
+} isolate_migrate_t;
+
 /*
  * Isolate all pages that can be migrated from the block pointed to by
  * the migrate scanner within compact_control.
  */
-static unsigned long isolate_migratepages(struct zone *zone,
+static isolate_migrate_t isolate_migratepages(struct zone *zone,
 					struct compact_control *cc)
 {
 	unsigned long low_pfn, end_pfn;
@@ -261,7 +279,7 @@
 	/* Do not cross the free scanner or scan within a memory hole */
 	if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) {
 		cc->migrate_pfn = end_pfn;
-		return 0;
+		return ISOLATE_NONE;
 	}
 
 	/*
@@ -270,10 +288,14 @@
 	 * delay for some time until fewer pages are isolated
 	 */
 	while (unlikely(too_many_isolated(zone))) {
+		/* async migration should just abort */
+		if (!cc->sync)
+			return ISOLATE_ABORT;
+
 		congestion_wait(BLK_RW_ASYNC, HZ/10);
 
 		if (fatal_signal_pending(current))
-			return 0;
+			return ISOLATE_ABORT;
 	}
 
 	/* Time to isolate some pages for migration */
@@ -358,7 +380,7 @@
 
 	trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
 
-	return cc->nr_migratepages;
+	return ISOLATE_SUCCESS;
 }
 
 /*
@@ -522,8 +544,15 @@
 		unsigned long nr_migrate, nr_remaining;
 		int err;
 
-		if (!isolate_migratepages(zone, cc))
+		switch (isolate_migratepages(zone, cc)) {
+		case ISOLATE_ABORT:
+			ret = COMPACT_PARTIAL;
+			goto out;
+		case ISOLATE_NONE:
 			continue;
+		case ISOLATE_SUCCESS:
+			;
+		}
 
 		nr_migrate = cc->nr_migratepages;
 		err = migrate_pages(&cc->migratepages, compaction_alloc,
@@ -547,6 +576,7 @@
 
 	}
 
+out:
 	/* Release free pages and check accounting */
 	cc->nr_freepages -= release_freepages(&cc->freepages);
 	VM_BUG_ON(cc->nr_freepages != 0);
diff -druN linux-2.6.39.3-libre/mm/nommu.c linux-2.6.39.4-libre/mm/nommu.c
--- linux-2.6.39.3-libre/mm/nommu.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/mm/nommu.c	2011-08-03 15:43:28.000000000 -0400
@@ -1819,10 +1819,13 @@
 	return NULL;
 }
 
-int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-		unsigned long to, unsigned long size, pgprot_t prot)
+int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
+		unsigned long pfn, unsigned long size, pgprot_t prot)
 {
-	vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
+	if (addr != (pfn << PAGE_SHIFT))
+		return -EINVAL;
+
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
 	return 0;
 }
 EXPORT_SYMBOL(remap_pfn_range);
diff -druN linux-2.6.39.3-libre/mm/oom_kill.c linux-2.6.39.4-libre/mm/oom_kill.c
--- linux-2.6.39.3-libre/mm/oom_kill.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/mm/oom_kill.c	2011-08-03 15:43:28.000000000 -0400
@@ -285,7 +285,7 @@
 	do_each_thread(g, p) {
 		unsigned int points;
 
-		if (!p->mm)
+		if (p->exit_state)
 			continue;
 		if (oom_unkillable_task(p, mem, nodemask))
 			continue;
@@ -301,6 +301,8 @@
 		 */
 		if (test_tsk_thread_flag(p, TIF_MEMDIE))
 			return ERR_PTR(-1UL);
+		if (!p->mm)
+			continue;
 
 		if (p->flags & PF_EXITING) {
 			/*
diff -druN linux-2.6.39.3-libre/mm/vmscan.c linux-2.6.39.4-libre/mm/vmscan.c
--- linux-2.6.39.3-libre/mm/vmscan.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/mm/vmscan.c	2011-08-03 15:43:28.000000000 -0400
@@ -1114,8 +1114,20 @@
 					nr_lumpy_dirty++;
 				scan++;
 			} else {
-				/* the page is freed already. */
-				if (!page_count(cursor_page))
+				/*
+				 * Check if the page is freed already.
+				 *
+				 * We can't use page_count() as that
+				 * requires compound_head and we don't
+				 * have a pin on the page here. If a
+				 * page is tail, we may or may not
+				 * have isolated the head, so assume
+				 * it's not free, it'd be tricky to
+				 * track the head status without a
+				 * page pin.
+				 */
+				if (!PageTail(cursor_page) &&
+				    !atomic_read(&cursor_page->_count))
 					continue;
 				break;
 			}
@@ -2245,7 +2257,8 @@
 	for (i = 0; i <= classzone_idx; i++)
 		present_pages += pgdat->node_zones[i].present_pages;
 
-	return balanced_pages > (present_pages >> 2);
+	/* A special case here: if zone has no page, we think it's balanced */
+	return balanced_pages >= (present_pages >> 2);
 }
 
 /* is kswapd sleeping prematurely? */
@@ -2261,7 +2274,7 @@
 		return true;
 
 	/* Check the watermark levels */
-	for (i = 0; i < pgdat->nr_zones; i++) {
+	for (i = 0; i <= classzone_idx; i++) {
 		struct zone *zone = pgdat->node_zones + i;
 
 		if (!populated_zone(zone))
@@ -2279,7 +2292,7 @@
 		}
 
 		if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
-							classzone_idx, 0))
+							i, 0))
 			all_zones_ok = false;
 		else
 			balanced += zone->present_pages;
@@ -2381,7 +2394,6 @@
 			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone), 0, 0)) {
 				end_zone = i;
-				*classzone_idx = i;
 				break;
 			}
 		}
@@ -2436,19 +2448,19 @@
 				KSWAPD_ZONE_BALANCE_GAP_RATIO);
 			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone) + balance_gap,
-					end_zone, 0))
+					end_zone, 0)) {
 				shrink_zone(priority, zone, &sc);
-			reclaim_state->reclaimed_slab = 0;
-			nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
-						lru_pages);
-			sc.nr_reclaimed += reclaim_state->reclaimed_slab;
-			total_scanned += sc.nr_scanned;
 
-			if (zone->all_unreclaimable)
-				continue;
-			if (nr_slab == 0 &&
-			    !zone_reclaimable(zone))
-				zone->all_unreclaimable = 1;
+				reclaim_state->reclaimed_slab = 0;
+				nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
+							lru_pages);
+				sc.nr_reclaimed += reclaim_state->reclaimed_slab;
+				total_scanned += sc.nr_scanned;
+
+				if (nr_slab == 0 && !zone_reclaimable(zone))
+					zone->all_unreclaimable = 1;
+			}
+
 			/*
 			 * If we've done a decent amount of scanning and
 			 * the reclaim ratio is low, start doing writepage
@@ -2458,6 +2470,12 @@
 			    total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
 				sc.may_writepage = 1;
 
+			if (zone->all_unreclaimable) {
+				if (end_zone && end_zone == i)
+					end_zone--;
+				continue;
+			}
+
 			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone), end_zone, 0)) {
 				all_zones_ok = 0;
@@ -2636,8 +2654,8 @@
  */
 static int kswapd(void *p)
 {
-	unsigned long order;
-	int classzone_idx;
+	unsigned long order, new_order;
+	int classzone_idx, new_classzone_idx;
 	pg_data_t *pgdat = (pg_data_t*)p;
 	struct task_struct *tsk = current;
 
@@ -2667,17 +2685,23 @@
 	tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
 	set_freezable();
 
-	order = 0;
-	classzone_idx = MAX_NR_ZONES - 1;
+	order = new_order = 0;
+	classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
 	for ( ; ; ) {
-		unsigned long new_order;
-		int new_classzone_idx;
 		int ret;
 
-		new_order = pgdat->kswapd_max_order;
-		new_classzone_idx = pgdat->classzone_idx;
-		pgdat->kswapd_max_order = 0;
-		pgdat->classzone_idx = MAX_NR_ZONES - 1;
+		/*
+		 * If the last balance_pgdat was unsuccessful it's unlikely a
+		 * new request of a similar or harder type will succeed soon
+		 * so consider going to sleep on the basis we reclaimed at
+		 */
+		if (classzone_idx >= new_classzone_idx && order == new_order) {
+			new_order = pgdat->kswapd_max_order;
+			new_classzone_idx = pgdat->classzone_idx;
+			pgdat->kswapd_max_order =  0;
+			pgdat->classzone_idx = pgdat->nr_zones - 1;
+		}
+
 		if (order < new_order || classzone_idx > new_classzone_idx) {
 			/*
 			 * Don't sleep if someone wants a larger 'order'
@@ -2690,7 +2714,7 @@
 			order = pgdat->kswapd_max_order;
 			classzone_idx = pgdat->classzone_idx;
 			pgdat->kswapd_max_order = 0;
-			pgdat->classzone_idx = MAX_NR_ZONES - 1;
+			pgdat->classzone_idx = pgdat->nr_zones - 1;
 		}
 
 		ret = try_to_freeze();
diff -druN linux-2.6.39.3-libre/net/bridge/br_private.h linux-2.6.39.4-libre/net/bridge/br_private.h
--- linux-2.6.39.3-libre/net/bridge/br_private.h	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/net/bridge/br_private.h	2011-08-03 15:43:28.000000000 -0400
@@ -123,6 +123,7 @@
 	bridge_id			designated_bridge;
 	u32				path_cost;
 	u32				designated_cost;
+	unsigned long			designated_age;
 
 	struct timer_list		forward_delay_timer;
 	struct timer_list		hold_timer;
diff -druN linux-2.6.39.3-libre/net/bridge/br_stp.c linux-2.6.39.4-libre/net/bridge/br_stp.c
--- linux-2.6.39.3-libre/net/bridge/br_stp.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/net/bridge/br_stp.c	2011-08-03 15:43:28.000000000 -0400
@@ -164,8 +164,7 @@
 	else {
 		struct net_bridge_port *root
 			= br_get_port(br, br->root_port);
-		bpdu.message_age = br->max_age
-			- (root->message_age_timer.expires - jiffies)
+		bpdu.message_age = (jiffies - root->designated_age)
 			+ MESSAGE_AGE_INCR;
 	}
 	bpdu.max_age = br->max_age;
@@ -189,6 +188,7 @@
 	p->designated_cost = bpdu->root_path_cost;
 	p->designated_bridge = bpdu->bridge_id;
 	p->designated_port = bpdu->port_id;
+	p->designated_age = jiffies + bpdu->message_age;
 
 	mod_timer(&p->message_age_timer, jiffies
 		  + (p->br->max_age - bpdu->message_age));
diff -druN linux-2.6.39.3-libre/net/mac80211/wpa.c linux-2.6.39.4-libre/net/mac80211/wpa.c
--- linux-2.6.39.3-libre/net/mac80211/wpa.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/net/mac80211/wpa.c	2011-08-03 15:43:28.000000000 -0400
@@ -86,6 +86,11 @@
 	struct sk_buff *skb = rx->skb;
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	int queue = rx->queue;
+
+	/* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
+	if (rx->queue == NUM_RX_DATA_QUEUES - 1)
+		queue = 0;
 
 	/* No way to verify the MIC if the hardware stripped it */
 	if (status->flag & RX_FLAG_MMIC_STRIPPED)
@@ -119,8 +124,8 @@
 	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 
 	/* update IV in key information to be able to detect replays */
-	rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
-	rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
+	rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32;
+	rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16;
 
 	return RX_CONTINUE;
 }
@@ -201,6 +206,11 @@
 	struct ieee80211_key *key = rx->key;
 	struct sk_buff *skb = rx->skb;
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+	int queue = rx->queue;
+
+	/* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
+	if (rx->queue == NUM_RX_DATA_QUEUES - 1)
+		queue = 0;
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
@@ -221,7 +231,7 @@
 	res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
 					  key, skb->data + hdrlen,
 					  skb->len - hdrlen, rx->sta->sta.addr,
-					  hdr->addr1, hwaccel, rx->queue,
+					  hdr->addr1, hwaccel, queue,
 					  &rx->tkip_iv32,
 					  &rx->tkip_iv16);
 	if (res != TKIP_DECRYPT_OK)
diff -druN linux-2.6.39.3-libre/net/sunrpc/rpcb_clnt.c linux-2.6.39.4-libre/net/sunrpc/rpcb_clnt.c
--- linux-2.6.39.3-libre/net/sunrpc/rpcb_clnt.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/net/sunrpc/rpcb_clnt.c	2011-08-03 15:43:28.000000000 -0400
@@ -528,7 +528,7 @@
 	u32 bind_version;
 	struct rpc_xprt *xprt;
 	struct rpc_clnt	*rpcb_clnt;
-	static struct rpcbind_args *map;
+	struct rpcbind_args *map;
 	struct rpc_task	*child;
 	struct sockaddr_storage addr;
 	struct sockaddr *sap = (struct sockaddr *)&addr;
diff -druN linux-2.6.39.3-libre/net/sunrpc/sched.c linux-2.6.39.4-libre/net/sunrpc/sched.c
--- linux-2.6.39.3-libre/net/sunrpc/sched.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/net/sunrpc/sched.c	2011-08-03 15:43:28.000000000 -0400
@@ -616,30 +616,25 @@
 	BUG_ON(RPC_IS_QUEUED(task));
 
 	for (;;) {
+		void (*do_action)(struct rpc_task *);
 
 		/*
-		 * Execute any pending callback.
+		 * Execute any pending callback first.
 		 */
-		if (task->tk_callback) {
-			void (*save_callback)(struct rpc_task *);
-
-			/*
-			 * We set tk_callback to NULL before calling it,
-			 * in case it sets the tk_callback field itself:
-			 */
-			save_callback = task->tk_callback;
-			task->tk_callback = NULL;
-			save_callback(task);
-		} else {
+		do_action = task->tk_callback;
+		task->tk_callback = NULL;
+		if (do_action == NULL) {
 			/*
 			 * Perform the next FSM step.
-			 * tk_action may be NULL when the task has been killed
-			 * by someone else.
+			 * tk_action may be NULL if the task has been killed.
+			 * In particular, note that rpc_killall_tasks may
+			 * do this at any time, so beware when dereferencing.
 			 */
-			if (task->tk_action == NULL)
+			do_action = task->tk_action;
+			if (do_action == NULL)
 				break;
-			task->tk_action(task);
 		}
+		do_action(task);
 
 		/*
 		 * Lockless check for whether task is sleeping or not.
diff -druN linux-2.6.39.3-libre/sound/soc/blackfin/bf5xx-i2s-pcm.c linux-2.6.39.4-libre/sound/soc/blackfin/bf5xx-i2s-pcm.c
--- linux-2.6.39.3-libre/sound/soc/blackfin/bf5xx-i2s-pcm.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/sound/soc/blackfin/bf5xx-i2s-pcm.c	2011-08-03 15:43:28.000000000 -0400
@@ -138,11 +138,20 @@
 	pr_debug("%s enter\n", __func__);
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		diff = sport_curr_offset_tx(sport);
-		frames = bytes_to_frames(substream->runtime, diff);
 	} else {
 		diff = sport_curr_offset_rx(sport);
-		frames = bytes_to_frames(substream->runtime, diff);
 	}
+
+	/*
+	 * TX at least can report one frame beyond the end of the
+	 * buffer if we hit the wraparound case - clamp to within the
+	 * buffer as the ALSA APIs require.
+	 */
+	if (diff == snd_pcm_lib_buffer_bytes(substream))
+		diff = 0;
+
+	frames = bytes_to_frames(substream->runtime, diff);
+
 	return frames;
 }
 
diff -druN linux-2.6.39.3-libre/sound/soc/codecs/ak4642.c linux-2.6.39.4-libre/sound/soc/codecs/ak4642.c
--- linux-2.6.39.3-libre/sound/soc/codecs/ak4642.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/sound/soc/codecs/ak4642.c	2011-08-03 15:43:28.000000000 -0400
@@ -357,7 +357,7 @@
 	default:
 		return -EINVAL;
 	}
-	snd_soc_update_bits(codec, PW_MGMT2, MS, data);
+	snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
 	snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
 
 	/* format type */
diff -druN linux-2.6.39.3-libre/sound/soc/codecs/wm8994.c linux-2.6.39.4-libre/sound/soc/codecs/wm8994.c
--- linux-2.6.39.3-libre/sound/soc/codecs/wm8994.c	2011-07-09 02:16:06.000000000 -0400
+++ linux-2.6.39.4-libre/sound/soc/codecs/wm8994.c	2011-08-03 15:43:28.000000000 -0400
@@ -1446,7 +1446,6 @@
 SND_SOC_DAPM_INPUT("DMIC2DAT"),
 SND_SOC_DAPM_INPUT("Clock"),
 
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
 SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
 		      SND_SOC_DAPM_PRE_PMU),
 
@@ -1765,8 +1764,10 @@
 	{ "AIF2DACDAT", NULL, "AIF1DACDAT" },
 	{ "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
 	{ "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
-	{ "MICBIAS", NULL, "CLK_SYS" },
-	{ "MICBIAS", NULL, "MICBIAS Supply" },
+	{ "MICBIAS1", NULL, "CLK_SYS" },
+	{ "MICBIAS1", NULL, "MICBIAS Supply" },
+	{ "MICBIAS2", NULL, "CLK_SYS" },
+	{ "MICBIAS2", NULL, "MICBIAS Supply" },
 };
 
 static const struct snd_soc_dapm_route wm8994_intercon[] = {
@@ -1969,6 +1970,8 @@
 		snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
 				    WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
 				    reg);
+
+		msleep(5);
 	}
 
 	wm8994->fll[id].in = freq_in;
@@ -3018,7 +3021,7 @@
 	report = SND_JACK_MICROPHONE;
 
 	/* Everything else is buttons; just assign slots */
-	if (status & 0x1c0)
+	if (status & 0x1c)
 		report |= SND_JACK_BTN_0;
 
 done:
