Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  sched: Fix rebalance interval calculation
  sched, doc: Beef up load balancing description
  sched: Leave sched_setscheduler() earlier if possible, do not disturb SCHED_FIFO tasks
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 7f399f9..139c018 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -412,7 +412,7 @@
 	pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
 
 	/* Don't force an interrupt if the irq has been disabled */
-	if (!irqd_irq_disabled(sn_irq_info->irq_irq) &&
+	if (!irqd_irq_disabled(irq_get_irq_data(sn_irq_info->irq_irq)) &&
 	    pci_provider && pci_provider->force_interrupt)
 		(*pci_provider->force_interrupt)(sn_irq_info);
 }
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index c76d8dc..7aab87f 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -45,38 +45,6 @@
 	return single_open(file, licenseID_show, NULL);
 }
 
-/*
- * Enable forced interrupt by default.
- * When set, the sn interrupt handler writes the force interrupt register on
- * the bridge chip.  The hardware will then send an interrupt message if the
- * interrupt line is active.  This mimics a level sensitive interrupt.
- */
-extern int sn_force_interrupt_flag;
-
-static int sn_force_interrupt_show(struct seq_file *s, void *p)
-{
-	seq_printf(s, "Force interrupt is %s\n",
-		sn_force_interrupt_flag ? "enabled" : "disabled");
-	return 0;
-}
-
-static ssize_t sn_force_interrupt_write_proc(struct file *file,
-		const char __user *buffer, size_t count, loff_t *data)
-{
-	char val;
-
-	if (copy_from_user(&val, buffer, 1))
-		return -EFAULT;
-
-	sn_force_interrupt_flag = (val == '0') ? 0 : 1;
-	return count;
-}
-
-static int sn_force_interrupt_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, sn_force_interrupt_show, NULL);
-}
-
 static int coherence_id_show(struct seq_file *s, void *p)
 {
 	seq_printf(s, "%d\n", partition_coherence_id());
@@ -114,14 +82,6 @@
 	.release	= single_release,
 };
 
-static const struct file_operations proc_sn_force_intr_fops = {
-	.open		= sn_force_interrupt_open,
-	.read		= seq_read,
-	.write		= sn_force_interrupt_write_proc,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
 static const struct file_operations proc_coherence_id_fops = {
 	.open		= coherence_id_open,
 	.read		= seq_read,
@@ -149,8 +109,6 @@
 	proc_create("system_serial_number", 0444, sgi_proc_dir,
 		    &proc_system_sn_fops);
 	proc_create("licenseID", 0444, sgi_proc_dir, &proc_license_id_fops);
-	proc_create("sn_force_interrupt", 0644, sgi_proc_dir,
-		    &proc_sn_force_intr_fops);
 	proc_create("coherence_id", 0444, sgi_proc_dir,
 		    &proc_coherence_id_fops);
 	proc_create("sn_topology", 0444, sgi_proc_dir, &proc_sn_topo_fops);
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index fe56a23..e4f0191 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -35,9 +35,9 @@
 	int   (*probe)(void);
 	void  (*kick_cpu)(int nr);
 	void  (*setup_cpu)(int nr);
+	void  (*bringup_done)(void);
 	void  (*take_timebase)(void);
 	void  (*give_timebase)(void);
-	int   (*cpu_enable)(unsigned int nr);
 	int   (*cpu_disable)(void);
 	void  (*cpu_die)(unsigned int nr);
 	int   (*cpu_bootable)(unsigned int nr);
@@ -267,7 +267,6 @@
 
 extern void e500_idle(void);
 extern void power4_idle(void);
-extern void power4_cpu_offline_powersave(void);
 extern void ppc6xx_idle(void);
 extern void book3e_idle(void);
 
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 66e237b..a902a0d 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -36,15 +36,16 @@
 
 extern void smp_send_debugger_break(int cpu);
 extern void smp_message_recv(int);
+extern void start_secondary_resume(void);
 
 DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
 #ifdef CONFIG_HOTPLUG_CPU
-extern void fixup_irqs(const struct cpumask *map);
+extern void migrate_irqs(void);
 int generic_cpu_disable(void);
-int generic_cpu_enable(unsigned int cpu);
 void generic_cpu_die(unsigned int cpu);
 void generic_mach_cpu_die(void);
+void generic_set_cpu_dead(unsigned int cpu);
 #endif
 
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 98c4b29..c5c24be 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -890,6 +890,15 @@
 	mtspr	SPRN_SRR1,r4
 	SYNC
 	RFI
+
+_GLOBAL(start_secondary_resume)
+	/* Reset stack */
+	rlwinm	r1,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+	li	r3,0
+	std	r3,0(r1)		/* Zero the stack frame pointer	*/
+	bl	start_secondary
+	b	.
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_KVM_BOOK3S_HANDLER
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 782f23d..271140b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -536,6 +536,13 @@
 	add	r13,r13,r4		/* for this processor.		*/
 	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG*/
 
+	/* Mark interrupts soft and hard disabled (they might be enabled
+	 * in the PACA when doing hotplug)
+	 */
+	li	r0,0
+	stb	r0,PACASOFTIRQEN(r13)
+	stb	r0,PACAHARDIRQEN(r13)
+
 	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
 	subi	r1,r1,STACK_FRAME_OVERHEAD
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 5328709..ba31954 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -53,24 +53,3 @@
 	isync
 	b	1b
 
-_GLOBAL(power4_cpu_offline_powersave)
-	/* Go to NAP now */
-	mfmsr	r7
-	rldicl	r0,r7,48,1
-	rotldi	r0,r0,16
-	mtmsrd	r0,1			/* hard-disable interrupts */
-	li	r0,1
-	li	r6,0
-	stb	r0,PACAHARDIRQEN(r13)	/* we'll hard-enable shortly */
-	stb	r6,PACASOFTIRQEN(r13)	/* soft-disable irqs */
-BEGIN_FTR_SECTION
-	DSSALL
-	sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-	ori	r7,r7,MSR_EE
-	oris	r7,r7,MSR_POW@h
-	sync
-	isync
-	mtmsrd	r7
-	isync
-	blr
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 63625e0..f621b7d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -246,12 +246,13 @@
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(const struct cpumask *map)
+void migrate_irqs(void)
 {
 	struct irq_desc *desc;
 	unsigned int irq;
 	static int warned;
 	cpumask_var_t mask;
+	const struct cpumask *map = cpu_online_mask;
 
 	alloc_cpumask_var(&mask, GFP_KERNEL);
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 9813605..cbdbb14 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,6 +57,25 @@
 #define DBG(fmt...)
 #endif
 
+
+/* Store all idle threads, this can be reused instead of creating
+* a new thread. Also avoids complicated thread destroy functionality
+* for idle threads.
+*/
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
+ * removed after init for !CONFIG_HOTPLUG_CPU.
+ */
+static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
+#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
+#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
+#else
+static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
+#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
+#endif
+
 struct thread_info *secondary_ti;
 
 DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
@@ -238,23 +257,6 @@
 	per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
 }
 
-static void __init smp_create_idle(unsigned int cpu)
-{
-	struct task_struct *p;
-
-	/* create a process for the processor */
-	p = fork_idle(cpu);
-	if (IS_ERR(p))
-		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-#ifdef CONFIG_PPC64
-	paca[cpu].__current = p;
-	paca[cpu].kstack = (unsigned long) task_thread_info(p)
-		+ THREAD_SIZE - STACK_FRAME_OVERHEAD;
-#endif
-	current_set[cpu] = task_thread_info(p);
-	task_thread_info(p)->cpu = cpu;
-}
-
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned int cpu;
@@ -288,10 +290,6 @@
 			max_cpus = NR_CPUS;
 	else
 		max_cpus = 1;
-
-	for_each_possible_cpu(cpu)
-		if (cpu != boot_cpuid)
-			smp_create_idle(cpu);
 }
 
 void __devinit smp_prepare_boot_cpu(void)
@@ -305,7 +303,7 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* State of each CPU during hotplug phases */
-DEFINE_PER_CPU(int, cpu_state) = { 0 };
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
 int generic_cpu_disable(void)
 {
@@ -317,30 +315,8 @@
 	set_cpu_online(cpu, false);
 #ifdef CONFIG_PPC64
 	vdso_data->processorCount--;
-	fixup_irqs(cpu_online_mask);
 #endif
-	return 0;
-}
-
-int generic_cpu_enable(unsigned int cpu)
-{
-	/* Do the normal bootup if we haven't
-	 * already bootstrapped. */
-	if (system_state != SYSTEM_RUNNING)
-		return -ENOSYS;
-
-	/* get the target out of it's holding state */
-	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
-	smp_wmb();
-
-	while (!cpu_online(cpu))
-		cpu_relax();
-
-#ifdef CONFIG_PPC64
-	fixup_irqs(cpu_online_mask);
-	/* counter the irq disable in fixup_irqs */
-	local_irq_enable();
-#endif
+	migrate_irqs();
 	return 0;
 }
 
@@ -362,37 +338,89 @@
 	unsigned int cpu;
 
 	local_irq_disable();
+	idle_task_exit();
 	cpu = smp_processor_id();
 	printk(KERN_DEBUG "CPU%d offline\n", cpu);
 	__get_cpu_var(cpu_state) = CPU_DEAD;
 	smp_wmb();
 	while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
 		cpu_relax();
-	set_cpu_online(cpu, true);
-	local_irq_enable();
+}
+
+void generic_set_cpu_dead(unsigned int cpu)
+{
+	per_cpu(cpu_state, cpu) = CPU_DEAD;
 }
 #endif
 
-static int __devinit cpu_enable(unsigned int cpu)
-{
-	if (smp_ops && smp_ops->cpu_enable)
-		return smp_ops->cpu_enable(cpu);
+struct create_idle {
+	struct work_struct work;
+	struct task_struct *idle;
+	struct completion done;
+	int cpu;
+};
 
-	return -ENOSYS;
+static void __cpuinit do_fork_idle(struct work_struct *work)
+{
+	struct create_idle *c_idle =
+		container_of(work, struct create_idle, work);
+
+	c_idle->idle = fork_idle(c_idle->cpu);
+	complete(&c_idle->done);
+}
+
+static int __cpuinit create_idle(unsigned int cpu)
+{
+	struct thread_info *ti;
+	struct create_idle c_idle = {
+		.cpu	= cpu,
+		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+	};
+	INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+
+	c_idle.idle = get_idle_for_cpu(cpu);
+
+	/* We can't use kernel_thread since we must avoid to
+	 * reschedule the child. We use a workqueue because
+	 * we want to fork from a kernel thread, not whatever
+	 * userspace process happens to be trying to online us.
+	 */
+	if (!c_idle.idle) {
+		schedule_work(&c_idle.work);
+		wait_for_completion(&c_idle.done);
+	} else
+		init_idle(c_idle.idle, cpu);
+	if (IS_ERR(c_idle.idle)) {		
+		pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
+		return PTR_ERR(c_idle.idle);
+	}
+	ti = task_thread_info(c_idle.idle);
+
+#ifdef CONFIG_PPC64
+	paca[cpu].__current = c_idle.idle;
+	paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
+#endif
+	ti->cpu = cpu;
+	current_set[cpu] = ti;
+
+	return 0;
 }
 
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-	int c;
+	int rc, c;
 
 	secondary_ti = current_set[cpu];
-	if (!cpu_enable(cpu))
-		return 0;
 
 	if (smp_ops == NULL ||
 	    (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
 		return -EINVAL;
 
+	/* Make sure we have an idle thread */
+	rc = create_idle(cpu);
+	if (rc)
+		return rc;
+
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
 	 * hotplug
 	 */
@@ -502,7 +530,7 @@
 }
 
 /* Activate a secondary processor. */
-int __devinit start_secondary(void *unused)
+void __devinit start_secondary(void *unused)
 {
 	unsigned int cpu = smp_processor_id();
 	struct device_node *l2_cache;
@@ -523,6 +551,10 @@
 
 	secondary_cpu_time_init();
 
+#ifdef CONFIG_PPC64
+	if (system_state == SYSTEM_RUNNING)
+		vdso_data->processorCount++;
+#endif
 	ipi_call_lock();
 	notify_cpu_starting(cpu);
 	set_cpu_online(cpu, true);
@@ -558,7 +590,8 @@
 	local_irq_enable();
 
 	cpu_idle();
-	return 0;
+
+	BUG();
 }
 
 int setup_profiling_timer(unsigned int multiplier)
@@ -585,7 +618,11 @@
 
 	free_cpumask_var(old_mask);
 
+	if (smp_ops && smp_ops->bringup_done)
+		smp_ops->bringup_done();
+
 	dump_numa_cpu_topology();
+
 }
 
 int arch_sd_sibling_asym_packing(void)
@@ -660,5 +697,9 @@
 {
 	if (ppc_md.cpu_die)
 		ppc_md.cpu_die();
+
+	/* If we return, we re-enter start_secondary */
+	start_secondary_resume();
 }
+
 #endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index aa92696..375480c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -577,14 +577,21 @@
 	struct clock_event_device *evt = &decrementer->event;
 	u64 now;
 
+	/* Ensure a positive value is written to the decrementer, or else
+	 * some CPUs will continue to take decrementer exceptions.
+	 */
+	set_dec(DECREMENTER_MAX);
+
+	/* Some implementations of hotplug will get timer interrupts while
+	 * offline, just ignore these
+	 */
+	if (!cpu_online(smp_processor_id()))
+		return;
+
 	trace_timer_interrupt_entry(regs);
 
 	__get_cpu_var(irq_stat).timer_irqs++;
 
-	/* Ensure a positive value is written to the decrementer, or else
-	 * some CPUs will continuue to take decrementer exceptions */
-	set_dec(DECREMENTER_MAX);
-
 #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index f0bc08f..20468f4 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -33,7 +33,6 @@
 extern void pmac_check_ht_link(void);
 
 extern void pmac_setup_smp(void);
-extern void pmac32_cpu_die(void);
 extern void low_cpu_die(void) __attribute__((noreturn));
 
 extern int pmac_nvram_init(void);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index d5aceb7..aa45281 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -650,51 +650,6 @@
 		return PCI_PROBE_NORMAL;
 	return PCI_PROBE_DEVTREE;
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
-/* access per cpu vars from generic smp.c */
-DECLARE_PER_CPU(int, cpu_state);
-
-static void pmac64_cpu_die(void)
-{
-	/*
-	 * turn off as much as possible, we'll be
-	 * kicked out as this will only be invoked
-	 * on core99 platforms for now ...
-	 */
-
-	printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
-	__get_cpu_var(cpu_state) = CPU_DEAD;
-	smp_wmb();
-
-	/*
-	 * during the path that leads here preemption is disabled,
-	 * reenable it now so that when coming up preempt count is
-	 * zero correctly
-	 */
-	preempt_enable();
-
-	/*
-	 * hard-disable interrupts for the non-NAP case, the NAP code
-	 * needs to re-enable interrupts (but soft-disables them)
-	 */
-	hard_irq_disable();
-
-	while (1) {
-		/* let's not take timer interrupts too often ... */
-		set_dec(0x7fffffff);
-
-		/* should always be true at this point */
-		if (cpu_has_feature(CPU_FTR_CAN_NAP))
-			power4_cpu_offline_powersave();
-		else {
-			HMT_low();
-			HMT_very_low();
-		}
-	}
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
 #endif /* CONFIG_PPC64 */
 
 define_machine(powermac) {
@@ -726,15 +681,4 @@
 	.pcibios_after_init	= pmac_pcibios_after_init,
 	.phys_mem_access_prot	= pci_phys_mem_access_prot,
 #endif
-#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_PPC64
-	.cpu_die		= pmac64_cpu_die,
-#endif
-#ifdef CONFIG_PPC32
-	.cpu_die		= pmac32_cpu_die,
-#endif
-#endif
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
-	.cpu_die		= generic_mach_cpu_die,
-#endif
 };
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index c95215f..a830c5e 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -840,92 +840,149 @@
 
 	/* Setup openpic */
 	mpic_setup_this_cpu();
-
-	if (cpu_nr == 0) {
-#ifdef CONFIG_PPC64
-		extern void g5_phy_disable_cpu1(void);
-
-		/* Close i2c bus if it was used for tb sync */
-		if (pmac_tb_clock_chip_host) {
-			pmac_i2c_close(pmac_tb_clock_chip_host);
-			pmac_tb_clock_chip_host	= NULL;
-		}
-
-		/* If we didn't start the second CPU, we must take
-		 * it off the bus
-		 */
-		if (of_machine_is_compatible("MacRISC4") &&
-		    num_online_cpus() < 2)		
-			g5_phy_disable_cpu1();
-#endif /* CONFIG_PPC64 */
-
-		if (ppc_md.progress)
-			ppc_md.progress("core99_setup_cpu 0 done", 0x349);
-	}
 }
 
-
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
-
-int smp_core99_cpu_disable(void)
+#ifdef CONFIG_HOTPLUG_CPU
+static int smp_core99_cpu_notify(struct notifier_block *self,
+				 unsigned long action, void *hcpu)
 {
-	set_cpu_online(smp_processor_id(), false);
+	int rc;
 
-	/* XXX reset cpu affinity here */
+	switch(action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		/* Open i2c bus if it was used for tb sync */
+		if (pmac_tb_clock_chip_host) {
+			rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
+			if (rc) {
+				pr_err("Failed to open i2c bus for time sync\n");
+				return notifier_from_errno(rc);
+			}
+		}
+		break;
+	case CPU_ONLINE:
+	case CPU_UP_CANCELED:
+		/* Close i2c bus if it was used for tb sync */
+		if (pmac_tb_clock_chip_host)
+			pmac_i2c_close(pmac_tb_clock_chip_host);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+	.notifier_call	= smp_core99_cpu_notify,
+};
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static void __init smp_core99_bringup_done(void)
+{
+#ifdef CONFIG_PPC64
+	extern void g5_phy_disable_cpu1(void);
+
+	/* Close i2c bus if it was used for tb sync */
+	if (pmac_tb_clock_chip_host)
+		pmac_i2c_close(pmac_tb_clock_chip_host);
+
+	/* If we didn't start the second CPU, we must take
+	 * it off the bus.
+	 */
+	if (of_machine_is_compatible("MacRISC4") &&
+	    num_online_cpus() < 2) {
+		set_cpu_present(1, false);
+		g5_phy_disable_cpu1();
+	}
+#endif /* CONFIG_PPC64 */
+
+#ifdef CONFIG_HOTPLUG_CPU
+	register_cpu_notifier(&smp_core99_cpu_nb);
+#endif
+	if (ppc_md.progress)
+		ppc_md.progress("smp_core99_bringup_done", 0x349);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int smp_core99_cpu_disable(void)
+{
+	int rc = generic_cpu_disable();
+	if (rc)
+		return rc;
+
 	mpic_cpu_set_priority(0xf);
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	mb();
-	udelay(20);
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
 	return 0;
 }
 
-static int cpu_dead[NR_CPUS];
+#ifdef CONFIG_PPC32
 
-void pmac32_cpu_die(void)
+static void pmac_cpu_die(void)
 {
+	int cpu = smp_processor_id();
+
 	local_irq_disable();
-	cpu_dead[smp_processor_id()] = 1;
+	idle_task_exit();
+	pr_debug("CPU%d offline\n", cpu);
+	generic_set_cpu_dead(cpu);
+	smp_wmb();
 	mb();
 	low_cpu_die();
 }
 
-void smp_core99_cpu_die(unsigned int cpu)
-{
-	int timeout;
+#else /* CONFIG_PPC32 */
 
-	timeout = 1000;
-	while (!cpu_dead[cpu]) {
-		if (--timeout == 0) {
-			printk("CPU %u refused to die!\n", cpu);
-			break;
-		}
-		msleep(1);
+static void pmac_cpu_die(void)
+{
+	int cpu = smp_processor_id();
+
+	local_irq_disable();
+	idle_task_exit();
+
+	/*
+	 * turn off as much as possible, we'll be
+	 * kicked out as this will only be invoked
+	 * on core99 platforms for now ...
+	 */
+
+	printk(KERN_INFO "CPU#%d offline\n", cpu);
+	generic_set_cpu_dead(cpu);
+	smp_wmb();
+
+	/*
+	 * Re-enable interrupts. The NAP code needs to enable them
+	 * anyways, do it now so we deal with the case where one already
+	 * happened while soft-disabled.
+	 * We shouldn't get any external interrupts, only decrementer, and the
+	 * decrementer handler is safe for use on offline CPUs
+	 */
+	local_irq_enable();
+
+	while (1) {
+		/* let's not take timer interrupts too often ... */
+		set_dec(0x7fffffff);
+
+		/* Enter NAP mode */
+		power4_idle();
 	}
-	cpu_dead[cpu] = 0;
 }
 
-#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
+#endif /* else CONFIG_PPC32 */
+#endif /* CONFIG_HOTPLUG_CPU */
 
 /* Core99 Macs (dual G4s and G5s) */
 struct smp_ops_t core99_smp_ops = {
 	.message_pass	= smp_mpic_message_pass,
 	.probe		= smp_core99_probe,
+	.bringup_done	= smp_core99_bringup_done,
 	.kick_cpu	= smp_core99_kick_cpu,
 	.setup_cpu	= smp_core99_setup_cpu,
 	.give_timebase	= smp_core99_give_timebase,
 	.take_timebase	= smp_core99_take_timebase,
 #if defined(CONFIG_HOTPLUG_CPU)
-# if defined(CONFIG_PPC32)
 	.cpu_disable	= smp_core99_cpu_disable,
-	.cpu_die	= smp_core99_cpu_die,
-# endif
-# if defined(CONFIG_PPC64)
-	.cpu_disable	= generic_cpu_disable,
 	.cpu_die	= generic_cpu_die,
-	/* intentionally do *NOT* assign cpu_enable,
-	 * the generic code will use kick_cpu then! */
-# endif
 #endif
 };
 
@@ -957,5 +1014,10 @@
 		smp_ops = &psurge_smp_ops;
 	}
 #endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_HOTPLUG_CPU
+	ppc_md.cpu_die = pmac_cpu_die;
+#endif
 }
 
+
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 75a6f48..08672d9 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -34,6 +34,4 @@
 #endif
 
 extern enum cpu_state_vals get_preferred_offline_state(int cpu);
-extern int start_secondary(void);
-extern void start_secondary_resume(void);
 #endif
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 2f475d7..9d897b6 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -403,8 +403,9 @@
 #define __NR_name_to_handle_at	332
 #define __NR_open_by_handle_at	333
 #define __NR_clock_adjtime	334
+#define __NR_syncfs		335
 
-#define NR_syscalls		335
+#define NR_syscalls		336
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c
index 2abace0..773091a 100644
--- a/arch/sparc/kernel/auxio_64.c
+++ b/arch/sparc/kernel/auxio_64.c
@@ -93,7 +93,7 @@
 }
 EXPORT_SYMBOL(auxio_set_lte);
 
-static struct of_device_id __initdata auxio_match[] = {
+static const struct of_device_id auxio_match[] = {
 	{
 		.name = "auxio",
 	},
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c
index 136d371..7eef3f7 100644
--- a/arch/sparc/kernel/central.c
+++ b/arch/sparc/kernel/central.c
@@ -140,7 +140,7 @@
 	goto out;
 }
 
-static struct of_device_id __initdata clock_board_match[] = {
+static const struct of_device_id clock_board_match[] = {
 	{
 		.name = "clock-board",
 	},
@@ -245,7 +245,7 @@
 	goto out;
 }
 
-static struct of_device_id __initdata fhc_match[] = {
+static const struct of_device_id fhc_match[] = {
 	{
 		.name = "fhc",
 	},
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 4a700f4..3add4de 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -1218,7 +1218,7 @@
 	return 0;
 }
 
-static struct vio_device_id __initdata ds_match[] = {
+static const struct vio_device_id ds_match[] = {
 	{
 		.type = "domain-services-port",
 	},
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 1504df8..906ee3e 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1283,7 +1283,7 @@
 	.globl	ret_from_fork
 ret_from_fork:
 	call	schedule_tail
-	 mov	%g3, %o0
+	 ld	[%g3 + TI_TASK], %o0
 	b	ret_sys_call
 	 ld	[%sp + STACKFRAME_SZ + PT_I0], %o0
 
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 6addb91..56db064 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -107,7 +107,7 @@
 	return hp;
 }
 
-static void mdesc_memblock_free(struct mdesc_handle *hp)
+static void __init mdesc_memblock_free(struct mdesc_handle *hp)
 {
 	unsigned int alloc_size;
 	unsigned long start;
diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c
index 3d70f83..d29a32f 100644
--- a/arch/sparc/kernel/pci_fire.c
+++ b/arch/sparc/kernel/pci_fire.c
@@ -496,7 +496,7 @@
 	return err;
 }
 
-static struct of_device_id __initdata fire_match[] = {
+static const struct of_device_id fire_match[] = {
 	{
 		.name = "pci",
 		.compatible = "pciex108e,80f0",
diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c
index 56ee745..86ae08d 100644
--- a/arch/sparc/kernel/pci_psycho.c
+++ b/arch/sparc/kernel/pci_psycho.c
@@ -592,7 +592,7 @@
 	return err;
 }
 
-static struct of_device_id __initdata psycho_match[] = {
+static const struct of_device_id psycho_match[] = {
 	{
 		.name = "pci",
 		.compatible = "pci108e,8000",
diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c
index 2857073..948068a 100644
--- a/arch/sparc/kernel/pci_sabre.c
+++ b/arch/sparc/kernel/pci_sabre.c
@@ -581,7 +581,7 @@
 	return err;
 }
 
-static struct of_device_id __initdata sabre_match[] = {
+static const struct of_device_id sabre_match[] = {
 	{
 		.name = "pci",
 		.compatible = "pci108e,a001",
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
index 1d41af7..fecfcb2 100644
--- a/arch/sparc/kernel/pci_schizo.c
+++ b/arch/sparc/kernel/pci_schizo.c
@@ -1470,7 +1470,7 @@
  * and pci108e,8001.  So list the chips in reverse chronological
  * order.
  */
-static struct of_device_id __initdata schizo_match[] = {
+static const struct of_device_id schizo_match[] = {
 	{
 		.name = "pci",
 		.compatible = "pci108e,a801",
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 6cf5346..b01a06e 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -998,7 +998,7 @@
 	return err;
 }
 
-static struct of_device_id __initdata pci_sun4v_match[] = {
+static const struct of_device_id pci_sun4v_match[] = {
 	{
 		.name = "pci",
 		.compatible = "SUNW,sun4v-pci",
diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c
index cd725fe2..cb4c0f5 100644
--- a/arch/sparc/kernel/power.c
+++ b/arch/sparc/kernel/power.c
@@ -52,7 +52,7 @@
 	return 0;
 }
 
-static struct of_device_id __initdata power_match[] = {
+static const struct of_device_id power_match[] = {
 	{
 		.name = "power",
 	},
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 4b86eaf..47ac73c 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -84,4 +84,4 @@
 /*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
 /*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-
+/*335*/	.long sys_syncfs
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 0331baf..4f3170c 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -85,6 +85,7 @@
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
 	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
+	.word sys_syncfs
 
 #endif /* CONFIG_COMPAT */
 
@@ -161,3 +162,4 @@
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
 	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
+	.word sys_syncfs
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 95ec25f..2b8d54b 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -442,7 +442,7 @@
 	return platform_device_register(&rtc_cmos_device);
 }
 
-static struct of_device_id __initdata rtc_match[] = {
+static const struct of_device_id rtc_match[] = {
 	{
 		.name = "rtc",
 		.compatible = "m5819",
@@ -487,7 +487,7 @@
 	return platform_device_register(&rtc_bq4802_device);
 }
 
-static struct of_device_id __initdata bq4802_match[] = {
+static const struct of_device_id bq4802_match[] = {
 	{
 		.name = "rtc",
 		.compatible = "bq4802",
@@ -552,7 +552,7 @@
 	return platform_device_register(&m48t59_rtc);
 }
 
-static struct of_device_id __initdata mostek_match[] = {
+static const struct of_device_id mostek_match[] = {
 	{
 		.name = "eeprom",
 	},
diff --git a/arch/unicore32/Makefile b/arch/unicore32/Makefile
index e08d6d3..76a8bee 100644
--- a/arch/unicore32/Makefile
+++ b/arch/unicore32/Makefile
@@ -48,7 +48,7 @@
 ASM_GENERIC_HEADERS	+= cputime.h current.h
 ASM_GENERIC_HEADERS	+= device.h div64.h
 ASM_GENERIC_HEADERS	+= emergency-restart.h errno.h
-ASM_GENERIC_HEADERS	+= fb.h fcntl.h ftrace.h
+ASM_GENERIC_HEADERS	+= fb.h fcntl.h ftrace.h futex.h
 ASM_GENERIC_HEADERS	+= hardirq.h hw_irq.h
 ASM_GENERIC_HEADERS	+= ioctl.h ioctls.h ipcbuf.h irq_regs.h
 ASM_GENERIC_HEADERS	+= kdebug.h kmap_types.h
diff --git a/arch/unicore32/include/asm/futex.h b/arch/unicore32/include/asm/futex.h
deleted file mode 100644
index 07dea61..0000000
--- a/arch/unicore32/include/asm/futex.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * linux/arch/unicore32/include/asm/futex.h
- *
- * Code specific to PKUnity SoC and UniCore ISA
- *
- * Copyright (C) 2001-2010 GUAN Xue-tao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __UNICORE_FUTEX_H__
-#define __UNICORE_FUTEX_H__
-
-#ifdef __KERNEL__
-
-#include <linux/futex.h>
-#include <linux/preempt.h>
-#include <linux/uaccess.h>
-#include <linux/errno.h>
-
-#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
-	__asm__ __volatile__(					\
-	"1:	ldw.u	%1, [%2]\n"				\
-	"	" insn "\n"					\
-	"2:	stw.u	%0, [%2]\n"				\
-	"	mov	%0, #0\n"				\
-	"3:\n"							\
-	"	.pushsection __ex_table,\"a\"\n"		\
-	"	.align	3\n"					\
-	"	.long	1b, 4f, 2b, 4f\n"			\
-	"	.popsection\n"					\
-	"	.pushsection .fixup,\"ax\"\n"			\
-	"4:	mov	%0, %4\n"				\
-	"	b	3b\n"					\
-	"	.popsection"					\
-	: "=&r" (ret), "=&r" (oldval)				\
-	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
-	: "cc", "memory")
-
-static inline int
-futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	pagefault_disable();	/* implies preempt_disable() */
-
-	switch (op) {
-	case FUTEX_OP_SET:
-		__futex_atomic_op("mov	%0, %3", ret, oldval, uaddr, oparg);
-		break;
-	case FUTEX_OP_ADD:
-		__futex_atomic_op("add	%0, %1, %3", ret, oldval, uaddr, oparg);
-		break;
-	case FUTEX_OP_OR:
-		__futex_atomic_op("or	%0, %1, %3", ret, oldval, uaddr, oparg);
-		break;
-	case FUTEX_OP_ANDN:
-		__futex_atomic_op("and	%0, %1, %3",
-				ret, oldval, uaddr, ~oparg);
-		break;
-	case FUTEX_OP_XOR:
-		__futex_atomic_op("xor	%0, %1, %3", ret, oldval, uaddr, oparg);
-		break;
-	default:
-		ret = -ENOSYS;
-	}
-
-	pagefault_enable();	/* subsumes preempt_enable() */
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ:
-			ret = (oldval == cmparg);
-			break;
-		case FUTEX_OP_CMP_NE:
-			ret = (oldval != cmparg);
-			break;
-		case FUTEX_OP_CMP_LT:
-			ret = (oldval <  cmparg);
-			break;
-		case FUTEX_OP_CMP_GE:
-			ret = (oldval >= cmparg);
-			break;
-		case FUTEX_OP_CMP_LE:
-			ret = (oldval <= cmparg);
-			break;
-		case FUTEX_OP_CMP_GT:
-			ret = (oldval >  cmparg);
-			break;
-		default:
-			ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-static inline int
-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
-{
-	int val;
-
-	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	pagefault_disable();	/* implies preempt_disable() */
-
-	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
-	"1:	ldw.u	%0, [%3]\n"
-	"	cmpxor.a	%0, %1\n"
-	"	bne	3f\n"
-	"2:	stw.u	%2, [%3]\n"
-	"3:\n"
-	"	.pushsection __ex_table,\"a\"\n"
-	"	.align	3\n"
-	"	.long	1b, 4f, 2b, 4f\n"
-	"	.popsection\n"
-	"	.pushsection .fixup,\"ax\"\n"
-	"4:	mov	%0, %4\n"
-	"	b	3b\n"
-	"	.popsection"
-	: "=&r" (val)
-	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
-	: "cc", "memory");
-
-	pagefault_enable();	/* subsumes preempt_enable() */
-
-	return val;
-}
-
-#endif /* __KERNEL__ */
-#endif /* __UNICORE_FUTEX_H__ */
diff --git a/arch/unicore32/include/mach/PKUnity.h b/arch/unicore32/include/mach/PKUnity.h
index a18bdc3..8040d57 100644
--- a/arch/unicore32/include/mach/PKUnity.h
+++ b/arch/unicore32/include/mach/PKUnity.h
@@ -24,16 +24,6 @@
 #define PKUNITY_MMIO_BASE		0x80000000 /* 0x80000000 - 0xFFFFFFFF 2GB */
 
 /*
- * PKUNITY Memory Map Addresses: 0x0D000000 - 0x0EFFFFFF (32MB)
- *	0x0D000000 - 0x0DFFFFFF 16MB: for UVC
- *	0x0E000000 - 0x0EFFFFFF 16MB: for UNIGFX
- */
-#define PKUNITY_UVC_MMAP_BASE		0x0D000000
-#define PKUNITY_UVC_MMAP_SIZE		0x01000000 /* 16MB */
-#define PKUNITY_UNIGFX_MMAP_BASE        0x0E000000
-#define PKUNITY_UNIGFX_MMAP_SIZE        0x01000000 /* 16MB */
-
-/*
  * PKUNITY System Bus Addresses (PCI): 0x80000000 - 0xBFFFFFFF (1GB)
  * 0x80000000 - 0x8000000B 12B    PCI Configuration regs
  * 0x80010000 - 0x80010250 592B   PCI Bridge Base
diff --git a/arch/unicore32/include/mach/memory.h b/arch/unicore32/include/mach/memory.h
index 0bf21c9..4be72c2 100644
--- a/arch/unicore32/include/mach/memory.h
+++ b/arch/unicore32/include/mach/memory.h
@@ -50,7 +50,6 @@
 
 /* kuser area */
 #define KUSER_VECPAGE_BASE	(KUSER_BASE + UL(0x3fff0000))
-#define KUSER_UNIGFX_BASE	(PAGE_OFFSET + PKUNITY_UNIGFX_MMAP_BASE)
 /* kuser_vecpage (0xbfff0000) is ro, and vectors page (0xffff0000) is rw */
 #define kuser_vecpage_to_vectors(x)	((x) - (KUSER_VECPAGE_BASE)	\
 					+ (VECTORS_BASE))
diff --git a/arch/unicore32/kernel/puv3-core.c b/arch/unicore32/kernel/puv3-core.c
index 8b1b6be..1a505a7 100644
--- a/arch/unicore32/kernel/puv3-core.c
+++ b/arch/unicore32/kernel/puv3-core.c
@@ -99,11 +99,6 @@
 		.end	= io_v2p(PKUNITY_UNIGFX_BASE) + 0xfff,
 		.flags	= IORESOURCE_MEM,
 	},
-	[1] = {
-		.start	= PKUNITY_UNIGFX_MMAP_BASE,
-		.end	= PKUNITY_UNIGFX_MMAP_BASE + PKUNITY_UNIGFX_MMAP_SIZE,
-		.flags	= IORESOURCE_MEM,
-	},
 };
 
 static struct resource puv3_rtc_resources[] = {
diff --git a/arch/unicore32/kernel/rtc.c b/arch/unicore32/kernel/rtc.c
index c5f0682..8cad70b 100644
--- a/arch/unicore32/kernel/rtc.c
+++ b/arch/unicore32/kernel/rtc.c
@@ -88,11 +88,6 @@
 	return 0;
 }
 
-static int puv3_rtc_setfreq(struct device *dev, int freq)
-{
-	return 0;
-}
-
 /* Time read/write */
 
 static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
@@ -214,8 +209,6 @@
 	.set_time	= puv3_rtc_settime,
 	.read_alarm	= puv3_rtc_getalarm,
 	.set_alarm	= puv3_rtc_setalarm,
-	.irq_set_freq	= puv3_rtc_setfreq,
-	.irq_set_state	= puv3_rtc_setpie,
 	.proc	        = puv3_rtc_proc,
 };
 
@@ -294,8 +287,6 @@
 
 	puv3_rtc_enable(pdev, 1);
 
-	puv3_rtc_setfreq(&pdev->dev, 1);
-
 	/* register RTC and exit */
 
 	rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c
index 1e175a8..471b6bc 100644
--- a/arch/unicore32/kernel/setup.c
+++ b/arch/unicore32/kernel/setup.c
@@ -64,12 +64,6 @@
  */
 static struct resource mem_res[] = {
 	{
-		.name = "Video RAM",
-		.start = 0,
-		.end = 0,
-		.flags = IORESOURCE_MEM
-	},
-	{
 		.name = "Kernel text",
 		.start = 0,
 		.end = 0,
@@ -83,9 +77,8 @@
 	}
 };
 
-#define video_ram   mem_res[0]
-#define kernel_code mem_res[1]
-#define kernel_data mem_res[2]
+#define kernel_code mem_res[0]
+#define kernel_data mem_res[1]
 
 /*
  * These functions re-use the assembly code in head.S, which
@@ -224,10 +217,6 @@
 		    kernel_data.end <= res->end)
 			request_resource(res, &kernel_data);
 	}
-
-	video_ram.start = PKUNITY_UNIGFX_MMAP_BASE;
-	video_ram.end   = PKUNITY_UNIGFX_MMAP_BASE + PKUNITY_UNIGFX_MMAP_SIZE;
-	request_resource(&iomem_resource, &video_ram);
 }
 
 static void (*init_machine)(void) __initdata;
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c
index 25abbb1..254e36f 100644
--- a/arch/unicore32/kernel/traps.c
+++ b/arch/unicore32/kernel/traps.c
@@ -22,7 +22,6 @@
 #include <linux/delay.h>
 #include <linux/hardirq.h>
 #include <linux/init.h>
-#include <linux/uaccess.h>
 #include <linux/atomic.h>
 #include <linux/unistd.h>
 
diff --git a/arch/unicore32/kernel/vmlinux.lds.S b/arch/unicore32/kernel/vmlinux.lds.S
index 0b4eb89..9bf7f7a 100644
--- a/arch/unicore32/kernel/vmlinux.lds.S
+++ b/arch/unicore32/kernel/vmlinux.lds.S
@@ -14,6 +14,7 @@
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
+#include <asm/cache.h>
 
 OUTPUT_ARCH(unicore32)
 ENTRY(stext)
@@ -29,7 +30,7 @@
 	HEAD_TEXT_SECTION
 	INIT_TEXT_SECTION(PAGE_SIZE)
 	INIT_DATA_SECTION(16)
-	PERCPU(PAGE_SIZE)
+	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
 	__init_end = .;
 
 	_stext = .;
@@ -45,10 +46,10 @@
 
 	_sdata = .;
 	RO_DATA_SECTION(PAGE_SIZE)
-	RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 	_edata = .;
 
-	EXCEPTION_TABLE(32)
+	EXCEPTION_TABLE(L1_CACHE_BYTES)
 	NOTES
 
 	BSS_SECTION(0, 0, 0)
diff --git a/arch/unicore32/mm/mmu.c b/arch/unicore32/mm/mmu.c
index 7bf3d58..db2d334 100644
--- a/arch/unicore32/mm/mmu.c
+++ b/arch/unicore32/mm/mmu.c
@@ -338,15 +338,6 @@
 	 * and can only be in node 0.
 	 */
 	memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
-
-#ifdef CONFIG_PUV3_UNIGFX
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen/video memory region at the 48M~64M of main system memory.
-	 */
-	memblock_reserve(PKUNITY_UNIGFX_MMAP_BASE, PKUNITY_UNIGFX_MMAP_SIZE);
-	memblock_reserve(PKUNITY_UVC_MMAP_BASE, PKUNITY_UVC_MMAP_SIZE);
-#endif
 }
 
 /*
@@ -371,17 +362,6 @@
 		pmd_clear(pmd_off_k(addr));
 
 	/*
-	 * Create a mapping for UniGFX VRAM
-	 */
-#ifdef CONFIG_PUV3_UNIGFX
-	map.pfn = __phys_to_pfn(PKUNITY_UNIGFX_MMAP_BASE);
-	map.virtual = KUSER_UNIGFX_BASE;
-	map.length = PKUNITY_UNIGFX_MMAP_SIZE;
-	map.type = MT_KUSER;
-	create_mapping(&map);
-#endif
-
-	/*
 	 * Create a mapping for the machine vectors at the high-vectors
 	 * location (0xffff0000).  If we aren't using high-vectors, also
 	 * create a mapping at the low-vectors virtual address.
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 5a05ef6..3385ea2 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1626,7 +1626,7 @@
 static unsigned int mce_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &mce_wait, wait);
-	if (rcu_dereference_check_mce(mcelog.next))
+	if (rcu_access_index(mcelog.next))
 		return POLLIN | POLLRDNORM;
 	if (!mce_apei_read_done && apei_check_mce())
 		return POLLIN | POLLRDNORM;
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 8dace18..cf97500 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -49,6 +49,10 @@
 	val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0;
 	val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0;
 	val |= (counter_config->unit_mask & 0xFF) << 8;
+	counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV |
+				  ARCH_PERFMON_EVENTSEL_EDGE |
+				  ARCH_PERFMON_EVENTSEL_CMASK);
+	val |= counter_config->extra;
 	event &= model->event_mask ? model->event_mask : 0xFF;
 	val |= event & 0xFF;
 	val |= (event & 0x0F00) << 24;
@@ -440,6 +444,7 @@
 		oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
 		oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
 		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
+		oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra);
 	}
 
 	return 0;
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h
index e28398d..0b7b7b1 100644
--- a/arch/x86/oprofile/op_counter.h
+++ b/arch/x86/oprofile/op_counter.h
@@ -22,6 +22,7 @@
 	unsigned long kernel;
 	unsigned long user;
 	unsigned long unit_mask;
+	unsigned long extra;
 };
 
 extern struct op_counter_config counter_config[];
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 25ef1a4..cd0ff66 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -165,7 +165,6 @@
 static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
-static void release_vccs(struct atm_dev *dev);
 static int atm_init(struct solos_card *, struct device *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -384,7 +383,6 @@
 	/* Anything but 'Showtime' is down */
 	if (strcmp(state_str, "Showtime")) {
 		atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
-		release_vccs(card->atmdev[port]);
 		dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
 		return 0;
 	}
@@ -697,7 +695,7 @@
 					      size);
 			}
 			if (atmdebug) {
-				dev_info(&card->dev->dev, "Received: device %d\n", port);
+				dev_info(&card->dev->dev, "Received: port %d\n", port);
 				dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
 					 size, le16_to_cpu(header->vpi),
 					 le16_to_cpu(header->vci));
@@ -710,8 +708,8 @@
 					       le16_to_cpu(header->vci));
 				if (!vcc) {
 					if (net_ratelimit())
-						dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
-							 le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
+						dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
+							 le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
 							 port);
 					continue;
 				}
@@ -830,28 +828,6 @@
 	return num_found;
 }
 
-static void release_vccs(struct atm_dev *dev)
-{
-        int i;
-
-        write_lock_irq(&vcc_sklist_lock);
-        for (i = 0; i < VCC_HTABLE_SIZE; i++) {
-                struct hlist_head *head = &vcc_hash[i];
-                struct hlist_node *node, *tmp;
-                struct sock *s;
-                struct atm_vcc *vcc;
-
-                sk_for_each_safe(s, node, tmp, head) {
-                        vcc = atm_sk(s);
-                        if (vcc->dev == dev) {
-                                vcc_release_async(vcc, -EPIPE);
-                                sk_del_node_init(s);
-                        }
-                }
-        }
-        write_unlock_irq(&vcc_sklist_lock);
-}
-
 
 static int popen(struct atm_vcc *vcc)
 {
@@ -1018,8 +994,15 @@
 
 			/* Clean up and free oldskb now it's gone */
 			if (atmdebug) {
+				struct pkt_hdr *header = (void *)oldskb->data;
+				int size = le16_to_cpu(header->size);
+
+				skb_pull(oldskb, sizeof(*header));
 				dev_info(&card->dev->dev, "Transmitted: port %d\n",
 					 port);
+				dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
+					 size, le16_to_cpu(header->vpi),
+					 le16_to_cpu(header->vci));
 				print_buffer(oldskb);
 			}
 
@@ -1262,7 +1245,7 @@
 		card->atmdev[i]->ci_range.vci_bits = 16;
 		card->atmdev[i]->dev_data = card;
 		card->atmdev[i]->phy_data = (void *)(unsigned long)i;
-		atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN);
+		atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
 
 		skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
 		if (!skb) {
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 55653ab..c42c9d5 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -31,24 +31,9 @@
 #include <linux/connector.h>
 #include <linux/delay.h>
 
-void cn_queue_wrapper(struct work_struct *work)
-{
-	struct cn_callback_entry *cbq =
-		container_of(work, struct cn_callback_entry, work);
-	struct cn_callback_data *d = &cbq->data;
-	struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
-	struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
-
-	d->callback(msg, nsp);
-
-	kfree_skb(d->skb);
-	d->skb = NULL;
-
-	kfree(d->free);
-}
-
 static struct cn_callback_entry *
-cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
+cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
+			      struct cb_id *id,
 			      void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
 {
 	struct cn_callback_entry *cbq;
@@ -59,17 +44,23 @@
 		return NULL;
 	}
 
+	atomic_set(&cbq->refcnt, 1);
+
+	atomic_inc(&dev->refcnt);
+	cbq->pdev = dev;
+
 	snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
 	memcpy(&cbq->id.id, id, sizeof(struct cb_id));
-	cbq->data.callback = callback;
-
-	INIT_WORK(&cbq->work, &cn_queue_wrapper);
+	cbq->callback = callback;
 	return cbq;
 }
 
-static void cn_queue_free_callback(struct cn_callback_entry *cbq)
+void cn_queue_release_callback(struct cn_callback_entry *cbq)
 {
-	flush_workqueue(cbq->pdev->cn_queue);
+	if (!atomic_dec_and_test(&cbq->refcnt))
+		return;
+
+	atomic_dec(&cbq->pdev->refcnt);
 	kfree(cbq);
 }
 
@@ -85,13 +76,10 @@
 	struct cn_callback_entry *cbq, *__cbq;
 	int found = 0;
 
-	cbq = cn_queue_alloc_callback_entry(name, id, callback);
+	cbq = cn_queue_alloc_callback_entry(dev, name, id, callback);
 	if (!cbq)
 		return -ENOMEM;
 
-	atomic_inc(&dev->refcnt);
-	cbq->pdev = dev;
-
 	spin_lock_bh(&dev->queue_lock);
 	list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
 		if (cn_cb_equal(&__cbq->id.id, id)) {
@@ -104,8 +92,7 @@
 	spin_unlock_bh(&dev->queue_lock);
 
 	if (found) {
-		cn_queue_free_callback(cbq);
-		atomic_dec(&dev->refcnt);
+		cn_queue_release_callback(cbq);
 		return -EINVAL;
 	}
 
@@ -130,10 +117,8 @@
 	}
 	spin_unlock_bh(&dev->queue_lock);
 
-	if (found) {
-		cn_queue_free_callback(cbq);
-		atomic_dec(&dev->refcnt);
-	}
+	if (found)
+		cn_queue_release_callback(cbq);
 }
 
 struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
@@ -151,12 +136,6 @@
 
 	dev->nls = nls;
 
-	dev->cn_queue = alloc_ordered_workqueue(dev->name, 0);
-	if (!dev->cn_queue) {
-		kfree(dev);
-		return NULL;
-	}
-
 	return dev;
 }
 
@@ -164,9 +143,6 @@
 {
 	struct cn_callback_entry *cbq, *n;
 
-	flush_workqueue(dev->cn_queue);
-	destroy_workqueue(dev->cn_queue);
-
 	spin_lock_bh(&dev->queue_lock);
 	list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
 		list_del(&cbq->callback_entry);
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index f7554de..d770058 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -122,51 +122,28 @@
  */
 static int cn_call_callback(struct sk_buff *skb)
 {
-	struct cn_callback_entry *__cbq, *__new_cbq;
+	struct cn_callback_entry *i, *cbq = NULL;
 	struct cn_dev *dev = &cdev;
 	struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
+	struct netlink_skb_parms *nsp = &NETLINK_CB(skb);
 	int err = -ENODEV;
 
 	spin_lock_bh(&dev->cbdev->queue_lock);
-	list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
-		if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
-			if (likely(!work_pending(&__cbq->work) &&
-					__cbq->data.skb == NULL)) {
-				__cbq->data.skb = skb;
-
-				if (queue_work(dev->cbdev->cn_queue,
-					       &__cbq->work))
-					err = 0;
-				else
-					err = -EINVAL;
-			} else {
-				struct cn_callback_data *d;
-
-				err = -ENOMEM;
-				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
-				if (__new_cbq) {
-					d = &__new_cbq->data;
-					d->skb = skb;
-					d->callback = __cbq->data.callback;
-					d->free = __new_cbq;
-
-					INIT_WORK(&__new_cbq->work,
-							&cn_queue_wrapper);
-
-					if (queue_work(dev->cbdev->cn_queue,
-						       &__new_cbq->work))
-						err = 0;
-					else {
-						kfree(__new_cbq);
-						err = -EINVAL;
-					}
-				}
-			}
+	list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) {
+		if (cn_cb_equal(&i->id.id, &msg->id)) {
+			atomic_inc(&i->refcnt);
+			cbq = i;
 			break;
 		}
 	}
 	spin_unlock_bh(&dev->cbdev->queue_lock);
 
+	if (cbq != NULL) {
+		cbq->callback(msg, nsp);
+		kfree_skb(skb);
+		cn_queue_release_callback(cbq);
+	}
+
 	return err;
 }
 
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c
index 97e22be..de58191 100644
--- a/drivers/hwmon/twl4030-madc-hwmon.c
+++ b/drivers/hwmon/twl4030-madc-hwmon.c
@@ -154,4 +154,4 @@
 MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("J Keerthy");
-MODULE_ALIAS("twl4030_madc_hwmon");
+MODULE_ALIAS("platform:twl4030_madc_hwmon");
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index bca2af2..c987033 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -153,7 +153,7 @@
 static struct i2c_adapter *		u3_1;
 static struct i2c_adapter *		k2;
 static struct i2c_client *		fcu;
-static struct cpu_pid_state		cpu_state[2];
+static struct cpu_pid_state		processor_state[2];
 static struct basckside_pid_params	backside_params;
 static struct backside_pid_state	backside_state;
 static struct drives_pid_state		drives_state;
@@ -664,8 +664,8 @@
 
 static void fetch_cpu_pumps_minmax(void)
 {
-	struct cpu_pid_state *state0 = &cpu_state[0];
-	struct cpu_pid_state *state1 = &cpu_state[1];
+	struct cpu_pid_state *state0 = &processor_state[0];
+	struct cpu_pid_state *state1 = &processor_state[1];
 	u16 pump_min = 0, pump_max = 0xffff;
 	u16 tmp[4];
 
@@ -717,17 +717,17 @@
 	return sprintf(buf, "%d", data);			\
 }
 
-BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage)
-BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a)
-BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm)
-BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
+BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
+BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
+BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
 
-BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage)
-BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a)
-BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm)
-BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
+BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
+BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
+BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
 
 BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
 BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
@@ -919,8 +919,8 @@
 
 static void do_monitor_cpu_combined(void)
 {
-	struct cpu_pid_state *state0 = &cpu_state[0];
-	struct cpu_pid_state *state1 = &cpu_state[1];
+	struct cpu_pid_state *state0 = &processor_state[0];
+	struct cpu_pid_state *state1 = &processor_state[1];
 	s32 temp0, power0, temp1, power1;
 	s32 temp_combi, power_combi;
 	int rc, intake, pump;
@@ -1150,7 +1150,7 @@
 /*
  * Initialize the state structure for one CPU control loop
  */
-static int init_cpu_state(struct cpu_pid_state *state, int index)
+static int init_processor_state(struct cpu_pid_state *state, int index)
 {
 	int err;
 
@@ -1205,7 +1205,7 @@
 /*
  * Dispose of the state data for one CPU control loop
  */
-static void dispose_cpu_state(struct cpu_pid_state *state)
+static void dispose_processor_state(struct cpu_pid_state *state)
 {
 	if (state->monitor == NULL)
 		return;
@@ -1804,9 +1804,9 @@
 		set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
 
 	/* Initialize ADCs */
-	initialize_adc(&cpu_state[0]);
-	if (cpu_state[1].monitor != NULL)
-		initialize_adc(&cpu_state[1]);
+	initialize_adc(&processor_state[0]);
+	if (processor_state[1].monitor != NULL)
+		initialize_adc(&processor_state[1]);
 
 	fcu_tickle_ticks = FCU_TICKLE_TICKS;
 
@@ -1833,14 +1833,14 @@
 		if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
 			do_monitor_cpu_combined();
 		else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
-			do_monitor_cpu_rack(&cpu_state[0]);
-			if (cpu_state[1].monitor != NULL)
-				do_monitor_cpu_rack(&cpu_state[1]);
+			do_monitor_cpu_rack(&processor_state[0]);
+			if (processor_state[1].monitor != NULL)
+				do_monitor_cpu_rack(&processor_state[1]);
 			// better deal with UP
 		} else {
-			do_monitor_cpu_split(&cpu_state[0]);
-			if (cpu_state[1].monitor != NULL)
-				do_monitor_cpu_split(&cpu_state[1]);
+			do_monitor_cpu_split(&processor_state[0]);
+			if (processor_state[1].monitor != NULL)
+				do_monitor_cpu_split(&processor_state[1]);
 			// better deal with UP
 		}
 		/* Then, the rest */
@@ -1885,8 +1885,8 @@
  */
 static void dispose_control_loops(void)
 {
-	dispose_cpu_state(&cpu_state[0]);
-	dispose_cpu_state(&cpu_state[1]);
+	dispose_processor_state(&processor_state[0]);
+	dispose_processor_state(&processor_state[1]);
 	dispose_backside_state(&backside_state);
 	dispose_drives_state(&drives_state);
 	dispose_slots_state(&slots_state);
@@ -1928,12 +1928,12 @@
 	/* Create control loops for everything. If any fail, everything
 	 * fails
 	 */
-	if (init_cpu_state(&cpu_state[0], 0))
+	if (init_processor_state(&processor_state[0], 0))
 		goto fail;
 	if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
 		fetch_cpu_pumps_minmax();
 
-	if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1))
+	if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
 		goto fail;
 	if (init_backside_state(&backside_state))
 		goto fail;
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index 64454d3..ecfd9fb 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -1494,12 +1494,17 @@
 	}
 
 	memset(&fm_st_proto, 0, sizeof(fm_st_proto));
-	fm_st_proto.type = ST_FM;
 	fm_st_proto.recv = fm_st_receive;
 	fm_st_proto.match_packet = NULL;
 	fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb;
 	fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */
 	fm_st_proto.priv_data = fmdev;
+	fm_st_proto.chnl_id = 0x08;
+	fm_st_proto.max_frame_size = 0xff;
+	fm_st_proto.hdr_len = 1;
+	fm_st_proto.offset_len_in_hdr = 0;
+	fm_st_proto.len_size = 1;
+	fm_st_proto.reserve = 1;
 
 	ret = st_register(&fm_st_proto);
 	if (ret == -EINPROGRESS) {
@@ -1532,7 +1537,7 @@
 		g_st_write = fm_st_proto.write;
 	} else {
 		fmerr("Failed to get ST write func pointer\n");
-		ret = st_unregister(ST_FM);
+		ret = st_unregister(&fm_st_proto);
 		if (ret < 0)
 			fmerr("st_unregister failed %d\n", ret);
 		return -EAGAIN;
@@ -1586,6 +1591,7 @@
  */
 u32 fmc_release(struct fmdev *fmdev)
 {
+	static struct st_proto_s fm_st_proto;
 	u32 ret;
 
 	if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
@@ -1604,7 +1610,11 @@
 	fmdev->resp_comp = NULL;
 	fmdev->rx.freq = 0;
 
-	ret = st_unregister(ST_FM);
+	memset(&fm_st_proto, 0, sizeof(fm_st_proto));
+	fm_st_proto.chnl_id = 0x08;
+
+	ret = st_unregister(&fm_st_proto);
+
 	if (ret < 0)
 		fmerr("Failed to de-register FM from ST %d\n", ret);
 	else
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index e637e9f..937ef1a 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1996,13 +1996,15 @@
 	if (!eeprom_buff)
 		return -ENOMEM;
 
-	ptr = (u32 *)eeprom_buff;
+	ptr = eeprom_buff;
 
 	if (eeprom->offset & 3) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
-		if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0])))
-			return -EIO;
+		if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
+			ret_val = -EIO;
+			goto out;
+		}
 		ptr++;
 	}
 	if (((eeprom->offset + eeprom->len) & 3)) {
@@ -2011,18 +2013,22 @@
 		 * only the first byte of the word is being modified
 		 */
 		if (!atl2_read_eeprom(hw, last_dword * 4,
-			&(eeprom_buff[last_dword - first_dword])))
-			return -EIO;
+					&(eeprom_buff[last_dword - first_dword]))) {
+			ret_val = -EIO;
+			goto out;
+		}
 	}
 
 	/* Device's eeprom is always little-endian, word addressable */
 	memcpy(ptr, bytes, eeprom->len);
 
 	for (i = 0; i < last_dword - first_dword + 1; i++) {
-		if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i]))
-			return -EIO;
+		if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
+			ret_val = -EIO;
+			goto out;
+		}
 	}
-
+ out:
 	kfree(eeprom_buff);
 	return ret_val;
 }
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 118c28a..4b3e358 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -74,7 +74,7 @@
 				 * packets to a Client that the Hash function
 				 * gave this entry index.
 				 */
-	u32 tx_bytes;		/* Each Client acumulates the BytesTx that
+	u32 tx_bytes;		/* Each Client accumulates the BytesTx that
 				 * were tranmitted to it, and after each
 				 * CallBack the LoadHistory is devided
 				 * by the balance interval
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 67c0ad4..186cd28 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -75,15 +75,9 @@
 /* We can't guess the type of connected dongle, user *must* supply it. */
 module_param(dongle_id, int, 0);
 
-/* FIXME : we should not need this, because instances should be automatically
- * managed by the PCI layer. Especially that we seem to only be using the
- * first entry. Jean II */
-/* Max 4 instances for now */
-static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
-
 /* Some prototypes */
-static int via_ircc_open(int i, chipio_t * info, unsigned int id);
-static int via_ircc_close(struct via_ircc_cb *self);
+static int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+			 unsigned int id);
 static int via_ircc_dma_receive(struct via_ircc_cb *self);
 static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,
 					 int iobase);
@@ -215,7 +209,7 @@
 			pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0));
 			pci_write_config_byte(pcidev,0x5a,0xc0);
 			WriteLPCReg(0x28, 0x70 );
-			if (via_ircc_open(0, &info,0x3076) == 0)
+			if (via_ircc_open(pcidev, &info, 0x3076) == 0)
 				rc=0;
 		} else
 			rc = -ENODEV; //IR not turn on	 
@@ -254,7 +248,7 @@
 			info.irq=FirIRQ;
 			info.dma=FirDRQ1;
 			info.dma2=FirDRQ0;
-			if (via_ircc_open(0, &info,0x3096) == 0)
+			if (via_ircc_open(pcidev, &info, 0x3096) == 0)
 				rc=0;
 		} else
 			rc = -ENODEV; //IR not turn on !!!!!
@@ -264,48 +258,10 @@
 	return rc;
 }
 
-/*
- * Function via_ircc_clean ()
- *
- *    Close all configured chips
- *
- */
-static void via_ircc_clean(void)
-{
-	int i;
-
-	IRDA_DEBUG(3, "%s()\n", __func__);
-
-	for (i=0; i < ARRAY_SIZE(dev_self); i++) {
-		if (dev_self[i])
-			via_ircc_close(dev_self[i]);
-	}
-}
-
-static void __devexit via_remove_one (struct pci_dev *pdev)
-{
-	IRDA_DEBUG(3, "%s()\n", __func__);
-
-	/* FIXME : This is ugly. We should use pci_get_drvdata(pdev);
-	 * to get our driver instance and call directly via_ircc_close().
-	 * See vlsi_ir for details...
-	 * Jean II */
-	via_ircc_clean();
-
-	/* FIXME : This should be in via_ircc_close(), because here we may
-	 * theoritically disable still configured devices :-( - Jean II */
-	pci_disable_device(pdev);
-}
-
 static void __exit via_ircc_cleanup(void)
 {
 	IRDA_DEBUG(3, "%s()\n", __func__);
 
-	/* FIXME : This should be redundant, as pci_unregister_driver()
-	 * should call via_remove_one() on each device.
-	 * Jean II */
-	via_ircc_clean();
-
 	/* Cleanup all instances of the driver */
 	pci_unregister_driver (&via_driver); 
 }
@@ -324,12 +280,13 @@
 };
 
 /*
- * Function via_ircc_open (iobase, irq)
+ * Function via_ircc_open(pdev, iobase, irq)
  *
  *    Open driver instance
  *
  */
-static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
+static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+				   unsigned int id)
 {
 	struct net_device *dev;
 	struct via_ircc_cb *self;
@@ -337,9 +294,6 @@
 
 	IRDA_DEBUG(3, "%s()\n", __func__);
 
-	if (i >= ARRAY_SIZE(dev_self))
-		return -ENOMEM;
-
 	/* Allocate new instance of the driver */
 	dev = alloc_irdadev(sizeof(struct via_ircc_cb));
 	if (dev == NULL) 
@@ -349,13 +303,8 @@
 	self->netdev = dev;
 	spin_lock_init(&self->lock);
 
-	/* FIXME : We should store our driver instance in the PCI layer,
-	 * using pci_set_drvdata(), not in this array.
-	 * See vlsi_ir for details... - Jean II */
-	/* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */
-	/* Need to store self somewhere */
-	dev_self[i] = self;
-	self->index = i;
+	pci_set_drvdata(pdev, self);
+
 	/* Initialize Resource */
 	self->io.cfg_base = info->cfg_base;
 	self->io.fir_base = info->fir_base;
@@ -414,7 +363,7 @@
 
 	/* Allocate memory if needed */
 	self->rx_buff.head =
-		dma_alloc_coherent(NULL, self->rx_buff.truesize,
+		dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize,
 				   &self->rx_buff_dma, GFP_KERNEL);
 	if (self->rx_buff.head == NULL) {
 		err = -ENOMEM;
@@ -423,7 +372,7 @@
 	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
 
 	self->tx_buff.head =
-		dma_alloc_coherent(NULL, self->tx_buff.truesize,
+		dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize,
 				   &self->tx_buff_dma, GFP_KERNEL);
 	if (self->tx_buff.head == NULL) {
 		err = -ENOMEM;
@@ -455,33 +404,32 @@
 	via_hw_init(self);
 	return 0;
  err_out4:
-	dma_free_coherent(NULL, self->tx_buff.truesize,
+	dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
 			  self->tx_buff.head, self->tx_buff_dma);
  err_out3:
-	dma_free_coherent(NULL, self->rx_buff.truesize,
+	dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
 			  self->rx_buff.head, self->rx_buff_dma);
  err_out2:
 	release_region(self->io.fir_base, self->io.fir_ext);
  err_out1:
+	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
-	dev_self[i] = NULL;
 	return err;
 }
 
 /*
- * Function via_ircc_close (self)
+ * Function via_remove_one(pdev)
  *
  *    Close driver instance
  *
  */
-static int via_ircc_close(struct via_ircc_cb *self)
+static void __devexit via_remove_one(struct pci_dev *pdev)
 {
+	struct via_ircc_cb *self = pci_get_drvdata(pdev);
 	int iobase;
 
 	IRDA_DEBUG(3, "%s()\n", __func__);
 
-	IRDA_ASSERT(self != NULL, return -1;);
-
 	iobase = self->io.fir_base;
 
 	ResetChip(iobase, 5);	//hardware reset.
@@ -493,16 +441,16 @@
 		   __func__, self->io.fir_base);
 	release_region(self->io.fir_base, self->io.fir_ext);
 	if (self->tx_buff.head)
-		dma_free_coherent(NULL, self->tx_buff.truesize,
+		dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
 				  self->tx_buff.head, self->tx_buff_dma);
 	if (self->rx_buff.head)
-		dma_free_coherent(NULL, self->rx_buff.truesize,
+		dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
 				  self->rx_buff.head, self->rx_buff_dma);
-	dev_self[self->index] = NULL;
+	pci_set_drvdata(pdev, NULL);
 
 	free_netdev(self->netdev);
 
-	return 0;
+	pci_disable_device(pdev);
 }
 
 /*
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 506cfd0..1ad1f60 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -603,7 +603,9 @@
 	}
 
 	for (i = 0; i < dev->caps.num_comp_vectors; ++i) {
-		err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
+		err = mlx4_create_eq(dev, dev->caps.num_cqs -
+					  dev->caps.reserved_cqs +
+					  MLX4_NUM_SPARE_EQE,
 				     (dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
 				     &priv->eq_table.eq[i]);
 		if (err) {
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index e71372a..37150b2 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -469,7 +469,6 @@
 
 	/*remove from list of promisc qps */
 	list_del(&pqp->list);
-	kfree(pqp);
 
 	/* set the default entry not to include the removed one */
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -528,6 +527,8 @@
 out_list:
 	if (back_to_list)
 		list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
+	else
+		kfree(pqp);
 out_mutex:
 	mutex_unlock(&priv->mcg_table.mutex);
 	return err;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 993c52c..e870c06 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -442,11 +442,11 @@
 			     u32 flags, phy_interface_t interface)
 {
 	struct device *d = &phydev->dev;
+	int err;
 
 	/* Assume that if there is no driver, that it doesn't
 	 * exist, and we should use the genphy driver. */
 	if (NULL == d->driver) {
-		int err;
 		d->driver = &genphy_driver.driver;
 
 		err = d->driver->probe(d);
@@ -474,7 +474,11 @@
 	/* Do initial configuration here, now that
 	 * we have certain key parameters
 	 * (dev_flags and interface) */
-	return phy_init_hw(phydev);
+	err = phy_init_hw(phydev);
+	if (err)
+		phy_detach(phydev);
+
+	return err;
 }
 
 /**
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 6f600cc..3ec22c3 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -433,4 +433,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called sierra_net.
 
+config USB_VL600
+	tristate "LG VL600 modem dongle"
+	depends on USB_NET_CDCETHER
+	select USB_ACM
+	help
+	  Select this if you want to use an LG Electronics 4G/LTE usb modem
+	  called VL600.  This driver only handles the ethernet
+	  interface exposed by the modem firmware.  To establish a connection
+	  you will first need a userspace program that sends the right
+	  command to the modem through its CDC ACM port, and most
+	  likely also a DHCP client.  See this thread about using the
+	  4G modem from Verizon:
+
+	  http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
+
 endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index cac1703..c7ec8a5 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -27,4 +27,5 @@
 obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
 obj-$(CONFIG_USB_NET_CX82310_ETH)	+= cx82310_eth.o
 obj-$(CONFIG_USB_NET_CDC_NCM)	+= cdc_ncm.o
+obj-$(CONFIG_USB_VL600)		+= lg-vl600.o
 
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 9a60e41..51c259b 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -378,7 +378,7 @@
 		   __le32_to_cpu(speeds[1]) / 1000);
 }
 
-static void cdc_status(struct usbnet *dev, struct urb *urb)
+void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
 {
 	struct usb_cdc_notification	*event;
 
@@ -418,8 +418,9 @@
 		break;
 	}
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_status);
 
-static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int				status;
 	struct cdc_state		*info = (void *) &dev->data;
@@ -441,6 +442,7 @@
 	 */
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
 
 static int cdc_manage_power(struct usbnet *dev, int on)
 {
@@ -452,18 +454,18 @@
 	.description =	"CDC Ethernet Device",
 	.flags =	FLAG_ETHER,
 	// .check_connect = cdc_check_connect,
-	.bind =		cdc_bind,
+	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
-	.status =	cdc_status,
+	.status =	usbnet_cdc_status,
 	.manage_power =	cdc_manage_power,
 };
 
 static const struct driver_info mbm_info = {
 	.description =	"Mobile Broadband Network Device",
 	.flags =	FLAG_WWAN,
-	.bind = 	cdc_bind,
+	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
-	.status =	cdc_status,
+	.status =	usbnet_cdc_status,
 	.manage_power =	cdc_manage_power,
 };
 
@@ -560,6 +562,13 @@
 	.driver_info		= 0,
 },
 
+/* LG Electronics VL600 wants additional headers on every frame */
+{
+	USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+	.driver_info		= 0,
+},
+
 /*
  * WHITELIST!!!
  *
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
new file mode 100644
index 0000000..1d83ccf
--- /dev/null
+++ b/drivers/net/usb/lg-vl600.c
@@ -0,0 +1,346 @@
+/*
+ * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Author: Andrzej Zaborowski <balrogg@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+/*
+ * The device has a CDC ACM port for modem control (it claims to be
+ * CDC ACM anyway) and a CDC Ethernet port for actual network data.
+ * It will however ignore data on both ports that is not encapsulated
+ * in a specific way, any data returned is also encapsulated the same
+ * way.  The headers don't seem to follow any popular standard.
+ *
+ * This driver adds and strips these headers from the ethernet frames
+ * sent/received from the CDC Ethernet port.  The proprietary header
+ * replaces the standard ethernet header in a packet so only actual
+ * ethernet frames are allowed.  The headers allow some form of
+ * multiplexing by using non standard values of the .h_proto field.
+ * Windows/Mac drivers do send a couple of such frames to the device
+ * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
+ * seems to be) a flag in the .dummy_flags.  This doesn't seem necessary
+ * for modem operation but can possibly be used for GPS or other funcitons.
+ */
+
+struct vl600_frame_hdr {
+	__le32 len;
+	__le32 serial;
+	__le32 pkt_cnt;
+	__le32 dummy_flags;
+	__le32 dummy;
+	__le32 magic;
+} __attribute__((packed));
+
+struct vl600_pkt_hdr {
+	__le32 dummy[2];
+	__le32 len;
+	__be16 h_proto;
+} __attribute__((packed));
+
+struct vl600_state {
+	struct sk_buff *current_rx_buf;
+};
+
+static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int ret;
+	struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
+
+	if (!s)
+		return -ENOMEM;
+
+	ret = usbnet_cdc_bind(dev, intf);
+	if (ret) {
+		kfree(s);
+		return ret;
+	}
+
+	dev->driver_priv = s;
+
+	/* ARP packets don't go through, but they're also of no use.  The
+	 * subnet has only two hosts anyway: us and the gateway / DHCP
+	 * server (probably simulated by modem firmware or network operator)
+	 * whose address changes everytime we connect to the intarwebz and
+	 * who doesn't bother answering ARP requests either.  So hardware
+	 * addresses have no meaning, the destination and the source of every
+	 * packet depend only on whether it is on the IN or OUT endpoint.  */
+	dev->net->flags |= IFF_NOARP;
+
+	return ret;
+}
+
+static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+	struct vl600_state *s = dev->driver_priv;
+
+	if (s->current_rx_buf)
+		dev_kfree_skb(s->current_rx_buf);
+
+	kfree(s);
+
+	return usbnet_cdc_unbind(dev, intf);
+}
+
+static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct vl600_frame_hdr *frame;
+	struct vl600_pkt_hdr *packet;
+	struct ethhdr *ethhdr;
+	int packet_len, count;
+	struct sk_buff *buf = skb;
+	struct sk_buff *clone;
+	struct vl600_state *s = dev->driver_priv;
+
+	/* Frame lengths are generally 4B multiplies but every couple of
+	 * hours there's an odd number of bytes sized yet correct frame,
+	 * so don't require this.  */
+
+	/* Allow a packet (or multiple packets batched together) to be
+	 * split across many frames.  We don't allow a new batch to
+	 * begin in the same frame another one is ending however, and no
+	 * leading or trailing pad bytes.  */
+	if (s->current_rx_buf) {
+		frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
+		if (skb->len + s->current_rx_buf->len >
+				le32_to_cpup(&frame->len)) {
+			netif_err(dev, ifup, dev->net, "Fragment too long\n");
+			dev->net->stats.rx_length_errors++;
+			goto error;
+		}
+
+		buf = s->current_rx_buf;
+		memcpy(skb_put(buf, skb->len), skb->data, skb->len);
+	} else if (skb->len < 4) {
+		netif_err(dev, ifup, dev->net, "Frame too short\n");
+		dev->net->stats.rx_length_errors++;
+		goto error;
+	}
+
+	frame = (struct vl600_frame_hdr *) buf->data;
+	/* NOTE: Should check that frame->magic == 0x53544448?
+	 * Otherwise if we receive garbage at the beginning of the frame
+	 * we may end up allocating a huge buffer and saving all the
+	 * future incoming data into it.  */
+
+	if (buf->len < sizeof(*frame) ||
+			buf->len != le32_to_cpup(&frame->len)) {
+		/* Save this fragment for later assembly */
+		if (s->current_rx_buf)
+			return 0;
+
+		s->current_rx_buf = skb_copy_expand(skb, 0,
+				le32_to_cpup(&frame->len), GFP_ATOMIC);
+		if (!s->current_rx_buf) {
+			netif_err(dev, ifup, dev->net, "Reserving %i bytes "
+					"for packet assembly failed.\n",
+					le32_to_cpup(&frame->len));
+			dev->net->stats.rx_errors++;
+		}
+
+		return 0;
+	}
+
+	count = le32_to_cpup(&frame->pkt_cnt);
+
+	skb_pull(buf, sizeof(*frame));
+
+	while (count--) {
+		if (buf->len < sizeof(*packet)) {
+			netif_err(dev, ifup, dev->net, "Packet too short\n");
+			goto error;
+		}
+
+		packet = (struct vl600_pkt_hdr *) buf->data;
+		packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
+		if (packet_len > buf->len) {
+			netif_err(dev, ifup, dev->net,
+					"Bad packet length stored in header\n");
+			goto error;
+		}
+
+		/* Packet header is same size as the ethernet header
+		 * (sizeof(*packet) == sizeof(*ethhdr)), additionally
+		 * the h_proto field is in the same place so we just leave it
+		 * alone and fill in the remaining fields.
+		 */
+		ethhdr = (struct ethhdr *) skb->data;
+		if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
+				buf->len > 0x26) {
+			/* Copy the addresses from packet contents */
+			memcpy(ethhdr->h_source,
+					&buf->data[sizeof(*ethhdr) + 0x8],
+					ETH_ALEN);
+			memcpy(ethhdr->h_dest,
+					&buf->data[sizeof(*ethhdr) + 0x12],
+					ETH_ALEN);
+		} else {
+			memset(ethhdr->h_source, 0, ETH_ALEN);
+			memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
+		}
+
+		if (count) {
+			/* Not the last packet in this batch */
+			clone = skb_clone(buf, GFP_ATOMIC);
+			if (!clone)
+				goto error;
+
+			skb_trim(clone, packet_len);
+			usbnet_skb_return(dev, clone);
+
+			skb_pull(buf, (packet_len + 3) & ~3);
+		} else {
+			skb_trim(buf, packet_len);
+
+			if (s->current_rx_buf) {
+				usbnet_skb_return(dev, buf);
+				s->current_rx_buf = NULL;
+				return 0;
+			}
+
+			return 1;
+		}
+	}
+
+error:
+	if (s->current_rx_buf) {
+		dev_kfree_skb_any(s->current_rx_buf);
+		s->current_rx_buf = NULL;
+	}
+	dev->net->stats.rx_errors++;
+	return 0;
+}
+
+static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
+		struct sk_buff *skb, gfp_t flags)
+{
+	struct sk_buff *ret;
+	struct vl600_frame_hdr *frame;
+	struct vl600_pkt_hdr *packet;
+	static uint32_t serial = 1;
+	int orig_len = skb->len - sizeof(struct ethhdr);
+	int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
+
+	frame = (struct vl600_frame_hdr *) skb->data;
+	if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
+		return skb; /* Already encapsulated? */
+
+	if (skb->len < sizeof(struct ethhdr))
+		/* Drop, device can only deal with ethernet packets */
+		return NULL;
+
+	if (!skb_cloned(skb)) {
+		int headroom = skb_headroom(skb);
+		int tailroom = skb_tailroom(skb);
+
+		if (tailroom >= full_len - skb->len - sizeof(*frame) &&
+				headroom >= sizeof(*frame))
+			/* There's enough head and tail room */
+			goto encapsulate;
+
+		if (headroom + tailroom + skb->len >= full_len) {
+			/* There's enough total room, just readjust */
+			skb->data = memmove(skb->head + sizeof(*frame),
+					skb->data, skb->len);
+			skb_set_tail_pointer(skb, skb->len);
+			goto encapsulate;
+		}
+	}
+
+	/* Alloc a new skb with the required size */
+	ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
+			skb->len - sizeof(struct vl600_frame_hdr), flags);
+	dev_kfree_skb_any(skb);
+	if (!ret)
+		return ret;
+	skb = ret;
+
+encapsulate:
+	/* Packet header is same size as ethernet packet header
+	 * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
+	 * h_proto field is in the same place so we just leave it alone and
+	 * overwrite the remaining fields.
+	 */
+	packet = (struct vl600_pkt_hdr *) skb->data;
+	memset(&packet->dummy, 0, sizeof(packet->dummy));
+	packet->len = cpu_to_le32(orig_len);
+
+	frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
+	memset(frame, 0, sizeof(*frame));
+	frame->len = cpu_to_le32(full_len);
+	frame->serial = cpu_to_le32(serial++);
+	frame->pkt_cnt = cpu_to_le32(1);
+
+	if (skb->len < full_len) /* Pad */
+		skb_put(skb, full_len - skb->len);
+
+	return skb;
+}
+
+static const struct driver_info	vl600_info = {
+	.description	= "LG VL600 modem",
+	.flags		= FLAG_ETHER | FLAG_RX_ASSEMBLE,
+	.bind		= vl600_bind,
+	.unbind		= vl600_unbind,
+	.status		= usbnet_cdc_status,
+	.rx_fixup	= vl600_rx_fixup,
+	.tx_fixup	= vl600_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+	{
+		USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+				USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+		.driver_info	= (unsigned long) &vl600_info,
+	},
+	{},	/* End */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver lg_vl600_driver = {
+	.name		= "lg-vl600",
+	.id_table	= products,
+	.probe		= usbnet_probe,
+	.disconnect	= usbnet_disconnect,
+	.suspend	= usbnet_suspend,
+	.resume		= usbnet_resume,
+};
+
+static int __init vl600_init(void)
+{
+	return usb_register(&lg_vl600_driver);
+}
+module_init(vl600_init);
+
+static void __exit vl600_exit(void)
+{
+	usb_deregister(&lg_vl600_driver);
+}
+module_exit(vl600_exit);
+
+MODULE_AUTHOR("Anrzej Zaborowski");
+MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 95c41d5..cf58b76 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -387,8 +387,12 @@
 static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
 {
 	if (dev->driver_info->rx_fixup &&
-	    !dev->driver_info->rx_fixup (dev, skb))
-		goto error;
+	    !dev->driver_info->rx_fixup (dev, skb)) {
+		/* With RX_ASSEMBLE, rx_fixup() must update counters */
+		if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE))
+			dev->net->stats.rx_errors++;
+		goto done;
+	}
 	// else network stack removes extra byte if we forced a short packet
 
 	if (skb->len) {
@@ -401,8 +405,8 @@
 	}
 
 	netif_dbg(dev, rx_err, dev->net, "drop\n");
-error:
 	dev->net->stats.rx_errors++;
+done:
 	skb_queue_tail(&dev->done, skb);
 }
 
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index b86bc32..332a2c4 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -319,7 +319,7 @@
 	return IRQ_NONE;
 }
 
-static int __init
+static int __devinit
 vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
 {
 	int retval = 0;
@@ -391,7 +391,7 @@
 	spin_unlock_irq(&rtc_lock);
 }
 
-static void __exit rtc_mrst_do_remove(struct device *dev)
+static void __devexit rtc_mrst_do_remove(struct device *dev)
 {
 	struct mrst_rtc	*mrst = dev_get_drvdata(dev);
 	struct resource *iomem;
@@ -500,14 +500,14 @@
 
 #endif
 
-static int __init vrtc_mrst_platform_probe(struct platform_device *pdev)
+static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev)
 {
 	return vrtc_mrst_do_probe(&pdev->dev,
 			platform_get_resource(pdev, IORESOURCE_MEM, 0),
 			platform_get_irq(pdev, 0));
 }
 
-static int __exit vrtc_mrst_platform_remove(struct platform_device *pdev)
+static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev)
 {
 	rtc_mrst_do_remove(&pdev->dev);
 	return 0;
@@ -525,7 +525,7 @@
 
 static struct platform_driver vrtc_mrst_platform_driver = {
 	.probe		= vrtc_mrst_platform_probe,
-	.remove		= __exit_p(vrtc_mrst_platform_remove),
+	.remove		= __devexit_p(vrtc_mrst_platform_remove),
 	.shutdown	= vrtc_mrst_platform_shutdown,
 	.driver = {
 		.name		= (char *) driver_name,
diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c
index 6b633b1..8763088 100644
--- a/drivers/staging/altera-stapl/altera-jtag.c
+++ b/drivers/staging/altera-stapl/altera-jtag.c
@@ -23,6 +23,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <staging/altera.h>
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index e1aee37..80484af 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1506,7 +1506,7 @@
 
 config SERIAL_GRLIB_GAISLER_APBUART
 	tristate "GRLIB APBUART serial support"
-	depends on OF
+	depends on OF && SPARC
 	select SERIAL_CORE
 	---help---
 	Add support for the GRLIB APBUART serial port.
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 1ab999b..19a9436 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -555,10 +555,9 @@
 
 static int __devinit apbuart_probe(struct platform_device *op)
 {
-	int i = -1;
+	int i;
 	struct uart_port *port = NULL;
 
-	i = 0;
 	for (i = 0; i < grlib_apbuart_port_nr; i++) {
 		if (op->dev.of_node == grlib_apbuart_nodes[i])
 			break;
@@ -566,6 +565,7 @@
 
 	port = &grlib_apbuart_ports[i];
 	port->dev = &op->dev;
+	port->irq = op->archdata.irqs[0];
 
 	uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port);
 
@@ -598,24 +598,12 @@
 
 static int grlib_apbuart_configure(void)
 {
-	struct device_node *np, *rp;
-	const u32 *prop;
-	int freq_khz, line = 0;
-
-	/* Get bus frequency */
-	rp = of_find_node_by_path("/");
-	if (!rp)
-		return -ENODEV;
-	rp = of_get_next_child(rp, NULL);
-	if (!rp)
-		return -ENODEV;
-	prop = of_get_property(rp, "clock-frequency", NULL);
-	if (!prop)
-		return -ENODEV;
-	freq_khz = *prop;
+	struct device_node *np;
+	int line = 0;
 
 	for_each_matching_node(np, apbuart_match) {
-		const int *irqs, *ampopts;
+		const int *ampopts;
+		const u32 *freq_hz;
 		const struct amba_prom_registers *regs;
 		struct uart_port *port;
 		unsigned long addr;
@@ -623,11 +611,11 @@
 		ampopts = of_get_property(np, "ampopts", NULL);
 		if (ampopts && (*ampopts == 0))
 			continue; /* Ignore if used by another OS instance */
-
-		irqs = of_get_property(np, "interrupts", NULL);
 		regs = of_get_property(np, "reg", NULL);
+		/* Frequency of APB Bus is frequency of UART */
+		freq_hz = of_get_property(np, "freq", NULL);
 
-		if (!irqs || !regs)
+		if (!regs || !freq_hz || (*freq_hz == 0))
 			continue;
 
 		grlib_apbuart_nodes[line] = np;
@@ -638,12 +626,12 @@
 
 		port->mapbase = addr;
 		port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
-		port->irq = *irqs;
+		port->irq = 0;
 		port->iotype = UPIO_MEM;
 		port->ops = &grlib_apbuart_ops;
 		port->flags = UPF_BOOT_AUTOCONF;
 		port->line = line;
-		port->uartclk = freq_khz * 1000;
+		port->uartclk = *freq_hz;
 		port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line);
 		line++;
 
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index d2c0196..ba0d287 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -106,7 +106,7 @@
 static int  mct_u232_tiocmget(struct tty_struct *tty);
 static int  mct_u232_tiocmset(struct tty_struct *tty,
 			unsigned int set, unsigned int clear);
-static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
+static int  mct_u232_ioctl(struct tty_struct *tty,
 			unsigned int cmd, unsigned long arg);
 static int  mct_u232_get_icount(struct tty_struct *tty,
 			struct serial_icounter_struct *icount);
@@ -874,7 +874,7 @@
 	}
 }
 
-static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
+static int  mct_u232_ioctl(struct tty_struct *tty,
 			unsigned int cmd, unsigned long arg)
 {
 	DEFINE_WAIT(wait);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 201f609..a1dd4d4 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -413,7 +413,7 @@
 	return result;
 }
 
-static int opticon_tiocmset(struct tty_struct *tty, struct file *file,
+static int opticon_tiocmset(struct tty_struct *tty,
 			   unsigned int set, unsigned int clear)
 {
 	struct usb_serial_port *port = tty->driver_data;
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index dbd2dc4..27f2c57 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/vmalloc.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
@@ -531,7 +530,7 @@
 		return -EINVAL;
 	}
 
-	writel(PKUNITY_UNIGFX_MMAP_BASE, UDE_FSA);
+	writel(info->fix.smem_start, UDE_FSA);
 	writel(info->var.yres, UDE_LS);
 	writel(get_line_length(info->var.xres,
 			info->var.bits_per_pixel) >> 3, UDE_PS);
@@ -680,13 +679,27 @@
 	struct fb_info *info;
 	u32 unifb_regs[UNIFB_REGS_NUM];
 	int retval = -ENOMEM;
-	struct resource *iomem, *mapmem;
+	struct resource *iomem;
+	void *videomemory;
+
+	videomemory = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP,
+				get_order(UNIFB_MEMSIZE));
+	if (!videomemory)
+		goto err;
+
+	memset(videomemory, 0, UNIFB_MEMSIZE);
+
+	unifb_fix.smem_start = virt_to_phys(videomemory);
+	unifb_fix.smem_len = UNIFB_MEMSIZE;
+
+	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	unifb_fix.mmio_start = iomem->start;
 
 	info = framebuffer_alloc(sizeof(u32)*256, &dev->dev);
 	if (!info)
 		goto err;
 
-	info->screen_base = (char __iomem *)KUSER_UNIGFX_BASE;
+	info->screen_base = (char __iomem *)videomemory;
 	info->fbops = &unifb_ops;
 
 	retval = fb_find_mode(&info->var, info, NULL,
@@ -695,13 +708,6 @@
 	if (!retval || (retval == 4))
 		info->var = unifb_default;
 
-	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	unifb_fix.mmio_start = iomem->start;
-
-	mapmem = platform_get_resource(dev, IORESOURCE_MEM, 1);
-	unifb_fix.smem_start = mapmem->start;
-	unifb_fix.smem_len = UNIFB_MEMSIZE;
-
 	info->fix = unifb_fix;
 	info->pseudo_palette = info->par;
 	info->par = NULL;
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a1ee8fa..f60b07b 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -3215,9 +3215,15 @@
 {
 	struct ceph_mds_client *mdsc = fsc->mdsc;
 
+	dout("mdsc_destroy %p\n", mdsc);
 	ceph_mdsc_stop(mdsc);
+
+	/* flush out any connection work with references to us */
+	ceph_msgr_flush();
+
 	fsc->mdsc = NULL;
 	kfree(mdsc);
+	dout("mdsc_destroy %p done\n", mdsc);
 }
 
 
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index a9e78b4..f2f77fd 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -353,7 +353,7 @@
 
 	if (opt->name)
 		seq_printf(m, ",name=%s", opt->name);
-	if (opt->secret)
+	if (opt->key)
 		seq_puts(m, ",secret=<hidden>");
 
 	if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 93589fc..397e732 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -72,10 +72,9 @@
 	/*
 	 * check to see if the page is mapped already (no holes)
 	 */
-	if (PageMappedToDisk(page)) {
-		unlock_page(page);
+	if (PageMappedToDisk(page))
 		goto mapped;
-	}
+
 	if (page_has_buffers(page)) {
 		struct buffer_head *bh, *head;
 		int fully_mapped = 1;
@@ -90,7 +89,6 @@
 
 		if (fully_mapped) {
 			SetPageMappedToDisk(page);
-			unlock_page(page);
 			goto mapped;
 		}
 	}
@@ -105,16 +103,17 @@
 		return VM_FAULT_SIGBUS;
 
 	ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
-	if (unlikely(ret)) {
+	if (ret != VM_FAULT_LOCKED) {
 		nilfs_transaction_abort(inode->i_sb);
 		return ret;
 	}
+	nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
 	nilfs_transaction_commit(inode->i_sb);
 
  mapped:
 	SetPageChecked(page);
 	wait_on_page_writeback(page);
-	return 0;
+	return VM_FAULT_LOCKED;
 }
 
 static const struct vm_operations_struct nilfs_file_vm_ops = {
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 856e8e4..a8dd344 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -114,19 +114,19 @@
  * Macros to check inode numbers
  */
 #define NILFS_MDT_INO_BITS   \
-  ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO |		\
-		  1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO |	\
-		  1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
+	((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO |	\
+			1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO |	\
+			1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
 
 #define NILFS_SYS_INO_BITS   \
-  ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
+	((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
 
 #define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino)
 
 #define NILFS_MDT_INODE(sb, ino) \
-  ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
+	((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
 #define NILFS_VALID_INODE(sb, ino) \
-  ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
+	((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
 
 /**
  * struct nilfs_transaction_info: context information for synchronization
@@ -285,7 +285,7 @@
 extern void nilfs_error(struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
 extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
-       __attribute__ ((format (printf, 3, 4)));
+	__attribute__ ((format (printf, 3, 4)));
 extern struct nilfs_super_block *
 nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
 extern int nilfs_store_magic_and_option(struct super_block *,
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 4d2a1ee..9d2dc6b 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -495,12 +495,14 @@
 void nilfs_mapping_init(struct address_space *mapping,
 			struct backing_dev_info *bdi)
 {
+	static const struct address_space_operations empty_aops;
+
 	mapping->host = NULL;
 	mapping->flags = 0;
 	mapping_set_gfp_mask(mapping, GFP_NOFS);
 	mapping->assoc_mapping = NULL;
 	mapping->backing_dev_info = bdi;
-	mapping->a_ops = NULL;
+	mapping->a_ops = &empty_aops;
 }
 
 /*
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index f2d2faf..e5a3f58 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -194,6 +194,13 @@
 #ifdef CONFIG_SMP
 # define WARN_ON_SMP(x)			WARN_ON(x)
 #else
+/*
+ * Use of ({0;}) because WARN_ON_SMP(x) may be used either as
+ * a stand alone line statement or as a condition in an if ()
+ * statement.
+ * A simple "0" would cause gcc to give a "statement has no effect"
+ * warning.
+ */
 # define WARN_ON_SMP(x)			({0;})
 #endif
 
diff --git a/include/keys/ceph-type.h b/include/keys/ceph-type.h
new file mode 100644
index 0000000..f69c4ac
--- /dev/null
+++ b/include/keys/ceph-type.h
@@ -0,0 +1,8 @@
+#ifndef _KEYS_CEPH_TYPE_H
+#define _KEYS_CEPH_TYPE_H
+
+#include <linux/key.h>
+
+extern struct key_type key_type_ceph;
+
+#endif
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 475f8c4..381f4ce 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -443,6 +443,7 @@
 
 void vcc_insert_socket(struct sock *sk);
 
+void atm_dev_release_vccs(struct atm_dev *dev);
 
 /*
  * This is approximately the algorithm used by alloc_skb.
diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h
index 7fff521..aa13392 100644
--- a/include/linux/ceph/auth.h
+++ b/include/linux/ceph/auth.h
@@ -67,12 +67,12 @@
 	bool negotiating;       /* true if negotiating protocol */
 	const char *name;       /* entity name */
 	u64 global_id;          /* our unique id in system */
-	const char *secret;     /* our secret key */
+	const struct ceph_crypto_key *key;     /* our secret key */
 	unsigned want_keys;     /* which services we want */
 };
 
 extern struct ceph_auth_client *ceph_auth_init(const char *name,
-					       const char *secret);
+					       const struct ceph_crypto_key *key);
 extern void ceph_auth_destroy(struct ceph_auth_client *ac);
 
 extern void ceph_auth_reset(struct ceph_auth_client *ac);
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 0d2e0ff..6365f04 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -61,7 +61,7 @@
 					      pointer type of args */
 	int num_mon;
 	char *name;
-	char *secret;
+	struct ceph_crypto_key *key;
 };
 
 /*
diff --git a/include/linux/connector.h b/include/linux/connector.h
index bcafc94..7c60d09 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -88,8 +88,6 @@
 	atomic_t refcnt;
 	unsigned char name[CN_CBQ_NAMELEN];
 
-	struct workqueue_struct *cn_queue;
-
 	struct list_head queue_list;
 	spinlock_t queue_lock;
 
@@ -101,20 +99,13 @@
 	struct cb_id id;
 };
 
-struct cn_callback_data {
-	struct sk_buff *skb;
-	void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
-
-	void *free;
-};
-
 struct cn_callback_entry {
 	struct list_head callback_entry;
-	struct work_struct work;
+	atomic_t refcnt;
 	struct cn_queue_dev *pdev;
 
 	struct cn_callback_id id;
-	struct cn_callback_data data;
+	void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
 
 	u32 seq, group;
 };
@@ -138,13 +129,12 @@
 			  struct cb_id *id,
 			  void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
 void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
+void cn_queue_release_callback(struct cn_callback_entry *);
 
 struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *);
 void cn_queue_free_dev(struct cn_queue_dev *dev);
 
 int cn_cb_equal(struct cb_id *, struct cb_id *);
 
-void cn_queue_wrapper(struct work_struct *work);
-
 #endif				/* __KERNEL__ */
 #endif				/* __CONNECTOR_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 03e8e8d..c2478a3 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -208,6 +208,7 @@
 		unsigned long long *crash_size, unsigned long long *crash_base);
 int crash_shrink_memory(unsigned long new_size);
 size_t crash_get_memory_size(void);
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 311b4dc..04d75a8 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1086,7 +1086,7 @@
 {
 	perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
 
-	COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next));
+	__perf_event_task_sched_out(task, next);
 }
 
 extern void perf_event_mmap(struct vm_area_struct *vma);
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index af56148..ff422d2 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -339,6 +339,12 @@
 		((typeof(*p) __force __kernel *)(p)); \
 	})
 
+#define __rcu_access_index(p, space) \
+	({ \
+		typeof(p) _________p1 = ACCESS_ONCE(p); \
+		rcu_dereference_sparse(p, space); \
+		(_________p1); \
+	})
 #define __rcu_dereference_index_check(p, c) \
 	({ \
 		typeof(p) _________p1 = ACCESS_ONCE(p); \
@@ -429,6 +435,20 @@
 #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
 
 /**
+ * rcu_access_index() - fetch RCU index with no dereferencing
+ * @p: The index to read
+ *
+ * Return the value of the specified RCU-protected index, but omit the
+ * smp_read_barrier_depends() and keep the ACCESS_ONCE().  This is useful
+ * when the value of this index is accessed, but the index is not
+ * dereferenced, for example, when testing an RCU-protected index against
+ * -1.  Although rcu_access_index() may also be used in cases where
+ * update-side locks prevent the value of the index from changing, you
+ * should instead use rcu_dereference_index_protected() for this use case.
+ */
+#define rcu_access_index(p) __rcu_access_index((p), __rcu)
+
+/**
  * rcu_dereference_index_check() - rcu_dereference for indices with debug checking
  * @p: The pointer to read, prior to dereferencing
  * @c: The conditions under which the dereference will take place
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 239083b..d9e52fa 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -126,7 +126,7 @@
  * GRO uses frags we allocate at least 16 regardless of page size.
  */
 #if (65536/PAGE_SIZE + 2) < 16
-#define MAX_SKB_FRAGS 16
+#define MAX_SKB_FRAGS 16UL
 #else
 #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
 #endif
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 44842c8..201f222 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -102,6 +102,7 @@
  * Affects statistic (counters) and short packet handling.
  */
 #define FLAG_MULTI_PACKET	0x1000
+#define FLAG_RX_ASSEMBLE	0x2000	/* rx packets may span >1 frames */
 
 	/* init device ... can sleep, or cause probe() failure */
 	int	(*bind)(struct usbnet *, struct usb_interface *);
@@ -172,7 +173,9 @@
 };
 
 extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
+extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
 extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_status(struct usbnet *, struct urb *);
 
 /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
 #define	DEFAULT_FILTER	(USB_CDC_PACKET_TYPE_BROADCAST \
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 04977ee..fccc218 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -286,5 +286,21 @@
 	buf[9]  = broadcast[9];
 	memcpy(buf + 10, addr->s6_addr + 6, 10);
 }
+
+static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
+				    const unsigned char *broadcast, char *buf)
+{
+	if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
+		memcpy(buf, broadcast, 4);
+	} else {
+		/* v4mapped? */
+		if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
+		     (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
+			return -EINVAL;
+		memcpy(buf, &addr->s6_addr32[3], 4);
+	}
+	return 0;
+}
+
 #endif
 #endif
diff --git a/include/net/ip.h b/include/net/ip.h
index a4f6311..7c41658 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -339,6 +339,14 @@
 	buf[16] = addr & 0x0f;
 }
 
+static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
+{
+	if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
+		memcpy(buf, broadcast, 4);
+	else
+		memcpy(buf, &naddr, sizeof(naddr));
+}
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #include <linux/ipv6.h>
 #endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 979ed84..ddc2b3d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -45,25 +45,25 @@
 /* platform domain */
 #define SND_SOC_DAPM_INPUT(wname) \
 {	.id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0}
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
 #define SND_SOC_DAPM_OUTPUT(wname) \
 {	.id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0}
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
 #define SND_SOC_DAPM_MIC(wname, wevent) \
 {	.id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
 #define SND_SOC_DAPM_HP(wname, wevent) \
 {	.id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
 #define SND_SOC_DAPM_SPK(wname, wevent) \
 {	.id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
 #define SND_SOC_DAPM_LINE(wname, wevent) \
 {	.id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
 
 /* path domain */
@@ -189,11 +189,11 @@
 /* events that are pre and post DAPM */
 #define SND_SOC_DAPM_PRE(wname, wevent) \
 {	.id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}
 #define SND_SOC_DAPM_POST(wname, wevent) \
 {	.id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \
-	.num_kcontrols = 0, .event = wevent, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
 
 /* stream domain */
diff --git a/kernel/kexec.c b/kernel/kexec.c
index ec19b92..4e240a3 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1099,7 +1099,8 @@
 	return size;
 }
 
-static void free_reserved_phys_range(unsigned long begin, unsigned long end)
+void __weak crash_free_reserved_phys_range(unsigned long begin,
+					   unsigned long end)
 {
 	unsigned long addr;
 
@@ -1135,7 +1136,7 @@
 	start = roundup(start, PAGE_SIZE);
 	end = roundup(start + new_size, PAGE_SIZE);
 
-	free_reserved_phys_range(end, crashk_res.end);
+	crash_free_reserved_phys_range(end, crashk_res.end);
 
 	if ((start == end) && (crashk_res.parent != NULL))
 		release_resource(&crashk_res);
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index c75925c..27960f1 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -145,8 +145,8 @@
  */
 int sysctl_perf_event_paranoid __read_mostly = 1;
 
-/* Minimum for 128 pages + 1 for the user control page */
-int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */
+/* Minimum for 512 kiB + 1 user control page */
+int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
 
 /*
  * max perf event sample rate
@@ -6531,6 +6531,11 @@
 		goto err_alloc;
 	}
 
+	if (task) {
+		put_task_struct(task);
+		task = NULL;
+	}
+
 	/*
 	 * Look up the group leader (we will attach this event to it):
 	 */
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 5f1bb8e..f6117a4 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -652,6 +652,8 @@
 		struct timespec delta;
 		delta.tv_sec  = txc->time.tv_sec;
 		delta.tv_nsec = txc->time.tv_usec;
+		if (!capable(CAP_SYS_TIME))
+			return -EPERM;
 		if (!(txc->modes & ADJ_NANO))
 			delta.tv_nsec *= 1000;
 		result = timekeeping_inject_offset(&delta);
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 206e771..956a530 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1051,16 +1051,17 @@
 {
 	struct sock *sk = sock->sk;
 
-	sock_hold(sk);
-	lock_sock(sk);
 	if (sk) {
+		sock_hold(sk);
+		lock_sock(sk);
+
 		sock_orphan(sk);
 		sock->sk = NULL;
 		atalk_destroy_socket(sk);
-	}
-	release_sock(sk);
-	sock_put(sk);
 
+		release_sock(sk);
+		sock_put(sk);
+	}
 	return 0;
 }
 
diff --git a/net/atm/common.c b/net/atm/common.c
index 1b9c52a..22b963d 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -252,6 +252,7 @@
 	}
 	write_unlock_irq(&vcc_sklist_lock);
 }
+EXPORT_SYMBOL(atm_dev_release_vccs);
 
 static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
 {
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f61eb2e..59660c9 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1475,7 +1475,7 @@
 	    ip6h->payload_len == 0)
 		return 0;
 
-	len = ntohs(ip6h->payload_len);
+	len = ntohs(ip6h->payload_len) + sizeof(*ip6h);
 	if (skb->len < len)
 		return -EINVAL;
 
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 5593f5a..9b61d09 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -213,7 +213,7 @@
 
 	/* user has chosen a value so keep it */
 	if (br->flags & BR_SET_MAC_ADDR)
-		return;
+		return false;
 
 	list_for_each_entry(p, &br->port_list, list) {
 		if (addr == br_mac_zero ||
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index ad42404..be683f2 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -4,6 +4,7 @@
 	select LIBCRC32C
 	select CRYPTO_AES
 	select CRYPTO
+	select KEYS
 	default n
 	help
 	  Choose Y or M here to include cephlib, which provides the
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index 549c1f4..b4bf4ac 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -35,12 +35,12 @@
 /*
  * setup, teardown.
  */
-struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
 {
 	struct ceph_auth_client *ac;
 	int ret;
 
-	dout("auth_init name '%s' secret '%s'\n", name, secret);
+	dout("auth_init name '%s'\n", name);
 
 	ret = -ENOMEM;
 	ac = kzalloc(sizeof(*ac), GFP_NOFS);
@@ -52,8 +52,8 @@
 		ac->name = name;
 	else
 		ac->name = CEPH_AUTH_NAME_DEFAULT;
-	dout("auth_init name %s secret %s\n", ac->name, secret);
-	ac->secret = secret;
+	dout("auth_init name %s\n", ac->name);
+	ac->key = key;
 	return ac;
 
 out:
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 7fd5dfc..1587dc6 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -662,14 +662,16 @@
 		goto out;
 
 	ret = -EINVAL;
-	if (!ac->secret) {
+	if (!ac->key) {
 		pr_err("no secret set (for auth_x protocol)\n");
 		goto out_nomem;
 	}
 
-	ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
-	if (ret)
+	ret = ceph_crypto_key_clone(&xi->secret, ac->key);
+	if (ret < 0) {
+		pr_err("cannot clone key: %d\n", ret);
 		goto out_nomem;
+	}
 
 	xi->starting = true;
 	xi->ticket_handlers = RB_ROOT;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 95f96ab..132963a 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -5,6 +5,8 @@
 #include <linux/fs.h>
 #include <linux/inet.h>
 #include <linux/in6.h>
+#include <linux/key.h>
+#include <keys/ceph-type.h>
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/parser.h>
@@ -20,6 +22,7 @@
 #include <linux/ceph/decode.h>
 #include <linux/ceph/mon_client.h>
 #include <linux/ceph/auth.h>
+#include "crypto.h"
 
 
 
@@ -117,9 +120,29 @@
 	if (ret)
 		return ret;
 
-	ret = strcmp_null(opt1->secret, opt2->secret);
-	if (ret)
-		return ret;
+	if (opt1->key && !opt2->key)
+		return -1;
+	if (!opt1->key && opt2->key)
+		return 1;
+	if (opt1->key && opt2->key) {
+		if (opt1->key->type != opt2->key->type)
+			return -1;
+		if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
+			return -1;
+		if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
+			return -1;
+		if (opt1->key->len != opt2->key->len)
+			return -1;
+		if (opt1->key->key && !opt2->key->key)
+			return -1;
+		if (!opt1->key->key && opt2->key->key)
+			return 1;
+		if (opt1->key->key && opt2->key->key) {
+			ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
+			if (ret)
+				return ret;
+		}
+	}
 
 	/* any matching mon ip implies a match */
 	for (i = 0; i < opt1->num_mon; i++) {
@@ -176,6 +199,7 @@
 	Opt_fsid,
 	Opt_name,
 	Opt_secret,
+	Opt_key,
 	Opt_ip,
 	Opt_last_string,
 	/* string args above */
@@ -192,6 +216,7 @@
 	{Opt_fsid, "fsid=%s"},
 	{Opt_name, "name=%s"},
 	{Opt_secret, "secret=%s"},
+	{Opt_key, "key=%s"},
 	{Opt_ip, "ip=%s"},
 	/* string args above */
 	{Opt_noshare, "noshare"},
@@ -203,11 +228,56 @@
 {
 	dout("destroy_options %p\n", opt);
 	kfree(opt->name);
-	kfree(opt->secret);
+	if (opt->key) {
+		ceph_crypto_key_destroy(opt->key);
+		kfree(opt->key);
+	}
 	kfree(opt);
 }
 EXPORT_SYMBOL(ceph_destroy_options);
 
+/* get secret from key store */
+static int get_secret(struct ceph_crypto_key *dst, const char *name) {
+	struct key *ukey;
+	int key_err;
+	int err = 0;
+	struct ceph_crypto_key *ckey;
+
+	ukey = request_key(&key_type_ceph, name, NULL);
+	if (!ukey || IS_ERR(ukey)) {
+		/* request_key errors don't map nicely to mount(2)
+		   errors; don't even try, but still printk */
+		key_err = PTR_ERR(ukey);
+		switch (key_err) {
+		case -ENOKEY:
+			pr_warning("ceph: Mount failed due to key not found: %s\n", name);
+			break;
+		case -EKEYEXPIRED:
+			pr_warning("ceph: Mount failed due to expired key: %s\n", name);
+			break;
+		case -EKEYREVOKED:
+			pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
+			break;
+		default:
+			pr_warning("ceph: Mount failed due to unknown key error"
+			       " %d: %s\n", key_err, name);
+		}
+		err = -EPERM;
+		goto out;
+	}
+
+	ckey = ukey->payload.data;
+	err = ceph_crypto_key_clone(dst, ckey);
+	if (err)
+		goto out_key;
+	/* pass through, err is 0 */
+
+out_key:
+	key_put(ukey);
+out:
+	return err;
+}
+
 int ceph_parse_options(struct ceph_options **popt, char *options,
 		       const char *dev_name, const char *dev_name_end,
 		       int (*parse_extra_token)(char *c, void *private),
@@ -295,9 +365,24 @@
 					      GFP_KERNEL);
 			break;
 		case Opt_secret:
-			opt->secret = kstrndup(argstr[0].from,
-						argstr[0].to-argstr[0].from,
-						GFP_KERNEL);
+		        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+			if (!opt->key) {
+				err = -ENOMEM;
+				goto out;
+			}
+			err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
+			if (err < 0)
+				goto out;
+			break;
+		case Opt_key:
+		        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+			if (!opt->key) {
+				err = -ENOMEM;
+				goto out;
+			}
+			err = get_secret(opt->key, argstr[0].from);
+			if (err < 0)
+				goto out;
 			break;
 
 			/* misc */
@@ -394,8 +479,8 @@
 	ceph_osdc_stop(&client->osdc);
 
 	/*
-	 * make sure mds and osd connections close out before destroying
-	 * the auth module, which is needed to free those connections'
+	 * make sure osd connections close out before destroying the
+	 * auth module, which is needed to free those connections'
 	 * ceph_authorizers.
 	 */
 	ceph_msgr_flush();
@@ -496,10 +581,14 @@
 	if (ret < 0)
 		goto out;
 
-	ret = ceph_msgr_init();
+	ret = ceph_crypto_init();
 	if (ret < 0)
 		goto out_debugfs;
 
+	ret = ceph_msgr_init();
+	if (ret < 0)
+		goto out_crypto;
+
 	pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
 		CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
 		CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -507,6 +596,8 @@
 
 	return 0;
 
+out_crypto:
+	ceph_crypto_shutdown();
 out_debugfs:
 	ceph_debugfs_cleanup();
 out:
@@ -517,6 +608,7 @@
 {
 	dout("exit_ceph_lib\n");
 	ceph_msgr_exit();
+	ceph_crypto_shutdown();
 	ceph_debugfs_cleanup();
 }
 
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 7b505b0..5a8009c 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -5,10 +5,23 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <crypto/hash.h>
+#include <linux/key-type.h>
 
+#include <keys/ceph-type.h>
 #include <linux/ceph/decode.h>
 #include "crypto.h"
 
+int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+			  const struct ceph_crypto_key *src)
+{
+	memcpy(dst, src, sizeof(struct ceph_crypto_key));
+	dst->key = kmalloc(src->len, GFP_NOFS);
+	if (!dst->key)
+		return -ENOMEM;
+	memcpy(dst->key, src->key, src->len);
+	return 0;
+}
+
 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
 {
 	if (*p + sizeof(u16) + sizeof(key->created) +
@@ -410,3 +423,63 @@
 		return -EINVAL;
 	}
 }
+
+int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
+{
+	struct ceph_crypto_key *ckey;
+	int ret;
+	void *p;
+
+	ret = -EINVAL;
+	if (datalen <= 0 || datalen > 32767 || !data)
+		goto err;
+
+	ret = key_payload_reserve(key, datalen);
+	if (ret < 0)
+		goto err;
+
+	ret = -ENOMEM;
+	ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
+	if (!ckey)
+		goto err;
+
+	/* TODO ceph_crypto_key_decode should really take const input */
+	p = (void*)data;
+	ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
+	if (ret < 0)
+		goto err_ckey;
+
+	key->payload.data = ckey;
+	return 0;
+
+err_ckey:
+	kfree(ckey);
+err:
+	return ret;
+}
+
+int ceph_key_match(const struct key *key, const void *description)
+{
+	return strcmp(key->description, description) == 0;
+}
+
+void ceph_key_destroy(struct key *key) {
+	struct ceph_crypto_key *ckey = key->payload.data;
+
+	ceph_crypto_key_destroy(ckey);
+}
+
+struct key_type key_type_ceph = {
+	.name		= "ceph",
+	.instantiate	= ceph_key_instantiate,
+	.match		= ceph_key_match,
+	.destroy	= ceph_key_destroy,
+};
+
+int ceph_crypto_init(void) {
+	return register_key_type(&key_type_ceph);
+}
+
+void ceph_crypto_shutdown(void) {
+	unregister_key_type(&key_type_ceph);
+}
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index f9eccac..1919d15 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -19,6 +19,8 @@
 	kfree(key->key);
 }
 
+extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+				 const struct ceph_crypto_key *src);
 extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
 				  void **p, void *end);
 extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
@@ -40,6 +42,8 @@
 			 void *dst, size_t *dst_len,
 			 const void *src1, size_t src1_len,
 			 const void *src2, size_t src2_len);
+extern int ceph_crypto_init(void);
+extern void ceph_crypto_shutdown(void);
 
 /* armor.c */
 extern int ceph_armor(char *dst, const char *src, const char *end);
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 8a07939..cbe31fa 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -759,7 +759,7 @@
 
 	/* authentication */
 	monc->auth = ceph_auth_init(cl->options->name,
-				    cl->options->secret);
+				    cl->options->key);
 	if (IS_ERR(monc->auth))
 		return PTR_ERR(monc->auth);
 	monc->auth->want_keys =
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 02212ed..3b91d65 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -837,8 +837,7 @@
 			dout("moving osd to %p lru\n", req->r_osd);
 			__move_osd_to_lru(osdc, req->r_osd);
 		}
-		if (list_empty(&req->r_osd_item) &&
-		    list_empty(&req->r_linger_item))
+		if (list_empty(&req->r_linger_item))
 			req->r_osd = NULL;
 	}
 
@@ -883,7 +882,8 @@
 			dout("moving osd to %p lru\n", req->r_osd);
 			__move_osd_to_lru(osdc, req->r_osd);
 		}
-		req->r_osd = NULL;
+		if (list_empty(&req->r_osd_item))
+			req->r_osd = NULL;
 	}
 }
 
@@ -1602,11 +1602,11 @@
 	     cookie, ver, event);
 	if (event) {
 		event_work = kmalloc(sizeof(*event_work), GFP_NOIO);
-		INIT_WORK(&event_work->work, do_event_work);
 		if (!event_work) {
 			dout("ERROR: could not allocate event_work\n");
 			goto done_err;
 		}
+		INIT_WORK(&event_work->work, do_event_work);
 		event_work->event = event;
 		event_work->ver = ver;
 		event_work->notify_id = notify_id;
@@ -1672,7 +1672,7 @@
 	if (req->r_sent == 0) {
 		rc = __map_request(osdc, req);
 		if (rc < 0)
-			return rc;
+			goto out_unlock;
 		if (req->r_osd == NULL) {
 			dout("send_request %p no up osds in pg\n", req);
 			ceph_monc_request_next_osdmap(&osdc->client->monc);
@@ -1689,6 +1689,8 @@
 			}
 		}
 	}
+
+out_unlock:
 	mutex_unlock(&osdc->request_mutex);
 	up_read(&osdc->map_sem);
 	return rc;
diff --git a/net/core/dev.c b/net/core/dev.c
index 563ddc2..3da9fb0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1454,6 +1454,27 @@
 		__net_timestamp(skb);
 }
 
+static inline bool is_skb_forwardable(struct net_device *dev,
+				      struct sk_buff *skb)
+{
+	unsigned int len;
+
+	if (!(dev->flags & IFF_UP))
+		return false;
+
+	len = dev->mtu + dev->hard_header_len + VLAN_HLEN;
+	if (skb->len <= len)
+		return true;
+
+	/* if TSO is enabled, we don't care about the length as the packet
+	 * could be forwarded without being segmented before
+	 */
+	if (skb_is_gso(skb))
+		return true;
+
+	return false;
+}
+
 /**
  * dev_forward_skb - loopback an skb to another netif
  *
@@ -1477,8 +1498,7 @@
 	skb_orphan(skb);
 	nf_reset(skb);
 
-	if (unlikely(!(dev->flags & IFF_UP) ||
-		     (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
+	if (unlikely(!is_skb_forwardable(dev, skb))) {
 		atomic_long_inc(&dev->rx_dropped);
 		kfree_skb(skb);
 		return NET_RX_DROP;
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090d273..1b74d3b 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -215,6 +215,9 @@
 	case ARPHRD_INFINIBAND:
 		ip_ib_mc_map(addr, dev->broadcast, haddr);
 		return 0;
+	case ARPHRD_IPGRE:
+		ip_ipgre_mc_map(addr, dev->broadcast, haddr);
+		return 0;
 	default:
 		if (dir) {
 			memcpy(haddr, dev->broadcast, dev->addr_len);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f116ce8..4510883 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1068,6 +1068,7 @@
 	fib4_rules_exit(net);
 #endif
 
+	rtnl_lock();
 	for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
 		struct fib_table *tb;
 		struct hlist_head *head;
@@ -1080,6 +1081,7 @@
 			fib_free_table(tb);
 		}
 	}
+	rtnl_unlock();
 	kfree(net->ipv4.fib_table_hash);
 }
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e49c9d..92f952d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -341,6 +341,8 @@
 	case ARPHRD_INFINIBAND:
 		ipv6_ib_mc_map(addr, dev->broadcast, buf);
 		return 0;
+	case ARPHRD_IPGRE:
+		return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
 	default:
 		if (dir) {
 			memcpy(buf, dev->broadcast, dev->addr_len);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 152976e..d5bf91d 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1205,7 +1205,7 @@
 		if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)
 			continue;
 		sctp_assoc_hashtable = (struct sctp_hashbucket *)
-					__get_free_pages(GFP_ATOMIC, order);
+			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
 	} while (!sctp_assoc_hashtable && --order > 0);
 	if (!sctp_assoc_hashtable) {
 		pr_err("Failed association hash alloc\n");
@@ -1238,7 +1238,7 @@
 		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
 			continue;
 		sctp_port_hashtable = (struct sctp_bind_hashbucket *)
-					__get_free_pages(GFP_ATOMIC, order);
+			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
 	} while (!sctp_port_hashtable && --order > 0);
 	if (!sctp_port_hashtable) {
 		pr_err("Failed bind hash alloc\n");
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a82e3756..64449cb 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -375,6 +375,7 @@
 	}
 
 	if (runtime->no_period_wakeup) {
+		snd_pcm_sframes_t xrun_threshold;
 		/*
 		 * Without regular period interrupts, we have to check
 		 * the elapsed time to detect xruns.
@@ -383,7 +384,8 @@
 		if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
 			goto no_delta_check;
 		hdelta = jdelta - delta * HZ / runtime->rate;
-		while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
+		xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1;
+		while (hdelta > xrun_threshold) {
 			delta += runtime->buffer_size;
 			hw_base += runtime->buffer_size;
 			if (hw_base >= runtime->boundary)
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 0fce921..5466de8 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -778,10 +778,9 @@
 {
 	struct fwspk *fwspk = dev_get_drvdata(dev);
 
-	snd_card_disconnect(fwspk->card);
-
 	mutex_lock(&fwspk->mutex);
 	amdtp_out_stream_pcm_abort(&fwspk->stream);
+	snd_card_disconnect(fwspk->card);
 	fwspk_stop_stream(fwspk);
 	mutex_unlock(&fwspk->mutex);
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 537cfba..863eafe 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -229,6 +229,7 @@
 #define ES_REG_1371_CODEC 0x14	/* W/R: Codec Read/Write register address */
 #define   ES_1371_CODEC_RDY	   (1<<31)	/* codec ready */
 #define   ES_1371_CODEC_WIP	   (1<<30)	/* codec register access in progress */
+#define   EV_1938_CODEC_MAGIC	   (1<<26)
 #define   ES_1371_CODEC_PIRD	   (1<<23)	/* codec read/write select register */
 #define   ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
 #define   ES_1371_CODEC_READS(a)   ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
@@ -603,12 +604,18 @@
 
 #ifdef CHIP1371
 
+static inline bool is_ev1938(struct ensoniq *ensoniq)
+{
+	return ensoniq->pci->device == 0x8938;
+}
+
 static void snd_es1371_codec_write(struct snd_ac97 *ac97,
 				   unsigned short reg, unsigned short val)
 {
 	struct ensoniq *ensoniq = ac97->private_data;
-	unsigned int t, x;
+	unsigned int t, x, flag;
 
+	flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
 	mutex_lock(&ensoniq->src_mutex);
 	for (t = 0; t < POLL_COUNT; t++) {
 		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
@@ -630,7 +637,8 @@
 				    0x00010000)
 					break;
 			}
-			outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC));
+			outl(ES_1371_CODEC_WRITE(reg, val) | flag,
+			     ES_REG(ensoniq, 1371_CODEC));
 			/* restore SRC reg */
 			snd_es1371_wait_src_ready(ensoniq);
 			outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -647,8 +655,9 @@
 					    unsigned short reg)
 {
 	struct ensoniq *ensoniq = ac97->private_data;
-	unsigned int t, x, fail = 0;
+	unsigned int t, x, flag, fail = 0;
 
+	flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
       __again:
 	mutex_lock(&ensoniq->src_mutex);
 	for (t = 0; t < POLL_COUNT; t++) {
@@ -671,7 +680,8 @@
 				    0x00010000)
 					break;
 			}
-			outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC));
+			outl(ES_1371_CODEC_READS(reg) | flag,
+			     ES_REG(ensoniq, 1371_CODEC));
 			/* restore SRC reg */
 			snd_es1371_wait_src_ready(ensoniq);
 			outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -683,6 +693,11 @@
 			/* now wait for the stinkin' data (RDY) */
 			for (t = 0; t < POLL_COUNT; t++) {
 				if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
+					if (is_ev1938(ensoniq)) {
+						for (t = 0; t < 100; t++)
+							inl(ES_REG(ensoniq, CONTROL));
+						x = inl(ES_REG(ensoniq, 1371_CODEC));
+					}
 					mutex_unlock(&ensoniq->src_mutex);
 					return ES_1371_CODEC_READ(x);
 				}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index d08cf31..69e3386 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3034,6 +3034,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
 	SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
  	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
+	SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
 	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
 	{}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0ef0035..12c6f45 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9863,7 +9863,6 @@
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
 	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
-	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
 
 	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
 	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
@@ -10700,6 +10699,7 @@
 	PINFIX_LENOVO_Y530,
 	PINFIX_PB_M5210,
 	PINFIX_ACER_ASPIRE_7736,
+	PINFIX_GIGABYTE_880GM,
 };
 
 static const struct alc_fixup alc882_fixups[] = {
@@ -10731,6 +10731,13 @@
 		.type = ALC_FIXUP_SKU,
 		.v.sku = ALC_FIXUP_SKU_IGNORE,
 	},
+	[PINFIX_GIGABYTE_880GM] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x1114410 }, /* set as speaker */
+			{ }
+		}
+	},
 };
 
 static struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -10738,6 +10745,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
 	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
+	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),
 	{}
 };
 
@@ -18774,8 +18782,6 @@
 		      ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
 	SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
-	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
-		      ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
 	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
@@ -19449,6 +19455,7 @@
 	ALC662_FIXUP_IDEAPAD,
 	ALC272_FIXUP_MARIO,
 	ALC662_FIXUP_CZC_P10T,
+	ALC662_FIXUP_GIGABYTE,
 };
 
 static const struct alc_fixup alc662_fixups[] = {
@@ -19477,12 +19484,20 @@
 			{}
 		}
 	},
+	[ALC662_FIXUP_GIGABYTE] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x1114410 }, /* set as speaker */
+			{ }
+		}
+	},
 };
 
 static struct snd_pci_quirk alc662_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
 	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
+	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 00b6d87..eb1a0b4 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -324,6 +324,10 @@
 	dac33_write(codec, DAC33_OUT_AMP_CTRL,
 		    dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
 
+	dac33_write(codec, DAC33_LDAC_PWR_CTRL,
+		    dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL));
+	dac33_write(codec, DAC33_RDAC_PWR_CTRL,
+		    dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL));
 }
 
 static inline int dac33_read_id(struct snd_soc_codec *codec)
@@ -670,6 +674,7 @@
 {
 	struct snd_soc_codec *codec = dac33->codec;
 	unsigned int delay;
+	unsigned long flags;
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
@@ -677,10 +682,10 @@
 			DAC33_THRREG(dac33->nsample));
 
 		/* Take the timestamps */
-		spin_lock_irq(&dac33->lock);
+		spin_lock_irqsave(&dac33->lock, flags);
 		dac33->t_stamp2 = ktime_to_us(ktime_get());
 		dac33->t_stamp1 = dac33->t_stamp2;
-		spin_unlock_irq(&dac33->lock);
+		spin_unlock_irqrestore(&dac33->lock, flags);
 
 		dac33_write16(codec, DAC33_PREFILL_MSB,
 				DAC33_THRREG(dac33->alarm_threshold));
@@ -692,11 +697,11 @@
 		break;
 	case DAC33_FIFO_MODE7:
 		/* Take the timestamp */
-		spin_lock_irq(&dac33->lock);
+		spin_lock_irqsave(&dac33->lock, flags);
 		dac33->t_stamp1 = ktime_to_us(ktime_get());
 		/* Move back the timestamp with drain time */
 		dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
-		spin_unlock_irq(&dac33->lock);
+		spin_unlock_irqrestore(&dac33->lock, flags);
 
 		dac33_write16(codec, DAC33_PREFILL_MSB,
 				DAC33_THRREG(DAC33_MODE7_MARGIN));
@@ -714,13 +719,14 @@
 static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 {
 	struct snd_soc_codec *codec = dac33->codec;
+	unsigned long flags;
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_MODE1:
 		/* Take the timestamp */
-		spin_lock_irq(&dac33->lock);
+		spin_lock_irqsave(&dac33->lock, flags);
 		dac33->t_stamp2 = ktime_to_us(ktime_get());
-		spin_unlock_irq(&dac33->lock);
+		spin_unlock_irqrestore(&dac33->lock, flags);
 
 		dac33_write16(codec, DAC33_NSAMPLE_MSB,
 				DAC33_THRREG(dac33->nsample));
@@ -773,10 +779,11 @@
 {
 	struct snd_soc_codec *codec = dev;
 	struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+	unsigned long flags;
 
-	spin_lock(&dac33->lock);
+	spin_lock_irqsave(&dac33->lock, flags);
 	dac33->t_stamp1 = ktime_to_us(ktime_get());
-	spin_unlock(&dac33->lock);
+	spin_unlock_irqrestore(&dac33->lock, flags);
 
 	/* Do not schedule the workqueue in Mode7 */
 	if (dac33->fifo_mode != DAC33_FIFO_MODE7)
@@ -1173,15 +1180,16 @@
 	unsigned int time_delta, uthr;
 	int samples_out, samples_in, samples;
 	snd_pcm_sframes_t delay = 0;
+	unsigned long flags;
 
 	switch (dac33->fifo_mode) {
 	case DAC33_FIFO_BYPASS:
 		break;
 	case DAC33_FIFO_MODE1:
-		spin_lock(&dac33->lock);
+		spin_lock_irqsave(&dac33->lock, flags);
 		t0 = dac33->t_stamp1;
 		t1 = dac33->t_stamp2;
-		spin_unlock(&dac33->lock);
+		spin_unlock_irqrestore(&dac33->lock, flags);
 		t_now = ktime_to_us(ktime_get());
 
 		/* We have not started to fill the FIFO yet, delay is 0 */
@@ -1246,10 +1254,10 @@
 		}
 		break;
 	case DAC33_FIFO_MODE7:
-		spin_lock(&dac33->lock);
+		spin_lock_irqsave(&dac33->lock, flags);
 		t0 = dac33->t_stamp1;
 		uthr = dac33->uthr;
-		spin_unlock(&dac33->lock);
+		spin_unlock_irqrestore(&dac33->lock, flags);
 		t_now = ktime_to_us(ktime_get());
 
 		/* We have not started to fill the FIFO yet, delay is 0 */
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 482fcdb..255901c 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1629,8 +1629,10 @@
 	priv->naudint = naudint;
 	priv->workqueue = create_singlethread_workqueue("twl6040-codec");
 
-	if (!priv->workqueue)
+	if (!priv->workqueue) {
+		ret = -ENOMEM;
 		goto work_err;
+	}
 
 	INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work);
 
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 671ef8d..aab7765 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -110,12 +110,12 @@
 		slave_config.direction = DMA_TO_DEVICE;
 		slave_config.dst_addr = dma_params->dma_addr;
 		slave_config.dst_addr_width = buswidth;
-		slave_config.dst_maxburst = dma_params->burstsize;
+		slave_config.dst_maxburst = dma_params->burstsize * buswidth;
 	} else {
 		slave_config.direction = DMA_FROM_DEVICE;
 		slave_config.src_addr = dma_params->dma_addr;
 		slave_config.src_addr_width = buswidth;
-		slave_config.src_maxburst = dma_params->burstsize;
+		slave_config.src_maxburst = dma_params->burstsize * buswidth;
 	}
 
 	ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
@@ -303,6 +303,11 @@
 
 static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
 {
+	struct imx_ssi *ssi = platform_get_drvdata(pdev);
+
+	ssi->dma_params_tx.burstsize = 6;
+	ssi->dma_params_rx.burstsize = 4;
+
 	return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
 }
 
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index a4406a1..dc8a875 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -234,7 +234,4 @@
  */
 #define IMX_SSI_DMABUF_SIZE	(64 * 1024)
 
-#define DMA_RXFIFO_BURST      0x4
-#define DMA_TXFIFO_BURST      0x6
-
 #endif /* _IMX_SSI_H */
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 784cff5..9027da4 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -310,7 +310,7 @@
 	.cpu_dai_name = "pxa2xx-i2s",
 	.codec_dai_name = "wm8731-hifi",
 	.platform_name = "pxa-pcm-audio",
-	.codec_name = "wm8731-codec-0.001b",
+	.codec_name = "wm8731-codec.0-001b",
 	.init = corgi_wm8731_init,
 	.ops = &corgi_ops,
 };
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 158c30e..207dee5 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -165,8 +165,12 @@
 strip-libs = $(filter-out -l%,$(1))
 
 $(OUTPUT)python/perf.so: $(PYRF_OBJS)
-	$(QUIET_GEN)python util/setup.py --quiet  build_ext --build-lib='$(OUTPUT)python' \
-						--build-temp='$(OUTPUT)python/temp'
+	$(QUIET_GEN)( \
+		export CFLAGS="$(BASIC_CFLAGS)"; \
+		python util/setup.py --quiet  build_ext --build-lib='$(OUTPUT)python' \
+			--build-temp='$(OUTPUT)python/temp' \
+	)
+
 #
 # No Perl scripts right now:
 #
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6febcc1..17d1dcb 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -41,7 +41,7 @@
 static u64			default_interval		=      0;
 
 static unsigned int		page_size;
-static unsigned int		mmap_pages			=    128;
+static unsigned int		mmap_pages			= UINT_MAX;
 static unsigned int		user_freq 			= UINT_MAX;
 static int			freq				=   1000;
 static int			output;
@@ -275,11 +275,10 @@
 				     !no_inherit) < 0) {
 			int err = errno;
 
-			if (err == EPERM || err == EACCES)
-				die("Permission error - are you root?\n"
-					"\t Consider tweaking"
-					" /proc/sys/kernel/perf_event_paranoid.\n");
-			else if (err ==  ENODEV && cpu_list) {
+			if (err == EPERM || err == EACCES) {
+				ui__warning_paranoid();
+				exit(EXIT_FAILURE);
+			} else if (err ==  ENODEV && cpu_list) {
 				die("No such device - did you specify"
 					" an out-of-range profile CPU?\n");
 			} else if (err == EINVAL && sample_id_all_avail) {
@@ -302,11 +301,19 @@
 					&& attr->config == PERF_COUNT_HW_CPU_CYCLES) {
 
 				if (verbose)
-					warning(" ... trying to fall back to cpu-clock-ticks\n");
+					ui__warning("The cycles event is not supported, "
+						    "trying to fall back to cpu-clock-ticks\n");
 				attr->type = PERF_TYPE_SOFTWARE;
 				attr->config = PERF_COUNT_SW_CPU_CLOCK;
 				goto try_again;
 			}
+
+			if (err == ENOENT) {
+				ui__warning("The %s event is not supported.\n",
+					    event_name(pos));
+				exit(EXIT_FAILURE);
+			}
+
 			printf("\n");
 			error("sys_perf_event_open() syscall returned with %d (%s).  /bin/dmesg may provide additional information.\n",
 			      err, strerror(err));
@@ -506,6 +513,10 @@
 	if (have_tracepoints(&evsel_list->entries))
 		perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
 
+	/* 512 kiB: default amount of unprivileged mlocked memory */
+	if (mmap_pages == UINT_MAX)
+		mmap_pages = (512 * 1024) / page_size;
+
 	if (forks) {
 		child_pid = fork();
 		if (child_pid < 0) {
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 676b4fb..fc1273e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -850,10 +850,10 @@
 				     top.evlist->threads, group, inherit) < 0) {
 			int err = errno;
 
-			if (err == EPERM || err == EACCES)
-				die("Permission error - are you root?\n"
-					"\t Consider tweaking"
-					" /proc/sys/kernel/perf_event_paranoid.\n");
+			if (err == EPERM || err == EACCES) {
+				ui__warning_paranoid();
+				goto out_err;
+			}
 			/*
 			 * If it's cycles then fall back to hrtimer
 			 * based cpu-clock-tick sw counter, which
@@ -861,25 +861,41 @@
 			 */
 			if (attr->type == PERF_TYPE_HARDWARE &&
 			    attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
 				if (verbose)
-					warning(" ... trying to fall back to cpu-clock-ticks\n");
+					ui__warning("Cycles event not supported,\n"
+						    "trying to fall back to cpu-clock-ticks\n");
 
 				attr->type = PERF_TYPE_SOFTWARE;
 				attr->config = PERF_COUNT_SW_CPU_CLOCK;
 				goto try_again;
 			}
-			printf("\n");
-			error("sys_perf_event_open() syscall returned with %d "
-			      "(%s).  /bin/dmesg may provide additional information.\n",
-			      err, strerror(err));
-			die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-			exit(-1);
+
+			if (err == ENOENT) {
+				ui__warning("The %s event is not supported.\n",
+					    event_name(counter));
+				goto out_err;
+			}
+
+			ui__warning("The sys_perf_event_open() syscall "
+				    "returned with %d (%s).  /bin/dmesg "
+				    "may provide additional information.\n"
+				    "No CONFIG_PERF_EVENTS=y kernel support "
+				    "configured?\n", err, strerror(err));
+			goto out_err;
 		}
 	}
 
-	if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
-		die("failed to mmap with %d (%s)\n", errno, strerror(errno));
+	if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) {
+		ui__warning("Failed to mmap with %d (%s)\n",
+			    errno, strerror(errno));
+		goto out_err;
+	}
+
+	return;
+
+out_err:
+	exit_browser(0);
+	exit(0);
 }
 
 static int __cmd_top(void)
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index d4536a9..155749d 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -57,6 +57,16 @@
 }
 #endif
 
+void ui__warning_paranoid(void)
+{
+	ui__warning("Permission error - are you root?\n"
+		    "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
+		    " -1 - Not paranoid at all\n"
+		    "  0 - Disallow raw tracepoint access for unpriv\n"
+		    "  1 - Disallow cpu events for unpriv\n"
+		    "  2 - Disallow kernel profiling for unpriv\n");
+}
+
 void trace_event(union perf_event *event)
 {
 	unsigned char *raw_event = (void *)event;
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 93516cf4..fd53db4 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -36,5 +36,6 @@
 #endif
 
 void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
+void ui__warning_paranoid(void);
 
 #endif	/* __PERF_DEBUG_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2b15c36..1023f67 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -710,7 +710,7 @@
 		 * in the whole kernel symbol list.
 		 */
 		if ((long long)al->addr < 0 &&
-		    cpumode == PERF_RECORD_MISC_KERNEL &&
+		    cpumode == PERF_RECORD_MISC_USER &&
 		    machine && mg != &machine->kmaps) {
 			mg = &machine->kmaps;
 			goto try_again;
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index e24ffad..bbc982f 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -1,13 +1,18 @@
 #!/usr/bin/python2
 
 from distutils.core import setup, Extension
+from os import getenv
+
+cflags = ['-fno-strict-aliasing', '-Wno-write-strings']
+cflags += getenv('CFLAGS', '').split()
 
 perf = Extension('perf',
 		  sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c',
 			     'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c',
 			     'util/util.c', 'util/xyarray.c', 'util/cgroup.c'],
 		  include_dirs = ['util/include'],
-		  extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings'])
+		  extra_compile_args = cflags,
+                 )
 
 setup(name='perf',
       version='0.1',
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 17df793..f06c10f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1196,6 +1196,8 @@
 				if (curr_dso == NULL)
 					goto out_elf_end;
 				curr_dso->kernel = self->kernel;
+				curr_dso->long_name = self->long_name;
+				curr_dso->long_name_len = self->long_name_len;
 				curr_map = map__new2(start, curr_dso,
 						     map->type);
 				if (curr_map == NULL) {
@@ -1842,6 +1844,7 @@
 	if (fd < 0)
 		return -1;
 
+	dso__set_long_name(self, (char *)vmlinux);
 	dso__set_loaded(self, map->type);
 	err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
 	close(fd);
@@ -2403,6 +2406,8 @@
 	if (symbol_conf.initialized)
 		return 0;
 
+	symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64));
+
 	elf_version(EV_CURRENT);
 	if (symbol_conf.sort_by_name)
 		symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -