diff -druN linux-libre-3.2.21-gnu/arch/arm/plat-samsung/include/plat/map-s3c.h linux-libre-3.2.22-gnu/arch/arm/plat-samsung/include/plat/map-s3c.h
--- linux-libre-3.2.21-gnu/arch/arm/plat-samsung/include/plat/map-s3c.h	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/arch/arm/plat-samsung/include/plat/map-s3c.h	2012-07-04 00:44:35.000000000 -0400
@@ -22,7 +22,7 @@
 #define S3C24XX_VA_WATCHDOG	S3C_VA_WATCHDOG
 
 #define S3C2412_VA_SSMC		S3C_ADDR_CPU(0x00000000)
-#define S3C2412_VA_EBI		S3C_ADDR_CPU(0x00010000)
+#define S3C2412_VA_EBI		S3C_ADDR_CPU(0x00100000)
 
 #define S3C2410_PA_UART		(0x50000000)
 #define S3C24XX_PA_UART		S3C2410_PA_UART
diff -druN linux-libre-3.2.21-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h linux-libre-3.2.22-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h
--- linux-libre-3.2.21-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h	2012-07-04 00:44:35.000000000 -0400
@@ -24,7 +24,7 @@
 
 	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
 
-	if (s3c2410_wdtclk)
+	if (!IS_ERR(s3c2410_wdtclk))
 		clk_enable(s3c2410_wdtclk);
 
 	/* put initial values into count and data */
diff -druN linux-libre-3.2.21-gnu/arch/x86/include/asm/cpufeature.h linux-libre-3.2.22-gnu/arch/x86/include/asm/cpufeature.h
--- linux-libre-3.2.21-gnu/arch/x86/include/asm/cpufeature.h	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/arch/x86/include/asm/cpufeature.h	2012-07-04 00:44:35.000000000 -0400
@@ -175,7 +175,7 @@
 #define X86_FEATURE_XSAVEOPT	(7*32+ 4) /* Optimized Xsave */
 #define X86_FEATURE_PLN		(7*32+ 5) /* Intel Power Limit Notification */
 #define X86_FEATURE_PTS		(7*32+ 6) /* Intel Package Thermal Status */
-#define X86_FEATURE_DTS		(7*32+ 7) /* Digital Thermal Sensor */
+#define X86_FEATURE_DTHERM	(7*32+ 7) /* Digital Thermal Sensor */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
diff -druN linux-libre-3.2.21-gnu/arch/x86/include/asm/pgtable-3level.h linux-libre-3.2.22-gnu/arch/x86/include/asm/pgtable-3level.h
--- linux-libre-3.2.21-gnu/arch/x86/include/asm/pgtable-3level.h	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/arch/x86/include/asm/pgtable-3level.h	2012-07-04 00:44:35.000000000 -0400
@@ -31,6 +31,60 @@
 	ptep->pte_low = pte.pte_low;
 }
 
+#define pmd_read_atomic pmd_read_atomic
+/*
+ * pte_offset_map_lock on 32bit PAE kernels was reading the pmd_t with
+ * a "*pmdp" dereference done by gcc. Problem is, in certain places
+ * where pte_offset_map_lock is called, concurrent page faults are
+ * allowed, if the mmap_sem is hold for reading. An example is mincore
+ * vs page faults vs MADV_DONTNEED. On the page fault side
+ * pmd_populate rightfully does a set_64bit, but if we're reading the
+ * pmd_t with a "*pmdp" on the mincore side, a SMP race can happen
+ * because gcc will not read the 64bit of the pmd atomically. To fix
+ * this all places running pmd_offset_map_lock() while holding the
+ * mmap_sem in read mode, shall read the pmdp pointer using this
+ * function to know if the pmd is null nor not, and in turn to know if
+ * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd
+ * operations.
+ *
+ * Without THP if the mmap_sem is hold for reading, the pmd can only
+ * transition from null to not null while pmd_read_atomic runs. So
+ * we can always return atomic pmd values with this function.
+ *
+ * With THP if the mmap_sem is hold for reading, the pmd can become
+ * trans_huge or none or point to a pte (and in turn become "stable")
+ * at any time under pmd_read_atomic. We could read it really
+ * atomically here with a atomic64_read for the THP enabled case (and
+ * it would be a whole lot simpler), but to avoid using cmpxchg8b we
+ * only return an atomic pmdval if the low part of the pmdval is later
+ * found stable (i.e. pointing to a pte). And we're returning a none
+ * pmdval if the low part of the pmd is none. In some cases the high
+ * and low part of the pmdval returned may not be consistent if THP is
+ * enabled (the low part may point to previously mapped hugepage,
+ * while the high part may point to a more recently mapped hugepage),
+ * but pmd_none_or_trans_huge_or_clear_bad() only needs the low part
+ * of the pmd to be read atomically to decide if the pmd is unstable
+ * or not, with the only exception of when the low part of the pmd is
+ * zero in which case we return a none pmd.
+ */
+static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
+{
+	pmdval_t ret;
+	u32 *tmp = (u32 *)pmdp;
+
+	ret = (pmdval_t) (*tmp);
+	if (ret) {
+		/*
+		 * If the low part is null, we must not read the high part
+		 * or we can end up with a partial pmd.
+		 */
+		smp_rmb();
+		ret |= ((pmdval_t)*(tmp + 1)) << 32;
+	}
+
+	return (pmd_t) { ret };
+}
+
 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
 {
 	set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
diff -druN linux-libre-3.2.21-gnu/arch/x86/kernel/cpu/scattered.c linux-libre-3.2.22-gnu/arch/x86/kernel/cpu/scattered.c
--- linux-libre-3.2.21-gnu/arch/x86/kernel/cpu/scattered.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/arch/x86/kernel/cpu/scattered.c	2012-07-04 00:44:35.000000000 -0400
@@ -31,7 +31,7 @@
 	const struct cpuid_bit *cb;
 
 	static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
-		{ X86_FEATURE_DTS,		CR_EAX, 0, 0x00000006, 0 },
+		{ X86_FEATURE_DTHERM,		CR_EAX, 0, 0x00000006, 0 },
 		{ X86_FEATURE_IDA,		CR_EAX, 1, 0x00000006, 0 },
 		{ X86_FEATURE_ARAT,		CR_EAX, 2, 0x00000006, 0 },
 		{ X86_FEATURE_PLN,		CR_EAX, 4, 0x00000006, 0 },
diff -druN linux-libre-3.2.21-gnu/Documentation/stable_kernel_rules.txt linux-libre-3.2.22-gnu/Documentation/stable_kernel_rules.txt
--- linux-libre-3.2.21-gnu/Documentation/stable_kernel_rules.txt	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/Documentation/stable_kernel_rules.txt	2012-07-04 00:44:35.000000000 -0400
@@ -12,6 +12,12 @@
    marked CONFIG_BROKEN), an oops, a hang, data corruption, a real
    security issue, or some "oh, that's not good" issue.  In short, something
    critical.
+ - Serious issues as reported by a user of a distribution kernel may also
+   be considered if they fix a notable performance or interactivity issue.
+   As these fixes are not as obvious and have a higher risk of a subtle
+   regression they should only be submitted by a distribution kernel
+   maintainer and include an addendum linking to a bugzilla entry if it
+   exists and additional information on the user-visible impact.
  - New device IDs and quirks are also accepted.
  - No "theoretical race condition" issues, unless an explanation of how the
    race can be exploited is also provided.
diff -druN linux-libre-3.2.21-gnu/drivers/acpi/acpi_pad.c linux-libre-3.2.22-gnu/drivers/acpi/acpi_pad.c
--- linux-libre-3.2.21-gnu/drivers/acpi/acpi_pad.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/acpi/acpi_pad.c	2012-07-04 00:44:35.000000000 -0400
@@ -36,6 +36,7 @@
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
 #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
 static DEFINE_MUTEX(isolated_cpus_lock);
+static DEFINE_MUTEX(round_robin_lock);
 
 static unsigned long power_saving_mwait_eax;
 
@@ -107,7 +108,7 @@
 	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
 		return;
 
-	mutex_lock(&isolated_cpus_lock);
+	mutex_lock(&round_robin_lock);
 	cpumask_clear(tmp);
 	for_each_cpu(cpu, pad_busy_cpus)
 		cpumask_or(tmp, tmp, topology_thread_cpumask(cpu));
@@ -116,7 +117,7 @@
 	if (cpumask_empty(tmp))
 		cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
 	if (cpumask_empty(tmp)) {
-		mutex_unlock(&isolated_cpus_lock);
+		mutex_unlock(&round_robin_lock);
 		return;
 	}
 	for_each_cpu(cpu, tmp) {
@@ -131,7 +132,7 @@
 	tsk_in_cpu[tsk_index] = preferred_cpu;
 	cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
 	cpu_weight[preferred_cpu]++;
-	mutex_unlock(&isolated_cpus_lock);
+	mutex_unlock(&round_robin_lock);
 
 	set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
 }
diff -druN linux-libre-3.2.21-gnu/drivers/base/power/main.c linux-libre-3.2.22-gnu/drivers/base/power/main.c
--- linux-libre-3.2.21-gnu/drivers/base/power/main.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/base/power/main.c	2012-07-04 00:44:35.000000000 -0400
@@ -869,7 +869,7 @@
 	dpm_wait_for_children(dev, async);
 
 	if (async_error)
-		return 0;
+		goto Complete;
 
 	pm_runtime_get_noresume(dev);
 	if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
@@ -878,7 +878,7 @@
 	if (pm_wakeup_pending()) {
 		pm_runtime_put_sync(dev);
 		async_error = -EBUSY;
-		return 0;
+		goto Complete;
 	}
 
 	device_lock(dev);
@@ -926,6 +926,8 @@
 	}
 
 	device_unlock(dev);
+
+ Complete:
 	complete_all(&dev->power.completion);
 
 	if (error) {
diff -druN linux-libre-3.2.21-gnu/drivers/char/hw_random/atmel-rng.c linux-libre-3.2.22-gnu/drivers/char/hw_random/atmel-rng.c
--- linux-libre-3.2.21-gnu/drivers/char/hw_random/atmel-rng.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/char/hw_random/atmel-rng.c	2012-07-04 00:44:35.000000000 -0400
@@ -34,7 +34,7 @@
 	u32 *data = buf;
 
 	/* data ready? */
-	if (readl(trng->base + TRNG_ODATA) & 1) {
+	if (readl(trng->base + TRNG_ISR) & 1) {
 		*data = readl(trng->base + TRNG_ODATA);
 		/*
 		  ensure data ready is only set again AFTER the next data
diff -druN linux-libre-3.2.21-gnu/drivers/edac/i7core_edac.c linux-libre-3.2.22-gnu/drivers/edac/i7core_edac.c
--- linux-libre-3.2.21-gnu/drivers/edac/i7core_edac.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/edac/i7core_edac.c	2012-07-04 00:44:35.000000000 -0400
@@ -1932,12 +1932,6 @@
 	if (mce->bank != 8)
 		return NOTIFY_DONE;
 
-#ifdef CONFIG_SMP
-	/* Only handle if it is the right mc controller */
-	if (mce->socketid != pvt->i7core_dev->socket)
-		return NOTIFY_DONE;
-#endif
-
 	smp_rmb();
 	if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
 		smp_wmb();
@@ -2234,8 +2228,6 @@
 	if (pvt->enable_scrub)
 		disable_sdram_scrub_setting(mci);
 
-	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &i7_mce_dec);
-
 	/* Disable EDAC polling */
 	i7core_pci_ctl_release(pvt);
 
@@ -2336,8 +2328,6 @@
 	/* DCLK for scrub rate setting */
 	pvt->dclk_freq = get_dclk_freq();
 
-	atomic_notifier_chain_register(&x86_mce_decoder_chain, &i7_mce_dec);
-
 	return 0;
 
 fail0:
@@ -2481,8 +2471,10 @@
 
 	pci_rc = pci_register_driver(&i7core_driver);
 
-	if (pci_rc >= 0)
+	if (pci_rc >= 0) {
+		atomic_notifier_chain_register(&x86_mce_decoder_chain, &i7_mce_dec);
 		return 0;
+	}
 
 	i7core_printk(KERN_ERR, "Failed to register device with error %d.\n",
 		      pci_rc);
@@ -2498,6 +2490,7 @@
 {
 	debugf2("MC: " __FILE__ ": %s()\n", __func__);
 	pci_unregister_driver(&i7core_driver);
+	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &i7_mce_dec);
 }
 
 module_init(i7core_init);
diff -druN linux-libre-3.2.21-gnu/drivers/edac/sb_edac.c linux-libre-3.2.22-gnu/drivers/edac/sb_edac.c
--- linux-libre-3.2.21-gnu/drivers/edac/sb_edac.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/edac/sb_edac.c	2012-07-04 00:44:35.000000000 -0400
@@ -1661,9 +1661,6 @@
 	debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
 		__func__, mci, &sbridge_dev->pdev[0]->dev);
 
-	atomic_notifier_chain_unregister(&x86_mce_decoder_chain,
-					 &sbridge_mce_dec);
-
 	/* Remove MC sysfs nodes */
 	edac_mc_del_mc(mci->dev);
 
@@ -1731,8 +1728,6 @@
 		goto fail0;
 	}
 
-	atomic_notifier_chain_register(&x86_mce_decoder_chain,
-				       &sbridge_mce_dec);
 	return 0;
 
 fail0:
@@ -1861,8 +1856,10 @@
 
 	pci_rc = pci_register_driver(&sbridge_driver);
 
-	if (pci_rc >= 0)
+	if (pci_rc >= 0) {
+		atomic_notifier_chain_register(&x86_mce_decoder_chain, &sbridge_mce_dec);
 		return 0;
+	}
 
 	sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n",
 		      pci_rc);
@@ -1878,6 +1875,7 @@
 {
 	debugf2("MC: " __FILE__ ": %s()\n", __func__);
 	pci_unregister_driver(&sbridge_driver);
+	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &sbridge_mce_dec);
 }
 
 module_init(sbridge_init);
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/drm_edid.c linux-libre-3.2.22-gnu/drivers/gpu/drm/drm_edid.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/drm_edid.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/drm_edid.c	2012-07-04 00:44:35.000000000 -0400
@@ -585,7 +585,7 @@
 drm_monitor_supports_rb(struct edid *edid)
 {
 	if (edid->revision >= 4) {
-		bool ret;
+		bool ret = false;
 		drm_for_each_detailed_block((u8 *)edid, is_rb, &ret);
 		return ret;
 	}
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_gem.c linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_gem.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_gem.c	2012-07-04 00:44:35.000000000 -0400
@@ -3312,6 +3312,10 @@
 
 			if (ret == 0 && atomic_read(&dev_priv->mm.wedged))
 				ret = -EIO;
+		} else if (wait_for(i915_seqno_passed(ring->get_seqno(ring),
+						      seqno) ||
+				    atomic_read(&dev_priv->mm.wedged), 3000)) {
+			ret = -EBUSY;
 		}
 	}
 
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_irq.c linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_irq.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_irq.c	2012-07-04 00:44:35.000000000 -0400
@@ -424,6 +424,30 @@
 	mutex_unlock(&dev_priv->dev->struct_mutex);
 }
 
+static void gen6_queue_rps_work(struct drm_i915_private *dev_priv,
+				u32 pm_iir)
+{
+	unsigned long flags;
+
+	/*
+	 * IIR bits should never already be set because IMR should
+	 * prevent an interrupt from being shown in IIR. The warning
+	 * displays a case where we've unsafely cleared
+	 * dev_priv->pm_iir. Although missing an interrupt of the same
+	 * type is not a problem, it displays a problem in the logic.
+	 *
+	 * The mask bit in IMR is cleared by rps_work.
+	 */
+
+	spin_lock_irqsave(&dev_priv->rps_lock, flags);
+	dev_priv->pm_iir |= pm_iir;
+	I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
+	POSTING_READ(GEN6_PMIMR);
+	spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
+
+	queue_work(dev_priv->wq, &dev_priv->rps_work);
+}
+
 static void pch_irq_handler(struct drm_device *dev, u32 pch_iir)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -529,16 +553,8 @@
 		pch_irq_handler(dev, pch_iir);
 	}
 
-	if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
-		unsigned long flags;
-		spin_lock_irqsave(&dev_priv->rps_lock, flags);
-		WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
-		dev_priv->pm_iir |= pm_iir;
-		I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
-		POSTING_READ(GEN6_PMIMR);
-		spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
-		queue_work(dev_priv->wq, &dev_priv->rps_work);
-	}
+	if (pm_iir & GEN6_PM_DEFERRED_EVENTS)
+		gen6_queue_rps_work(dev_priv, pm_iir);
 
 	/* should clear PCH hotplug event before clear CPU irq */
 	I915_WRITE(SDEIIR, pch_iir);
@@ -634,25 +650,8 @@
 		i915_handle_rps_change(dev);
 	}
 
-	if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) {
-		/*
-		 * IIR bits should never already be set because IMR should
-		 * prevent an interrupt from being shown in IIR. The warning
-		 * displays a case where we've unsafely cleared
-		 * dev_priv->pm_iir. Although missing an interrupt of the same
-		 * type is not a problem, it displays a problem in the logic.
-		 *
-		 * The mask bit in IMR is cleared by rps_work.
-		 */
-		unsigned long flags;
-		spin_lock_irqsave(&dev_priv->rps_lock, flags);
-		WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
-		dev_priv->pm_iir |= pm_iir;
-		I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
-		POSTING_READ(GEN6_PMIMR);
-		spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
-		queue_work(dev_priv->wq, &dev_priv->rps_work);
-	}
+	if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS)
+		gen6_queue_rps_work(dev_priv, pm_iir);
 
 	/* should clear PCH hotplug event before clear CPU irq */
 	I915_WRITE(SDEIIR, pch_iir);
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_suspend.c linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/i915_suspend.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_suspend.c	2012-07-04 00:44:35.000000000 -0400
@@ -739,8 +739,11 @@
 	if (HAS_PCH_SPLIT(dev)) {
 		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
 		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
-		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
+		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
+		 * otherwise we get blank eDP screen after S3 on some machines
+		 */
 		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2);
+		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
 		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
 		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
 		I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/intel_display.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/intel_display.c	2012-07-04 00:44:35.000000000 -0400
@@ -2187,6 +2187,33 @@
 }
 
 static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+	struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	bool was_interruptible = dev_priv->mm.interruptible;
+	int ret;
+
+	wait_event(dev_priv->pending_flip_queue,
+		   atomic_read(&dev_priv->mm.wedged) ||
+		   atomic_read(&obj->pending_flip) == 0);
+
+	/* Big Hammer, we also need to ensure that any pending
+	 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+	 * current scanout is retired before unpinning the old
+	 * framebuffer.
+	 *
+	 * This should only fail upon a hung GPU, in which case we
+	 * can safely continue.
+	 */
+	dev_priv->mm.interruptible = false;
+	ret = i915_gem_object_finish_gpu(obj);
+	dev_priv->mm.interruptible = was_interruptible;
+
+	return ret;
+}
+
+static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		    struct drm_framebuffer *old_fb)
 {
@@ -2224,25 +2251,8 @@
 		return ret;
 	}
 
-	if (old_fb) {
-		struct drm_i915_private *dev_priv = dev->dev_private;
-		struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
-		wait_event(dev_priv->pending_flip_queue,
-			   atomic_read(&dev_priv->mm.wedged) ||
-			   atomic_read(&obj->pending_flip) == 0);
-
-		/* Big Hammer, we also need to ensure that any pending
-		 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
-		 * current scanout is retired before unpinning the old
-		 * framebuffer.
-		 *
-		 * This should only fail upon a hung GPU, in which case we
-		 * can safely continue.
-		 */
-		ret = i915_gem_object_finish_gpu(obj);
-		(void) ret;
-	}
+	if (old_fb)
+		intel_finish_fb(old_fb);
 
 	ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
 					 LEAVE_ATOMIC_MODE_SET);
@@ -3312,6 +3322,23 @@
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 	struct drm_device *dev = crtc->dev;
 
+	/* Flush any pending WAITs before we disable the pipe. Note that
+	 * we need to drop the struct_mutex in order to acquire it again
+	 * during the lowlevel dpms routines around a couple of the
+	 * operations. It does not look trivial nor desirable to move
+	 * that locking higher. So instead we leave a window for the
+	 * submission of further commands on the fb before we can actually
+	 * disable it. This race with userspace exists anyway, and we can
+	 * only rely on the pipe being disabled by userspace after it
+	 * receives the hotplug notification and has flushed any pending
+	 * batches.
+	 */
+	if (crtc->fb) {
+		mutex_lock(&dev->struct_mutex);
+		intel_finish_fb(crtc->fb);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
 	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 
 	if (crtc->fb) {
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2012-07-04 00:44:35.000000000 -0400
@@ -306,7 +306,7 @@
 
 	I915_WRITE_CTL(ring,
 			((ring->size - PAGE_SIZE) & RING_NR_PAGES)
-			| RING_REPORT_64K | RING_VALID);
+			| RING_VALID);
 
 	/* If the head is still not zero, the ring is dead */
 	if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
@@ -1157,18 +1157,6 @@
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long end;
-	u32 head;
-
-	/* If the reported head position has wrapped or hasn't advanced,
-	 * fallback to the slow and accurate path.
-	 */
-	head = intel_read_status_page(ring, 4);
-	if (head > ring->head) {
-		ring->head = head;
-		ring->space = ring_space(ring);
-		if (ring->space >= n)
-			return 0;
-	}
 
 	trace_i915_ring_wait_begin(ring);
 	end = jiffies + 3 * HZ;
diff -druN linux-libre-3.2.21-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c linux-libre-3.2.22-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c
--- linux-libre-3.2.21-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2012-07-04 00:44:35.000000000 -0400
@@ -499,7 +499,7 @@
 	nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
 
 	ret = drm_fb_helper_init(dev, &nfbdev->helper,
-				 nv_two_heads(dev) ? 2 : 1, 4);
+				 dev->mode_config.num_crtc, 4);
 	if (ret) {
 		kfree(nfbdev);
 		return ret;
diff -druN linux-libre-3.2.21-gnu/drivers/hwmon/applesmc.c linux-libre-3.2.22-gnu/drivers/hwmon/applesmc.c
--- linux-libre-3.2.21-gnu/drivers/hwmon/applesmc.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/hwmon/applesmc.c	2012-07-04 00:44:35.000000000 -0400
@@ -215,7 +215,7 @@
 	int i;
 
 	if (send_command(cmd) || send_argument(key)) {
-		pr_warn("%s: read arg fail\n", key);
+		pr_warn("%.4s: read arg fail\n", key);
 		return -EIO;
 	}
 
@@ -223,7 +223,7 @@
 
 	for (i = 0; i < len; i++) {
 		if (__wait_status(0x05)) {
-			pr_warn("%s: read data fail\n", key);
+			pr_warn("%.4s: read data fail\n", key);
 			return -EIO;
 		}
 		buffer[i] = inb(APPLESMC_DATA_PORT);
diff -druN linux-libre-3.2.21-gnu/drivers/hwmon/coretemp.c linux-libre-3.2.22-gnu/drivers/hwmon/coretemp.c
--- linux-libre-3.2.21-gnu/drivers/hwmon/coretemp.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/hwmon/coretemp.c	2012-07-04 00:44:35.000000000 -0400
@@ -660,7 +660,7 @@
 	 * sensors. We check this bit only, all the early CPUs
 	 * without thermal sensors will be filtered out.
 	 */
-	if (!cpu_has(c, X86_FEATURE_DTS))
+	if (!cpu_has(c, X86_FEATURE_DTHERM))
 		return;
 
 	if (!pdev) {
diff -druN linux-libre-3.2.21-gnu/drivers/md/dm-thin.c linux-libre-3.2.22-gnu/drivers/md/dm-thin.c
--- linux-libre-3.2.21-gnu/drivers/md/dm-thin.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/md/dm-thin.c	2012-07-04 00:44:35.000000000 -0400
@@ -288,8 +288,10 @@
 
 	hlist_del(&cell->list);
 
-	bio_list_add(inmates, cell->holder);
-	bio_list_merge(inmates, &cell->bios);
+	if (inmates) {
+		bio_list_add(inmates, cell->holder);
+		bio_list_merge(inmates, &cell->bios);
+	}
 
 	mempool_free(cell, prison->cell_pool);
 }
@@ -312,9 +314,10 @@
  */
 static void __cell_release_singleton(struct cell *cell, struct bio *bio)
 {
-	hlist_del(&cell->list);
 	BUG_ON(cell->holder != bio);
 	BUG_ON(!bio_list_empty(&cell->bios));
+
+	__cell_release(cell, NULL);
 }
 
 static void cell_release_singleton(struct cell *cell, struct bio *bio)
diff -druN linux-libre-3.2.21-gnu/drivers/media/dvb/siano/smsusb.c linux-libre-3.2.22-gnu/drivers/media/dvb/siano/smsusb.c
--- linux-libre-3.2.21-gnu/drivers/media/dvb/siano/smsusb.c	2012-06-19 21:13:47.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/media/dvb/siano/smsusb.c	2012-07-04 18:59:02.000000000 -0400
@@ -544,6 +544,8 @@
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0xc0a0),
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xf5a0),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ } /* Terminating entry */
 	};
 
diff -druN linux-libre-3.2.21-gnu/drivers/media/video/gspca/gspca.c linux-libre-3.2.22-gnu/drivers/media/video/gspca/gspca.c
--- linux-libre-3.2.21-gnu/drivers/media/video/gspca/gspca.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/media/video/gspca/gspca.c	2012-07-04 00:44:35.000000000 -0400
@@ -1697,7 +1697,7 @@
 				enum v4l2_buf_type buf_type)
 {
 	struct gspca_dev *gspca_dev = priv;
-	int ret;
+	int i, ret;
 
 	if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1728,6 +1728,8 @@
 	wake_up_interruptible(&gspca_dev->wq);
 
 	/* empty the transfer queues */
+	for (i = 0; i < gspca_dev->nframes; i++)
+		gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS;
 	atomic_set(&gspca_dev->fr_q, 0);
 	atomic_set(&gspca_dev->fr_i, 0);
 	gspca_dev->fr_o = 0;
diff -druN linux-libre-3.2.21-gnu/drivers/net/can/c_can/c_can.c linux-libre-3.2.22-gnu/drivers/net/can/c_can/c_can.c
--- linux-libre-3.2.21-gnu/drivers/net/can/c_can/c_can.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/can/c_can/c_can.c	2012-07-04 00:44:35.000000000 -0400
@@ -590,8 +590,8 @@
 	priv->write_reg(priv, &priv->regs->control,
 			CONTROL_ENABLE_AR);
 
-	if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY &
-					CAN_CTRLMODE_LOOPBACK)) {
+	if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
+	    (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
 		/* loopback + silent mode : useful for hot self-test */
 		priv->write_reg(priv, &priv->regs->control, CONTROL_EIE |
 				CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
diff -druN linux-libre-3.2.21-gnu/drivers/net/can/flexcan.c linux-libre-3.2.22-gnu/drivers/net/can/flexcan.c
--- linux-libre-3.2.21-gnu/drivers/net/can/flexcan.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/can/flexcan.c	2012-07-04 00:44:35.000000000 -0400
@@ -933,12 +933,12 @@
 	u32 clock_freq = 0;
 
 	if (pdev->dev.of_node) {
-		const u32 *clock_freq_p;
+		const __be32 *clock_freq_p;
 
 		clock_freq_p = of_get_property(pdev->dev.of_node,
 						"clock-frequency", NULL);
 		if (clock_freq_p)
-			clock_freq = *clock_freq_p;
+			clock_freq = be32_to_cpup(clock_freq_p);
 	}
 
 	if (!clock_freq) {
diff -druN linux-libre-3.2.21-gnu/drivers/net/ethernet/intel/e1000e/82571.c linux-libre-3.2.22-gnu/drivers/net/ethernet/intel/e1000e/82571.c
--- linux-libre-3.2.21-gnu/drivers/net/ethernet/intel/e1000e/82571.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/ethernet/intel/e1000e/82571.c	2012-07-04 00:44:35.000000000 -0400
@@ -2080,8 +2080,9 @@
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
-	.flags2			  = FLAG2_CHECK_PHY_HANG
+	.flags2			= FLAG2_CHECK_PHY_HANG
 				  | FLAG2_DISABLE_ASPM_L0S
+				  | FLAG2_DISABLE_ASPM_L1
 				  | FLAG2_NO_DISABLE_RX,
 	.pba			= 32,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
diff -druN linux-libre-3.2.21-gnu/drivers/net/ethernet/intel/e1000e/netdev.c linux-libre-3.2.22-gnu/drivers/net/ethernet/intel/e1000e/netdev.c
--- linux-libre-3.2.21-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2012-07-04 00:44:35.000000000 -0400
@@ -5132,14 +5132,6 @@
 		return -EINVAL;
 	}
 
-	/* 82573 Errata 17 */
-	if (((adapter->hw.mac.type == e1000_82573) ||
-	     (adapter->hw.mac.type == e1000_82574)) &&
-	    (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
-		adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
-		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
-	}
-
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
 		usleep_range(1000, 2000);
 	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
diff -druN linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/hw.c linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/hw.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/hw.c	2012-07-04 00:44:35.000000000 -0400
@@ -718,13 +718,25 @@
 
 u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+	int i = 0;
+
 	REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
 	udelay(100);
 	REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
 
-	while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
+	while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) {
+
 		udelay(100);
 
+		if (WARN_ON_ONCE(i >= 100)) {
+			ath_err(common, "PLL4 meaurement not done\n");
+			break;
+		}
+
+		i++;
+	}
+
 	return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
 }
 EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
diff -druN linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/main.c linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/main.c
--- linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/main.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/main.c	2012-07-04 00:44:35.000000000 -0400
@@ -1042,6 +1042,15 @@
 					    hw_pll_work.work);
 	u32 pll_sqsum;
 
+	/*
+	 * ensure that the PLL WAR is executed only
+	 * after the STA is associated (or) if the
+	 * beaconing had started in interfaces that
+	 * uses beacons.
+	 */
+	if (!(sc->sc_flags & SC_OP_BEACONS))
+		return;
+
 	if (AR_SREV_9485(sc->sc_ah)) {
 
 		ath9k_ps_wakeup(sc);
@@ -1486,15 +1495,6 @@
 		}
 	}
 
-	if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
-	    ((vif->type == NL80211_IFTYPE_ADHOC) &&
-	     sc->nvifs > 0)) {
-		ath_err(common, "Cannot create ADHOC interface when other"
-			" interfaces already exist.\n");
-		ret = -EINVAL;
-		goto out;
-	}
-
 	ath_dbg(common, ATH_DBG_CONFIG,
 		"Attach a VIF of type: %d\n", vif->type);
 
diff -druN linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/xmit.c linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-libre-3.2.21-gnu/drivers/net/wireless/ath/ath9k/xmit.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/xmit.c	2012-07-04 00:44:35.000000000 -0400
@@ -936,13 +936,13 @@
 		}
 
 		/* legacy rates */
+		rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
 		if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
 		    !(rate->flags & IEEE80211_RATE_ERP_G))
 			phy = WLAN_RC_PHY_CCK;
 		else
 			phy = WLAN_RC_PHY_OFDM;
 
-		rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
 		info->rates[i].Rate = rate->hw_value;
 		if (rate->hw_value_short) {
 			if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
diff -druN linux-libre-3.2.21-gnu/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c linux-libre-3.2.22-gnu/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
--- linux-libre-3.2.21-gnu/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c	2012-07-04 00:44:35.000000000 -0400
@@ -1777,6 +1777,7 @@
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUG
 static ssize_t iwl_dbgfs_log_event_read(struct file *file,
 					 char __user *user_buf,
 					 size_t count, loff_t *ppos)
@@ -1814,6 +1815,7 @@
 
 	return count;
 }
+#endif
 
 static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
 					char __user *user_buf,
@@ -1941,7 +1943,9 @@
 	return ret;
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUG
 DEBUGFS_READ_WRITE_FILE_OPS(log_event);
+#endif
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(fh_reg);
 DEBUGFS_READ_FILE_OPS(rx_queue);
@@ -1957,7 +1961,9 @@
 {
 	DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR);
 	DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR);
+#ifdef CONFIG_IWLWIFI_DEBUG
 	DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR);
+#endif
 	DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
 	DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
 	DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
diff -druN linux-libre-3.2.21-gnu/drivers/net/xen-netfront.c linux-libre-3.2.22-gnu/drivers/net/xen-netfront.c
--- linux-libre-3.2.21-gnu/drivers/net/xen-netfront.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/net/xen-netfront.c	2012-07-04 00:44:35.000000000 -0400
@@ -1922,14 +1922,14 @@
 
 	dev_dbg(&dev->dev, "%s\n", dev->nodename);
 
-	unregister_netdev(info->netdev);
-
 	xennet_disconnect_backend(info);
 
-	del_timer_sync(&info->rx_refill_timer);
-
 	xennet_sysfs_delif(info->netdev);
 
+	unregister_netdev(info->netdev);
+
+	del_timer_sync(&info->rx_refill_timer);
+
 	free_percpu(info->stats);
 
 	free_netdev(info->netdev);
diff -druN linux-libre-3.2.21-gnu/drivers/oprofile/oprofile_perf.c linux-libre-3.2.22-gnu/drivers/oprofile/oprofile_perf.c
--- linux-libre-3.2.21-gnu/drivers/oprofile/oprofile_perf.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/oprofile/oprofile_perf.c	2012-07-04 00:44:35.000000000 -0400
@@ -25,7 +25,7 @@
 static DEFINE_MUTEX(oprofile_perf_mutex);
 
 static struct op_counter_config *counter_config;
-static struct perf_event **perf_events[nr_cpumask_bits];
+static struct perf_event **perf_events[NR_CPUS];
 static int num_counters;
 
 /*
diff -druN linux-libre-3.2.21-gnu/drivers/staging/iio/adc/ad7606_core.c linux-libre-3.2.22-gnu/drivers/staging/iio/adc/ad7606_core.c
--- linux-libre-3.2.21-gnu/drivers/staging/iio/adc/ad7606_core.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/staging/iio/adc/ad7606_core.c	2012-07-04 00:44:35.000000000 -0400
@@ -241,6 +241,7 @@
 		.indexed = 1,				\
 		.channel = num,				\
 		.address = num,				\
+		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \
 		.scan_index = num,			\
 		.scan_type = IIO_ST('s', 16, 16, 0),	\
 	}
diff -druN linux-libre-3.2.21-gnu/drivers/staging/rtl8712/usb_intf.c linux-libre-3.2.22-gnu/drivers/staging/rtl8712/usb_intf.c
--- linux-libre-3.2.21-gnu/drivers/staging/rtl8712/usb_intf.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/staging/rtl8712/usb_intf.c	2012-07-04 00:44:35.000000000 -0400
@@ -102,6 +102,8 @@
 	/* - */
 	{USB_DEVICE(0x20F4, 0x646B)},
 	{USB_DEVICE(0x083A, 0xC512)},
+	{USB_DEVICE(0x25D4, 0x4CA1)},
+	{USB_DEVICE(0x25D4, 0x4CAB)},
 
 /* RTL8191SU */
 	/* Realtek */
diff -druN linux-libre-3.2.21-gnu/drivers/staging/rts_pstor/rtsx_transport.c linux-libre-3.2.22-gnu/drivers/staging/rts_pstor/rtsx_transport.c
--- linux-libre-3.2.21-gnu/drivers/staging/rts_pstor/rtsx_transport.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/staging/rts_pstor/rtsx_transport.c	2012-07-04 00:44:35.000000000 -0400
@@ -335,6 +335,7 @@
 	int sg_cnt, i, resid;
 	int err = 0;
 	long timeleft;
+	struct scatterlist *sg_ptr;
 	u32 val = TRIG_DMA;
 
 	if ((sg == NULL) || (num_sg <= 0) || !offset || !index)
@@ -371,7 +372,7 @@
 	sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir);
 
 	resid = size;
-
+	sg_ptr = sg;
 	chip->sgi = 0;
 	/* Usually the next entry will be @sg@ + 1, but if this sg element
 	 * is part of a chained scatterlist, it could jump to the start of
@@ -379,14 +380,14 @@
 	 * the proper sg
 	 */
 	for (i = 0; i < *index; i++)
-		sg = sg_next(sg);
+		sg_ptr = sg_next(sg_ptr);
 	for (i = *index; i < sg_cnt; i++) {
 		dma_addr_t addr;
 		unsigned int len;
 		u8 option;
 
-		addr = sg_dma_address(sg);
-		len = sg_dma_len(sg);
+		addr = sg_dma_address(sg_ptr);
+		len = sg_dma_len(sg_ptr);
 
 		RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
 			     (unsigned int)addr, len);
@@ -415,7 +416,7 @@
 		if (!resid)
 			break;
 
-		sg = sg_next(sg);
+		sg_ptr = sg_next(sg_ptr);
 	}
 
 	RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
diff -druN linux-libre-3.2.21-gnu/drivers/usb/serial/cp210x.c linux-libre-3.2.22-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-3.2.21-gnu/drivers/usb/serial/cp210x.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/usb/serial/cp210x.c	2012-07-04 00:44:35.000000000 -0400
@@ -93,6 +93,7 @@
 	{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
 	{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
 	{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+	{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
 	{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
 	{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
 	{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
@@ -134,7 +135,13 @@
 	{ USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
 	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 	{ USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
+	{ USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */
+	{ USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */
 	{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
+	{ USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */
+	{ USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */
+	{ USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */
+	{ USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */
 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
 	{ USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */
 	{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
@@ -146,7 +153,11 @@
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
 	{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
+	{ USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
+	{ USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
 	{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
+	{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
+	{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
 	{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
 	{ } /* Terminating Entry */
 };
diff -druN linux-libre-3.2.21-gnu/drivers/usb/serial/option.c linux-libre-3.2.22-gnu/drivers/usb/serial/option.c
--- linux-libre-3.2.21-gnu/drivers/usb/serial/option.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/drivers/usb/serial/option.c	2012-07-04 00:44:35.000000000 -0400
@@ -235,6 +235,7 @@
 #define NOVATELWIRELESS_PRODUCT_G1		0xA001
 #define NOVATELWIRELESS_PRODUCT_G1_M		0xA002
 #define NOVATELWIRELESS_PRODUCT_G2		0xA010
+#define NOVATELWIRELESS_PRODUCT_MC551		0xB001
 
 /* AMOI PRODUCTS */
 #define AMOI_VENDOR_ID				0x1614
@@ -496,6 +497,10 @@
 /* MediaTek products */
 #define MEDIATEK_VENDOR_ID			0x0e8d
 
+/* Cellient products */
+#define CELLIENT_VENDOR_ID			0x2692
+#define CELLIENT_PRODUCT_MEN200			0x9005
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
 		OPTION_BLACKLIST_NONE = 0,
@@ -730,6 +735,8 @@
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
+	/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
+	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
 
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -1227,6 +1234,7 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) },        /* MediaTek MT6276M modem & app port */
+	{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
diff -druN linux-libre-3.2.21-gnu/fs/nilfs2/gcinode.c linux-libre-3.2.22-gnu/fs/nilfs2/gcinode.c
--- linux-libre-3.2.21-gnu/fs/nilfs2/gcinode.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/fs/nilfs2/gcinode.c	2012-07-04 00:44:35.000000000 -0400
@@ -191,6 +191,8 @@
 	while (!list_empty(head)) {
 		ii = list_first_entry(head, struct nilfs_inode_info, i_dirty);
 		list_del_init(&ii->i_dirty);
+		truncate_inode_pages(&ii->vfs_inode.i_data, 0);
+		nilfs_btnode_cache_clear(&ii->i_btnode_cache);
 		iput(&ii->vfs_inode);
 	}
 }
diff -druN linux-libre-3.2.21-gnu/fs/nilfs2/segment.c linux-libre-3.2.22-gnu/fs/nilfs2/segment.c
--- linux-libre-3.2.21-gnu/fs/nilfs2/segment.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/fs/nilfs2/segment.c	2012-07-04 00:44:35.000000000 -0400
@@ -2309,6 +2309,8 @@
 		if (!test_bit(NILFS_I_UPDATED, &ii->i_state))
 			continue;
 		list_del_init(&ii->i_dirty);
+		truncate_inode_pages(&ii->vfs_inode.i_data, 0);
+		nilfs_btnode_cache_clear(&ii->i_btnode_cache);
 		iput(&ii->vfs_inode);
 	}
 }
diff -druN linux-libre-3.2.21-gnu/include/asm-generic/pgtable.h linux-libre-3.2.22-gnu/include/asm-generic/pgtable.h
--- linux-libre-3.2.21-gnu/include/asm-generic/pgtable.h	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/include/asm-generic/pgtable.h	2012-07-04 00:44:35.000000000 -0400
@@ -445,6 +445,18 @@
 #endif /* __HAVE_ARCH_PMD_WRITE */
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+#ifndef pmd_read_atomic
+static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
+{
+	/*
+	 * Depend on compiler for an atomic pmd read. NOTE: this is
+	 * only going to work, if the pmdval_t isn't larger than
+	 * an unsigned long.
+	 */
+	return *pmdp;
+}
+#endif
+
 /*
  * This function is meant to be used by sites walking pagetables with
  * the mmap_sem hold in read mode to protect against MADV_DONTNEED and
@@ -458,14 +470,30 @@
  * undefined so behaving like if the pmd was none is safe (because it
  * can return none anyway). The compiler level barrier() is critically
  * important to compute the two checks atomically on the same pmdval.
+ *
+ * For 32bit kernels with a 64bit large pmd_t this automatically takes
+ * care of reading the pmd atomically to avoid SMP race conditions
+ * against pmd_populate() when the mmap_sem is hold for reading by the
+ * caller (a special atomic read not done by "gcc" as in the generic
+ * version above, is also needed when THP is disabled because the page
+ * fault can populate the pmd from under us).
  */
 static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
 {
-	/* depend on compiler for an atomic pmd read */
-	pmd_t pmdval = *pmd;
+	pmd_t pmdval = pmd_read_atomic(pmd);
 	/*
 	 * The barrier will stabilize the pmdval in a register or on
 	 * the stack so that it will stop changing under the code.
+	 *
+	 * When CONFIG_TRANSPARENT_HUGEPAGE=y on x86 32bit PAE,
+	 * pmd_read_atomic is allowed to return a not atomic pmdval
+	 * (for example pointing to an hugepage that has never been
+	 * mapped in the pmd). The below checks will only care about
+	 * the low part of the pmd with 32bit PAE x86 anyway, with the
+	 * exception of pmd_none(). So the important thing is that if
+	 * the low part of the pmd is found null, the high part will
+	 * be also null or the pmd_none() check below would be
+	 * confused.
 	 */
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	barrier();
diff -druN linux-libre-3.2.21-gnu/Makefile linux-libre-3.2.22-gnu/Makefile
--- linux-libre-3.2.21-gnu/Makefile	2012-06-19 21:10:58.000000000 -0400
+++ linux-libre-3.2.22-gnu/Makefile	2012-07-04 18:56:06.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 21
+SUBLEVEL = 22
 EXTRAVERSION =-gnu
 NAME = Saber-toothed Squirrel
 
diff -druN linux-libre-3.2.21-gnu/net/batman-adv/routing.c linux-libre-3.2.22-gnu/net/batman-adv/routing.c
--- linux-libre-3.2.21-gnu/net/batman-adv/routing.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/net/batman-adv/routing.c	2012-07-04 00:44:35.000000000 -0400
@@ -619,6 +619,8 @@
 		/* packet needs to be linearized to access the TT changes */
 		if (skb_linearize(skb) < 0)
 			goto out;
+		/* skb_linearize() possibly changed skb->data */
+		tt_query = (struct tt_query_packet *)skb->data;
 
 		if (is_my_mac(tt_query->dst))
 			handle_tt_response(bat_priv, tt_query);
diff -druN linux-libre-3.2.21-gnu/net/batman-adv/translation-table.c linux-libre-3.2.22-gnu/net/batman-adv/translation-table.c
--- linux-libre-3.2.21-gnu/net/batman-adv/translation-table.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/net/batman-adv/translation-table.c	2012-07-04 00:44:35.000000000 -0400
@@ -1816,10 +1816,10 @@
 {
 	struct tt_local_entry *tt_local_entry = NULL;
 	struct tt_global_entry *tt_global_entry = NULL;
-	bool ret = true;
+	bool ret = false;
 
 	if (!atomic_read(&bat_priv->ap_isolation))
-		return false;
+		goto out;
 
 	tt_local_entry = tt_local_hash_find(bat_priv, dst);
 	if (!tt_local_entry)
@@ -1829,10 +1829,10 @@
 	if (!tt_global_entry)
 		goto out;
 
-	if (_is_ap_isolated(tt_local_entry, tt_global_entry))
+	if (!_is_ap_isolated(tt_local_entry, tt_global_entry))
 		goto out;
 
-	ret = false;
+	ret = true;
 
 out:
 	if (tt_global_entry)
diff -druN linux-libre-3.2.21-gnu/net/wireless/reg.c linux-libre-3.2.22-gnu/net/wireless/reg.c
--- linux-libre-3.2.21-gnu/net/wireless/reg.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/net/wireless/reg.c	2012-07-04 00:44:35.000000000 -0400
@@ -1369,7 +1369,7 @@
 	spin_unlock(&reg_requests_lock);
 
 	if (last_request->initiator == NL80211_REGDOM_SET_BY_USER)
-		cancel_delayed_work_sync(&reg_timeout);
+		cancel_delayed_work(&reg_timeout);
 
 	if (need_more_processing)
 		schedule_work(&reg_work);
diff -druN linux-libre-3.2.21-gnu/sound/pci/hda/patch_realtek.c linux-libre-3.2.22-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-3.2.21-gnu/sound/pci/hda/patch_realtek.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/sound/pci/hda/patch_realtek.c	2012-07-04 00:44:35.000000000 -0400
@@ -5988,6 +5988,7 @@
 	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
 	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
 	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
+	{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
 	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
 	  .patch = patch_alc861 },
 	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff -druN linux-libre-3.2.21-gnu/tools/hv/hv_kvp_daemon.c linux-libre-3.2.22-gnu/tools/hv/hv_kvp_daemon.c
--- linux-libre-3.2.21-gnu/tools/hv/hv_kvp_daemon.c	2012-06-19 18:18:30.000000000 -0400
+++ linux-libre-3.2.22-gnu/tools/hv/hv_kvp_daemon.c	2012-07-04 00:44:35.000000000 -0400
@@ -384,14 +384,18 @@
 	pfd.fd = fd;
 
 	while (1) {
+		struct sockaddr *addr_p = (struct sockaddr *) &addr;
+		socklen_t addr_l = sizeof(addr);
 		pfd.events = POLLIN;
 		pfd.revents = 0;
 		poll(&pfd, 1, -1);
 
-		len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0);
+		len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
+				addr_p, &addr_l);
 
-		if (len < 0) {
-			syslog(LOG_ERR, "recv failed; error:%d", len);
+		if (len < 0 || addr.nl_pid) {
+			syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
+					addr.nl_pid, errno, strerror(errno));
 			close(fd);
 			return -1;
 		}
